diff options
Diffstat (limited to 'spec/features')
129 files changed, 1011 insertions, 1112 deletions
diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb index 5596ad7bf21..b96762ec6ad 100644 --- a/spec/features/admin/admin_appearance_spec.rb +++ b/spec/features/admin/admin_appearance_spec.rb @@ -90,7 +90,7 @@ RSpec.describe 'Admin Appearance' do sign_in(admin) gitlab_enable_admin_mode_sign_in(admin) visit new_project_path - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click expect_custom_new_project_appearance(appearance) end diff --git a/spec/features/admin/admin_dev_ops_report_spec.rb b/spec/features/admin/admin_dev_ops_report_spec.rb index 33f984af807..8f1960b681c 100644 --- a/spec/features/admin/admin_dev_ops_report_spec.rb +++ b/spec/features/admin/admin_dev_ops_report_spec.rb @@ -32,7 +32,7 @@ RSpec.describe 'DevOps Report page', :js do it 'shows empty state' do visit admin_dev_ops_report_path - expect(page).to have_selector(".js-empty-state") + expect(page).to have_text('Service ping is off') end it 'hides the intro callout' do diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb index f9673a8aa2f..7d7b2baf941 100644 --- a/spec/features/admin/admin_groups_spec.rb +++ b/spec/features/admin/admin_groups_spec.rb @@ -132,6 +132,19 @@ RSpec.describe 'Admin Groups' do expect(page).to have_text(note_text) end + + context 'when group has open access requests' do + let!(:access_request) { create(:group_member, :access_request, group: group) } + + it 'shows access requests with link to manage access' do + visit admin_group_path(group) + + page.within '[data-testid="access-requests"]' do + expect(page).to have_content access_request.user.name + expect(page).to have_link 'Manage access', href: group_group_members_path(group, tab: 'access_requests') + end + end + end end describe 'group edit' do diff --git a/spec/features/admin/admin_mode/workers_spec.rb b/spec/features/admin/admin_mode/workers_spec.rb index fbbcf19063b..0caa883fb5b 100644 --- a/spec/features/admin/admin_mode/workers_spec.rb +++ b/spec/features/admin/admin_mode/workers_spec.rb @@ -4,6 +4,8 @@ require 'spec_helper' # Test an operation that triggers background jobs requiring administrative rights RSpec.describe 'Admin mode for workers', :request_store do + include Spec::Support::Helpers::Features::AdminUsersHelpers + let(:user) { create(:user) } let(:user_to_delete) { create(:user) } @@ -37,7 +39,8 @@ RSpec.describe 'Admin mode for workers', :request_store do it 'can delete user', :js do visit admin_user_path(user_to_delete) - click_button 'Delete user' + + click_action_in_user_dropdown(user_to_delete.id, 'Delete user') page.within '.modal-dialog' do find("input[name='username']").send_keys(user_to_delete.name) diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb index cbbe9aa3b8b..15def00f354 100644 --- a/spec/features/admin/admin_projects_spec.rb +++ b/spec/features/admin/admin_projects_spec.rb @@ -52,6 +52,8 @@ RSpec.describe "Admin::Projects" do end describe "GET /admin/projects/:namespace_id/:id" do + let!(:access_request) { create(:project_member, :access_request, project: project) } + before do expect(project).to be_persisted @@ -67,6 +69,15 @@ RSpec.describe "Admin::Projects" do expect(page).to have_content(project.creator.name) expect(page).to have_content(project.id) end + + context 'when project has open access requests' do + it 'shows access requests with link to manage access' do + page.within '[data-testid="access-requests"]' do + expect(page).to have_content access_request.user.name + expect(page).to have_link 'Manage access', href: project_project_members_path(project, tab: 'access_requests') + end + end + end end describe 'transfer project' do diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb index d7a267fec69..54c07985a21 100644 --- a/spec/features/admin/admin_runners_spec.rb +++ b/spec/features/admin/admin_runners_spec.rb @@ -4,8 +4,6 @@ require 'spec_helper' RSpec.describe "Admin Runners" do include StubENV - include FilteredSearchHelpers - include SortingHelper before do stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') @@ -14,31 +12,68 @@ RSpec.describe "Admin Runners" do gitlab_enable_admin_mode_sign_in(admin) end - describe "Runners page" do - let(:pipeline) { create(:ci_pipeline) } - - before do - stub_feature_flags(runner_list_view_vue_ui: false) - end + describe "Runners page", :js do + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group) } + let_it_be(:namespace) { create(:namespace) } + let_it_be(:project) { create(:project, namespace: namespace, creator: user) } context "when there are runners" do it 'has all necessary texts' do - runner = create(:ci_runner, contacted_at: Time.now) - create(:ci_build, pipeline: pipeline, runner_id: runner.id) + create(:ci_runner, :instance, contacted_at: Time.now) + visit admin_runners_path expect(page).to have_text "Set up a shared runner manually" expect(page).to have_text "Runners currently online: 1" end - describe 'search', :js do + it 'with an instance runner shows an instance badge and no project count' do + runner = create(:ci_runner, :instance) + + visit admin_runners_path + + within "[data-testid='runner-row-#{runner.id}']" do + expect(page).to have_selector '.badge', text: 'shared' + expect(page).to have_text 'n/a' + end + end + + it 'with a group runner shows a group badge and no project count' do + runner = create(:ci_runner, :group, groups: [group]) + + visit admin_runners_path + + within "[data-testid='runner-row-#{runner.id}']" do + expect(page).to have_selector '.badge', text: 'group' + expect(page).to have_text 'n/a' + end + end + + it 'with a project runner shows a project badge and project count' do + runner = create(:ci_runner, :project, projects: [project]) + + visit admin_runners_path + + within "[data-testid='runner-row-#{runner.id}']" do + expect(page).to have_selector '.badge', text: 'specific' + expect(page).to have_text '1' + end + end + + describe 'search' do before do - create(:ci_runner, description: 'runner-foo') - create(:ci_runner, description: 'runner-bar') + create(:ci_runner, :instance, description: 'runner-foo') + create(:ci_runner, :instance, description: 'runner-bar') visit admin_runners_path end + it 'shows runners' do + expect(page).to have_content("runner-foo") + expect(page).to have_content("runner-bar") + end + it 'shows correct runner when description matches' do input_filtered_search_keys('runner-foo') @@ -53,28 +88,29 @@ RSpec.describe "Admin Runners" do end end - describe 'filter by status', :js do + describe 'filter by status' do it 'shows correct runner when status matches' do - create(:ci_runner, description: 'runner-active', active: true) - create(:ci_runner, description: 'runner-paused', active: false) + create(:ci_runner, :instance, description: 'runner-active', active: true) + create(:ci_runner, :instance, description: 'runner-paused', active: false) visit admin_runners_path expect(page).to have_content 'runner-active' expect(page).to have_content 'runner-paused' - input_filtered_search_keys('status:=active') + input_filtered_search_filter_is_only('Status', 'Active') + expect(page).to have_content 'runner-active' expect(page).not_to have_content 'runner-paused' end it 'shows no runner when status does not match' do - create(:ci_runner, :online, description: 'runner-active', active: true) - create(:ci_runner, :online, description: 'runner-paused', active: false) + create(:ci_runner, :instance, description: 'runner-active', active: true) + create(:ci_runner, :instance, description: 'runner-paused', active: false) visit admin_runners_path - input_filtered_search_keys('status:=offline') + input_filtered_search_filter_is_only('Status', 'Online') expect(page).not_to have_content 'runner-active' expect(page).not_to have_content 'runner-paused' @@ -83,46 +119,48 @@ RSpec.describe "Admin Runners" do end it 'shows correct runner when status is selected and search term is entered' do - create(:ci_runner, description: 'runner-a-1', active: true) - create(:ci_runner, description: 'runner-a-2', active: false) - create(:ci_runner, description: 'runner-b-1', active: true) + create(:ci_runner, :instance, description: 'runner-a-1', active: true) + create(:ci_runner, :instance, description: 'runner-a-2', active: false) + create(:ci_runner, :instance, description: 'runner-b-1', active: true) visit admin_runners_path - input_filtered_search_keys('status:=active') + input_filtered_search_filter_is_only('Status', 'Active') + expect(page).to have_content 'runner-a-1' expect(page).to have_content 'runner-b-1' expect(page).not_to have_content 'runner-a-2' - input_filtered_search_keys('status:=active runner-a') + input_filtered_search_keys('runner-a') + expect(page).to have_content 'runner-a-1' expect(page).not_to have_content 'runner-b-1' expect(page).not_to have_content 'runner-a-2' end end - describe 'filter by type', :js do - it 'shows correct runner when type matches' do - create :ci_runner, :project, description: 'runner-project' - create :ci_runner, :group, description: 'runner-group' + describe 'filter by type' do + before do + create(:ci_runner, :project, description: 'runner-project', projects: [project]) + create(:ci_runner, :group, description: 'runner-group', groups: [group]) + end + it 'shows correct runner when type matches' do visit admin_runners_path expect(page).to have_content 'runner-project' expect(page).to have_content 'runner-group' - input_filtered_search_keys('type:=project_type') + input_filtered_search_filter_is_only('Type', 'project') + expect(page).to have_content 'runner-project' expect(page).not_to have_content 'runner-group' end it 'shows no runner when type does not match' do - create :ci_runner, :project, description: 'runner-project' - create :ci_runner, :group, description: 'runner-group' - visit admin_runners_path - input_filtered_search_keys('type:=instance_type') + input_filtered_search_filter_is_only('Type', 'instance') expect(page).not_to have_content 'runner-project' expect(page).not_to have_content 'runner-group' @@ -131,95 +169,93 @@ RSpec.describe "Admin Runners" do end it 'shows correct runner when type is selected and search term is entered' do - create :ci_runner, :project, description: 'runner-a-1' - create :ci_runner, :instance, description: 'runner-a-2' - create :ci_runner, :project, description: 'runner-b-1' + create(:ci_runner, :project, description: 'runner-2-project', projects: [project]) visit admin_runners_path - input_filtered_search_keys('type:=project_type') - expect(page).to have_content 'runner-a-1' - expect(page).to have_content 'runner-b-1' - expect(page).not_to have_content 'runner-a-2' + input_filtered_search_filter_is_only('Type', 'project') - input_filtered_search_keys('type:=project_type runner-a') - expect(page).to have_content 'runner-a-1' - expect(page).not_to have_content 'runner-b-1' - expect(page).not_to have_content 'runner-a-2' + expect(page).to have_content 'runner-project' + expect(page).to have_content 'runner-2-project' + expect(page).not_to have_content 'runner-group' + + input_filtered_search_keys('runner-project') + + expect(page).to have_content 'runner-project' + expect(page).not_to have_content 'runner-2-project' + expect(page).not_to have_content 'runner-group' end end - describe 'filter by tag', :js do - it 'shows correct runner when tag matches' do - create :ci_runner, description: 'runner-blue', tag_list: ['blue'] - create :ci_runner, description: 'runner-red', tag_list: ['red'] + describe 'filter by tag' do + before do + create(:ci_runner, :instance, description: 'runner-blue', tag_list: ['blue']) + create(:ci_runner, :instance, description: 'runner-red', tag_list: ['red']) + end + it 'shows correct runner when tag matches' do visit admin_runners_path expect(page).to have_content 'runner-blue' expect(page).to have_content 'runner-red' - input_filtered_search_keys('tag:=blue') + input_filtered_search_filter_is_only('Tags', 'blue') expect(page).to have_content 'runner-blue' expect(page).not_to have_content 'runner-red' end it 'shows no runner when tag does not match' do - create :ci_runner, description: 'runner-blue', tag_list: ['blue'] - create :ci_runner, description: 'runner-red', tag_list: ['blue'] - visit admin_runners_path - input_filtered_search_keys('tag:=red') + input_filtered_search_filter_is_only('Tags', 'green') expect(page).not_to have_content 'runner-blue' - expect(page).not_to have_content 'runner-blue' expect(page).to have_text 'No runners found' end it 'shows correct runner when tag is selected and search term is entered' do - create :ci_runner, description: 'runner-a-1', tag_list: ['blue'] - create :ci_runner, description: 'runner-a-2', tag_list: ['red'] - create :ci_runner, description: 'runner-b-1', tag_list: ['blue'] + create(:ci_runner, :instance, description: 'runner-2-blue', tag_list: ['blue']) visit admin_runners_path - input_filtered_search_keys('tag:=blue') + input_filtered_search_filter_is_only('Tags', 'blue') - expect(page).to have_content 'runner-a-1' - expect(page).to have_content 'runner-b-1' - expect(page).not_to have_content 'runner-a-2' + expect(page).to have_content 'runner-blue' + expect(page).to have_content 'runner-2-blue' + expect(page).not_to have_content 'runner-red' - input_filtered_search_keys('tag:=blue runner-a') + input_filtered_search_keys('runner-2-blue') - expect(page).to have_content 'runner-a-1' - expect(page).not_to have_content 'runner-b-1' - expect(page).not_to have_content 'runner-a-2' + expect(page).to have_content 'runner-2-blue' + expect(page).not_to have_content 'runner-blue' + expect(page).not_to have_content 'runner-red' end end - it 'sorts by last contact date', :js do - create(:ci_runner, description: 'runner-1', created_at: '2018-07-12 15:37', contacted_at: '2018-07-12 15:37') - create(:ci_runner, description: 'runner-2', created_at: '2018-07-12 16:37', contacted_at: '2018-07-12 16:37') + it 'sorts by last contact date' do + create(:ci_runner, :instance, description: 'runner-1', created_at: '2018-07-12 15:37', contacted_at: '2018-07-12 15:37') + create(:ci_runner, :instance, description: 'runner-2', created_at: '2018-07-12 16:37', contacted_at: '2018-07-12 16:37') visit admin_runners_path - within '[data-testid="runners-table"] .gl-responsive-table-row:nth-child(2)' do + within '[data-testid="runner-list"] tbody tr:nth-child(1)' do expect(page).to have_content 'runner-2' end - within '[data-testid="runners-table"] .gl-responsive-table-row:nth-child(3)' do + within '[data-testid="runner-list"] tbody tr:nth-child(2)' do expect(page).to have_content 'runner-1' end - sorting_by 'Last Contact' + click_on 'Created date' # Open "sort by" dropdown + click_on 'Last contact' + click_on 'Sort direction: Descending' - within '[data-testid="runners-table"] .gl-responsive-table-row:nth-child(2)' do + within '[data-testid="runner-list"] tbody tr:nth-child(1)' do expect(page).to have_content 'runner-1' end - within '[data-testid="runners-table"] .gl-responsive-table-row:nth-child(3)' do + within '[data-testid="runner-list"] tbody tr:nth-child(2)' do expect(page).to have_content 'runner-2' end end @@ -237,47 +273,6 @@ RSpec.describe "Admin Runners" do end end - context 'group runner' do - let(:group) { create(:group) } - let!(:runner) { create(:ci_runner, :group, groups: [group]) } - - it 'shows the label and does not show the project count' do - visit admin_runners_path - - within "[data-testid='runner-row-#{runner.id}']" do - expect(page).to have_selector '.badge', text: 'group' - expect(page).to have_text 'n/a' - end - end - end - - context 'shared runner' do - it 'shows the label and does not show the project count' do - runner = create(:ci_runner, :instance) - - visit admin_runners_path - - within "[data-testid='runner-row-#{runner.id}']" do - expect(page).to have_selector '.badge', text: 'shared' - expect(page).to have_text 'n/a' - end - end - end - - context 'specific runner' do - it 'shows the label and the project count' do - project = create(:project) - runner = create(:ci_runner, :project, projects: [project]) - - visit admin_runners_path - - within "[data-testid='runner-row-#{runner.id}']" do - expect(page).to have_selector '.badge', text: 'specific' - expect(page).to have_text '1' - end - end - end - describe 'runners registration token' do let!(:token) { Gitlab::CurrentSettings.runners_registration_token } @@ -286,17 +281,23 @@ RSpec.describe "Admin Runners" do end it 'has a registration token' do - expect(page.find('[data-testid="registration_token"]')).to have_content(token) + click_on 'Click to reveal' + expect(page.find('[data-testid="registration-token"]')).to have_content(token) end describe 'reset registration token' do - let(:page_token) { find('[data-testid="registration_token"]').text } + let(:page_token) { find('[data-testid="registration-token"]').text } before do click_button 'Reset registration token' + + page.accept_alert + + wait_for_requests end it 'changes registration token' do + click_on 'Click to reveal' expect(page_token).not_to eq token end end @@ -409,4 +410,43 @@ RSpec.describe "Admin Runners" do end end end + + private + + def search_bar_selector + '[data-testid="runners-filtered-search"]' + end + + # The filters must be clicked first to be able to receive events + # See: https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1493 + def focus_filtered_search + page.within(search_bar_selector) do + page.find('.gl-filtered-search-term-token').click + end + end + + def input_filtered_search_keys(search_term) + focus_filtered_search + + page.within(search_bar_selector) do + page.find('input').send_keys(search_term) + click_on 'Search' + end + end + + def input_filtered_search_filter_is_only(filter, value) + focus_filtered_search + + page.within(search_bar_selector) do + click_on filter + + # For OPERATOR_IS_ONLY, clicking the filter + # immediately preselects "=" operator + + page.find('input').send_keys(value) + page.find('input').send_keys(:enter) + + click_on 'Search' + end + end end diff --git a/spec/features/admin/admin_sees_background_migrations_spec.rb b/spec/features/admin/admin_sees_background_migrations_spec.rb index d848a8352bc..11823195310 100644 --- a/spec/features/admin/admin_sees_background_migrations_spec.rb +++ b/spec/features/admin/admin_sees_background_migrations_spec.rb @@ -31,7 +31,7 @@ RSpec.describe "Admin > Admin sees background migrations" do end end - it 'can view queued migrations' do + it 'can view queued migrations and pause and resume them' do visit admin_background_migrations_path within '#content-body' do @@ -40,7 +40,16 @@ RSpec.describe "Admin > Admin sees background migrations" do expect(page).to have_content(active_migration.job_class_name) expect(page).to have_content(active_migration.table_name) expect(page).to have_content('0.00%') - expect(page).to have_content(active_migration.status.humanize) + expect(page).not_to have_content('Paused') + expect(page).to have_content('Active') + + click_button('Pause') + expect(page).not_to have_content('Active') + expect(page).to have_content('Paused') + + click_button('Resume') + expect(page).not_to have_content('Paused') + expect(page).to have_content('Active') end end diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index c289c18126d..9efb31ef4c1 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -269,77 +269,43 @@ RSpec.describe 'Admin updates settings' do end context 'Integrations page' do + let(:mailgun_events_receiver_enabled) { true } + before do + stub_feature_flags(mailgun_events_receiver: mailgun_events_receiver_enabled) visit general_admin_application_settings_path end it 'enable hiding third party offers' do page.within('.as-third-party-offers') do - check 'Do not display offers from third parties within GitLab' + check 'Do not display offers from third parties' click_button 'Save changes' end expect(page).to have_content "Application settings saved successfully" expect(current_settings.hide_third_party_offers).to be true end - end - - context 'when Service Templates are enabled' do - before do - stub_feature_flags(disable_service_templates: false) - visit general_admin_application_settings_path - end - - it 'shows Service Templates link' do - expect(page).to have_link('Service Templates') - end - - context 'when the Slack Notifications Service template is active' do - before do - create(:service, :template, type: 'SlackService', active: true) - - visit general_admin_application_settings_path - end - it 'change Slack Notifications Service template settings', :js do - first(:link, 'Service Templates').click - click_link 'Slack notifications' - fill_in 'Webhook', with: 'http://localhost' - fill_in 'Username', with: 'test_user' - fill_in 'service[push_channel]', with: '#test_channel' - page.check('Notify only broken pipelines') - page.select 'All branches', from: 'Branches to be notified' - page.select 'Match any of the labels', from: 'Labels to be notified behavior' - - check_all_events - click_button 'Save changes' + context 'when mailgun_events_receiver feature flag is enabled' do + it 'enabling Mailgun events', :aggregate_failures do + page.within('.as-mailgun') do + check 'Enable Mailgun event receiver' + fill_in 'Mailgun HTTP webhook signing key', with: 'MAILGUN_SIGNING_KEY' + click_button 'Save changes' + end expect(page).to have_content 'Application settings saved successfully' - - click_link 'Slack notifications' - - expect(page.all('input[type=checkbox]')).to all(be_checked) - expect(find_field('Webhook').value).to eq 'http://localhost' - expect(find_field('Username').value).to eq 'test_user' - expect(find('[name="service[push_channel]"]').value).to eq '#test_channel' - end - - it 'defaults Deployment events to false for chat notification template settings', :js do - first(:link, 'Service Templates').click - click_link 'Slack notifications' - - expect(find_field('Deployment')).not_to be_checked + expect(current_settings.mailgun_events_enabled).to be true + expect(current_settings.mailgun_signing_key).to eq 'MAILGUN_SIGNING_KEY' end end - end - context 'When Service templates are disabled' do - before do - stub_feature_flags(disable_service_templates: true) - end + context 'when mailgun_events_receiver feature flag is disabled' do + let(:mailgun_events_receiver_enabled) { false } - it 'does not show Service Templates link' do - expect(page).not_to have_link('Service Templates') + it 'does not have mailgun' do + expect(page).not_to have_selector('.as-mailgun') + end end end @@ -370,6 +336,43 @@ RSpec.describe 'Admin updates settings' do expect(page).to have_content "Application settings saved successfully" end + context 'Runner Registration' do + context 'when feature is enabled' do + before do + stub_feature_flags(runner_registration_control: true) + end + + it 'allows admins to control who has access to register runners' do + visit ci_cd_admin_application_settings_path + + expect(current_settings.valid_runner_registrars).to eq(ApplicationSetting::VALID_RUNNER_REGISTRAR_TYPES) + + page.within('.as-runner') do + find_all('.form-check-input').each(&:click) + + click_button 'Save changes' + end + + expect(current_settings.valid_runner_registrars).to eq([]) + expect(page).to have_content "Application settings saved successfully" + end + end + + context 'when feature is disabled' do + before do + stub_feature_flags(runner_registration_control: false) + end + + it 'does not allow admins to control who has access to register runners' do + visit ci_cd_admin_application_settings_path + + expect(current_settings.valid_runner_registrars).to eq(ApplicationSetting::VALID_RUNNER_REGISTRAR_TYPES) + + expect(page).not_to have_css('.as-runner') + end + end + end + context 'Container Registry' do let(:feature_flag_enabled) { true } let(:client_support) { true } @@ -530,7 +533,7 @@ RSpec.describe 'Admin updates settings' do wait_for_requests - expect(page).to have_selector '.js-usage-ping-payload' + expect(page).to have_selector '.js-service-ping-payload' expect(page).to have_button 'Hide payload' expect(page).to have_content expected_payload_content end @@ -581,8 +584,8 @@ RSpec.describe 'Admin updates settings' do new_documentation_url = 'https://docs.gitlab.com' page.within('.as-help-page') do - fill_in 'Help page text', with: 'Example text' - check 'Hide marketing-related entries from help' + fill_in 'Additional text to show on the Help page', with: 'Example text' + check 'Hide marketing-related entries from the Help page.' fill_in 'Support page URL', with: new_support_url fill_in 'Documentation pages URL', with: new_documentation_url click_button 'Save changes' diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb index dc528dd92d4..ee64e71f176 100644 --- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb +++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb @@ -28,10 +28,10 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do name = 'Hello World' visit admin_user_impersonation_tokens_path(user_id: user.username) - fill_in "Name", with: name + fill_in "Token name", with: name # Set date to 1st of next month - find_field("Expires at").click + find_field("Expiration date").click find(".pika-next").click click_on "1" diff --git a/spec/features/admin/services/admin_visits_service_templates_spec.rb b/spec/features/admin/services/admin_visits_service_templates_spec.rb index 9d011b97f63..d367867ebb5 100644 --- a/spec/features/admin/services/admin_visits_service_templates_spec.rb +++ b/spec/features/admin/services/admin_visits_service_templates_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'Admin visits service templates' do let(:admin) { create(:user, :admin) } - let(:slack_service) { Integration.for_template.find { |s| s.type == 'SlackService' } } + let(:slack_integration) { Integration.for_template.find { |s| s.type == 'SlackService' } } before do sign_in(admin) @@ -23,7 +23,7 @@ RSpec.describe 'Admin visits service templates' do context 'with an active service template' do before do - create(:slack_service, :template, active: true) + create(:integrations_slack, :template, active: true) visit(admin_application_settings_services_path) end @@ -33,20 +33,20 @@ RSpec.describe 'Admin visits service templates' do context 'without instance-level integration' do it 'shows a link to service template' do - expect(page).to have_link('Slack', href: edit_admin_application_settings_service_path(slack_service.id)) - expect(page).not_to have_link('Slack', href: edit_admin_application_settings_integration_path(slack_service)) + expect(page).to have_link('Slack', href: edit_admin_application_settings_service_path(slack_integration.id)) + expect(page).not_to have_link('Slack', href: edit_admin_application_settings_integration_path(slack_integration)) end end context 'with instance-level integration' do before do - create(:slack_service, instance: true, project: nil) + create(:integrations_slack, instance: true, project: nil) visit(admin_application_settings_services_path) end it 'shows a link to instance-level integration' do - expect(page).not_to have_link('Slack', href: edit_admin_application_settings_service_path(slack_service.id)) - expect(page).to have_link('Slack', href: edit_admin_application_settings_integration_path(slack_service)) + expect(page).not_to have_link('Slack', href: edit_admin_application_settings_service_path(slack_integration.id)) + expect(page).to have_link('Slack', href: edit_admin_application_settings_integration_path(slack_integration)) end end end diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb index 3599658ee56..e6eb76b13eb 100644 --- a/spec/features/admin/users/user_spec.rb +++ b/spec/features/admin/users/user_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'Admin::Users::User' do + include Spec::Support::Helpers::Features::AdminUsersHelpers + let_it_be(:user) { create(:omniauth_user, provider: 'twitter', extern_uid: '123456') } let_it_be(:current_user) { create(:admin) } @@ -12,15 +14,18 @@ RSpec.describe 'Admin::Users::User' do end describe 'GET /admin/users/:id' do - it 'has user info', :aggregate_failures do + it 'has user info', :js, :aggregate_failures do visit admin_user_path(user) expect(page).to have_content(user.email) expect(page).to have_content(user.name) expect(page).to have_content("ID: #{user.id}") expect(page).to have_content("Namespace ID: #{user.namespace_id}") - expect(page).to have_button('Deactivate user') - expect(page).to have_button('Block user') + + click_user_dropdown_toggle(user.id) + + expect(page).to have_button('Block') + expect(page).to have_button('Deactivate') expect(page).to have_button('Delete user') expect(page).to have_button('Delete user and contributions') end @@ -29,9 +34,7 @@ RSpec.describe 'Admin::Users::User' do it 'shows confirmation and allows blocking and unblocking', :js do visit admin_user_path(user) - find('button', text: 'Block user').click - - wait_for_requests + click_action_in_user_dropdown(user.id, 'Block') expect(page).to have_content('Block user') expect(page).to have_content('You can always unblock their account, their data will remain intact.') @@ -41,21 +44,18 @@ RSpec.describe 'Admin::Users::User' do wait_for_requests expect(page).to have_content('Successfully blocked') - expect(page).to have_content('This user is blocked') - - find('button', text: 'Unblock user').click - wait_for_requests + click_action_in_user_dropdown(user.id, 'Unblock') expect(page).to have_content('Unblock user') expect(page).to have_content('You can always block their account again if needed.') find('.modal-footer button', text: 'Unblock').click - wait_for_requests - expect(page).to have_content('Successfully unblocked') - expect(page).to have_content('Block this user') + + click_user_dropdown_toggle(user.id) + expect(page).to have_content('Block') end end @@ -63,9 +63,7 @@ RSpec.describe 'Admin::Users::User' do it 'shows confirmation and allows deactivating/re-activating', :js do visit admin_user_path(user) - find('button', text: 'Deactivate user').click - - wait_for_requests + click_action_in_user_dropdown(user.id, 'Deactivate') expect(page).to have_content('Deactivate user') expect(page).to have_content('You can always re-activate their account, their data will remain intact.') @@ -75,11 +73,8 @@ RSpec.describe 'Admin::Users::User' do wait_for_requests expect(page).to have_content('Successfully deactivated') - expect(page).to have_content('Reactivate this user') - - find('button', text: 'Activate user').click - wait_for_requests + click_action_in_user_dropdown(user.id, 'Activate') expect(page).to have_content('Activate user') expect(page).to have_content('You can always deactivate their account again if needed.') @@ -89,7 +84,9 @@ RSpec.describe 'Admin::Users::User' do wait_for_requests expect(page).to have_content('Successfully activated') - expect(page).to have_content('Deactivate this user') + + click_user_dropdown_toggle(user.id) + expect(page).to have_content('Deactivate') end end @@ -367,8 +364,43 @@ RSpec.describe 'Admin::Users::User' do expect(page).to have_content(user.name) expect(page).to have_content('Pending approval') - expect(page).to have_link('Approve user') - expect(page).to have_link('Reject request') + + click_user_dropdown_toggle(user.id) + + expect(page).to have_button('Approve') + expect(page).to have_button('Reject') + end + end + end + + context 'when user has an unconfirmed email', :js do + let(:unconfirmed_user) { create(:user, :unconfirmed) } + + where(:path_helper) do + [ + [-> (user) { admin_user_path(user) }], + [-> (user) { projects_admin_user_path(user) }], + [-> (user) { keys_admin_user_path(user) }], + [-> (user) { admin_user_identities_path(user) }], + [-> (user) { admin_user_impersonation_tokens_path(user) }] + ] + end + + with_them do + it "allows an admin to force confirmation of the user's email", :aggregate_failures do + visit path_helper.call(unconfirmed_user) + + click_button 'Confirm user' + + page.within('[role="dialog"]') do + expect(page).to have_content("Confirm user #{unconfirmed_user.name}?") + expect(page).to have_content('This user has an unconfirmed email address. You may force a confirmation.') + + click_button 'Confirm user' + end + + expect(page).to have_content('Successfully confirmed') + expect(page).not_to have_button('Confirm user') end end end diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb index 187fa6fc2a4..119b01ff552 100644 --- a/spec/features/admin/users/users_spec.rb +++ b/spec/features/admin/users/users_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'Admin::Users' do + include Spec::Support::Helpers::Features::AdminUsersHelpers + let_it_be(:user, reload: true) { create(:omniauth_user, provider: 'twitter', extern_uid: '123456') } let_it_be(:current_user) { create(:admin) } @@ -572,12 +574,6 @@ RSpec.describe 'Admin::Users' do end end - def click_user_dropdown_toggle(user_id) - page.within("[data-testid='user-actions-#{user_id}']") do - find("[data-testid='dropdown-toggle']").click - end - end - def first_row page.all('[role="row"]')[1] end @@ -592,14 +588,4 @@ RSpec.describe 'Admin::Users' do click_link option end end - - def click_action_in_user_dropdown(user_id, action) - click_user_dropdown_toggle(user_id) - - within find("[data-testid='user-actions-#{user_id}']") do - find('li button', text: action).click - end - - wait_for_requests - end end diff --git a/spec/features/alert_management/alert_management_list_spec.rb b/spec/features/alert_management/alert_management_list_spec.rb index aeaadacb38d..1e710169c9c 100644 --- a/spec/features/alert_management/alert_management_list_spec.rb +++ b/spec/features/alert_management/alert_management_list_spec.rb @@ -50,7 +50,7 @@ RSpec.describe 'Alert Management index', :js do end context 'when the prometheus integration is enabled' do - let_it_be(:integration) { create(:prometheus_service, project: project) } + let_it_be(:integration) { create(:prometheus_integration, project: project) } it_behaves_like 'alert page with title, filtered search, and table' end diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 02bb7574fb0..4b52bb953ed 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -244,8 +244,7 @@ RSpec.describe 'Project issue boards', :js do expect(page).to have_selector(selector, text: development.title, count: 1) end - # TODO https://gitlab.com/gitlab-org/gitlab/-/issues/323551 - xit 'issue moves between lists and does not show the "Development" label since the card is in the "Development" list label' do + it 'issue moves between lists and does not show the "Development" label since the card is in the "Development" list label' do drag(list_from_index: 1, from_index: 1, list_to_index: 2) wait_for_board_cards(2, 7) diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb index 977147c3c6b..0bb8e0bcdc0 100644 --- a/spec/features/boards/sidebar_spec.rb +++ b/spec/features/boards/sidebar_spec.rb @@ -31,4 +31,12 @@ RSpec.describe 'Project issue boards sidebar', :js do def click_first_issue_card click_card(first_card) end + + def refresh_and_click_first_card + page.refresh + + wait_for_requests + + first_card.click + end end diff --git a/spec/features/calendar_spec.rb b/spec/features/calendar_spec.rb index 21da92c9f43..a8aa3f0b36a 100644 --- a/spec/features/calendar_spec.rb +++ b/spec/features/calendar_spec.rb @@ -145,7 +145,7 @@ RSpec.describe 'Contributions Calendar', :js do describe '1 issue creation calendar activity' do before do - Issues::CreateService.new(project: contributed_project, current_user: user, params: issue_params).execute + Issues::CreateService.new(project: contributed_project, current_user: user, params: issue_params, spam_params: nil).execute end it_behaves_like 'a day with activity', contribution_count: 1 @@ -180,7 +180,7 @@ RSpec.describe 'Contributions Calendar', :js do push_code_contribution travel_to(Date.yesterday) do - Issues::CreateService.new(project: contributed_project, current_user: user, params: issue_params).execute + Issues::CreateService.new(project: contributed_project, current_user: user, params: issue_params, spam_params: nil).execute end end include_context 'visit user page' diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb index 8c7564535b5..d0f8767884e 100644 --- a/spec/features/cycle_analytics_spec.rb +++ b/spec/features/cycle_analytics_spec.rb @@ -6,6 +6,7 @@ RSpec.describe 'Value Stream Analytics', :js do let_it_be(:user) { create(:user) } let_it_be(:guest) { create(:user) } let_it_be(:project) { create(:project, :repository) } + let(:issue) { create(:issue, project: project, created_at: 2.days.ago) } let(:milestone) { create(:milestone, project: project) } let(:mr) { create_merge_request_closing_issue(user, project, issue, commit_message: "References #{issue.to_reference}") } diff --git a/spec/features/dashboard/datetime_on_tooltips_spec.rb b/spec/features/dashboard/datetime_on_tooltips_spec.rb index 442b8904974..bf9f6895d24 100644 --- a/spec/features/dashboard/datetime_on_tooltips_spec.rb +++ b/spec/features/dashboard/datetime_on_tooltips_spec.rb @@ -5,6 +5,7 @@ require 'spec_helper' RSpec.describe 'Tooltips on .timeago dates', :js do let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, name: 'test', namespace: user.namespace) } + let(:created_date) { 1.day.ago.beginning_of_minute - 1.hour } before_all do diff --git a/spec/features/dashboard/issues_filter_spec.rb b/spec/features/dashboard/issues_filter_spec.rb index 4bd00bd0a80..4d59e1ded3d 100644 --- a/spec/features/dashboard/issues_filter_spec.rb +++ b/spec/features/dashboard/issues_filter_spec.rb @@ -81,14 +81,14 @@ RSpec.describe 'Dashboard Issues filtering', :js do sort_by('Created date') visit_issues(assignee_username: user.username) - expect(find('.issues-filters')).to have_content('Created date') + expect(page).to have_button('Created date') end it 'keeps sorting issues after visiting Projects Issues page' do sort_by('Created date') visit project_issues_path(project) - expect(find('.issues-filters')).to have_content('Created date') + expect(page).to have_button('Created date') end end diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb index 26b376be660..aa2485d4236 100644 --- a/spec/features/dashboard/merge_requests_spec.rb +++ b/spec/features/dashboard/merge_requests_spec.rb @@ -53,6 +53,7 @@ RSpec.describe 'Dashboard Merge Requests' do context 'merge requests exist' do let_it_be(:author_user) { create(:user) } + let(:label) { create(:label) } let!(:assigned_merge_request) do @@ -181,6 +182,7 @@ RSpec.describe 'Dashboard Merge Requests' do context 'merge request review', :js do let_it_be(:author_user) { create(:user) } + let!(:review_requested_merge_request) do create(:merge_request, reviewers: [current_user], diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb index 20c753b1cdb..1f0981de7e1 100644 --- a/spec/features/dashboard/projects_spec.rb +++ b/spec/features/dashboard/projects_spec.rb @@ -18,12 +18,6 @@ RSpec.describe 'Dashboard Projects' do end end - it 'shows the customize banner', :js do - visit dashboard_projects_path - - expect(page).to have_content('Do you want to customize this page?') - end - context 'when user has access to the project' do it 'shows role badge' do visit dashboard_projects_path diff --git a/spec/features/dashboard/root_spec.rb b/spec/features/dashboard/root_spec.rb new file mode 100644 index 00000000000..55bb43c6fcf --- /dev/null +++ b/spec/features/dashboard/root_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Root path' do + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project) } + + before do + project.add_developer(user) + sign_in(user) + end + + it 'shows the customize banner', :js do + visit root_path + + expect(page).to have_content('Do you want to customize this page?') + end +end diff --git a/spec/features/file_uploads/group_import_spec.rb b/spec/features/file_uploads/group_import_spec.rb index 0f9d05c3975..a8592f99bd6 100644 --- a/spec/features/file_uploads/group_import_spec.rb +++ b/spec/features/file_uploads/group_import_spec.rb @@ -7,6 +7,7 @@ RSpec.describe 'Upload a group export archive', :api, :js do let_it_be(:user) { create(:user, :admin) } let_it_be(:personal_access_token) { create(:personal_access_token, user: user) } + let(:api_path) { '/groups/import' } let(:url) { capybara_url(api(api_path, personal_access_token: personal_access_token)) } let(:file) { fixture_file_upload('spec/fixtures/group_export.tar.gz') } diff --git a/spec/features/file_uploads/project_import_spec.rb b/spec/features/file_uploads/project_import_spec.rb index 1bf16f46c63..82b6f490d2a 100644 --- a/spec/features/file_uploads/project_import_spec.rb +++ b/spec/features/file_uploads/project_import_spec.rb @@ -7,6 +7,7 @@ RSpec.describe 'Upload a project export archive', :api, :js do let_it_be(:user) { create(:user, :admin) } let_it_be(:personal_access_token) { create(:personal_access_token, user: user) } + let(:api_path) { '/projects/import' } let(:url) { capybara_url(api(api_path, personal_access_token: personal_access_token)) } let(:file) { fixture_file_upload('spec/features/projects/import_export/test_project_export.tar.gz') } diff --git a/spec/features/file_uploads/user_avatar_spec.rb b/spec/features/file_uploads/user_avatar_spec.rb index 043115be61a..c30e3452201 100644 --- a/spec/features/file_uploads/user_avatar_spec.rb +++ b/spec/features/file_uploads/user_avatar_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe 'Upload a user avatar', :js do let_it_be(:user, reload: true) { create(:user) } + let(:file) { fixture_file_upload('spec/fixtures/banana_sample.gif') } before do diff --git a/spec/features/groups/import_export/connect_instance_spec.rb b/spec/features/groups/import_export/connect_instance_spec.rb index 563c8f429f8..cf893e444c4 100644 --- a/spec/features/groups/import_export/connect_instance_spec.rb +++ b/spec/features/groups/import_export/connect_instance_spec.rb @@ -24,6 +24,7 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do pat = 'demo-pat' stub_path = 'stub-group' total = 37 + stub_request(:get, "%{url}/api/v4/groups?page=1&per_page=20&top_level_only=true&min_access_level=50&search=" % { url: source_url }).to_return( body: [{ id: 2595438, @@ -32,7 +33,7 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do path: stub_path, full_name: 'Stub', full_path: stub_path - }].to_json, + }].to_json, headers: { 'Content-Type' => 'application/json', 'X-Next-Page' => 2, @@ -43,6 +44,10 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do } ) + allow_next_instance_of(BulkImports::Clients::HTTP) do |client| + allow(client).to receive(:validate_instance_version!).and_return(true) + end + expect(page).to have_content 'Import groups from another instance of GitLab' expect(page).to have_content 'Not all related objects are migrated' @@ -53,6 +58,10 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do expect(page).to have_content 'Showing 1-1 of %{total} groups from %{url}' % { url: source_url, total: total } expect(page).to have_content stub_path + + visit '/' + + wait_for_all_requests end end diff --git a/spec/features/groups/import_export/import_file_spec.rb b/spec/features/groups/import_export/import_file_spec.rb index 08295a3392a..76d17c4409d 100644 --- a/spec/features/groups/import_export/import_file_spec.rb +++ b/spec/features/groups/import_export/import_file_spec.rb @@ -77,7 +77,7 @@ RSpec.describe 'Import/Export - Group Import', :js do click_link 'Import group' fill_in :import_group_path, with: 'test-group-import' - expect(page).to have_content 'Group path is already taken. Suggestions: test-group-import1' + expect(page).to have_content "Group path is already taken. We've suggested one that is available." end end end diff --git a/spec/features/groups/members/manage_members_spec.rb b/spec/features/groups/members/manage_members_spec.rb index ee18298e894..1d57d0a9103 100644 --- a/spec/features/groups/members/manage_members_spec.rb +++ b/spec/features/groups/members/manage_members_spec.rb @@ -93,13 +93,13 @@ RSpec.describe 'Groups > Members > Manage members' do visit group_group_members_path(group) click_on 'Invite members' - fill_in 'Select members or type email addresses', with: '@gitlab.com' + find('[data-testid="members-token-select-input"]').set('@gitlab.com') wait_for_requests expect(page).to have_content('No matches found') - fill_in 'Select members or type email addresses', with: 'undisclosed_email@gitlab.com' + find('[data-testid="members-token-select-input"]').set('undisclosed_email@gitlab.com') wait_for_requests expect(page).to have_content("Jane 'invisible' Doe") diff --git a/spec/features/groups/merge_requests_spec.rb b/spec/features/groups/merge_requests_spec.rb index f79c93157dc..077f680629f 100644 --- a/spec/features/groups/merge_requests_spec.rb +++ b/spec/features/groups/merge_requests_spec.rb @@ -75,4 +75,29 @@ RSpec.describe 'Group merge requests page' do end end end + + context 'empty state with no merge requests' do + before do + MergeRequest.delete_all + end + + it 'shows an empty state, button to create merge request and no filters bar', :aggregate_failures, :js do + visit path + + expect(page).to have_selector('.empty-state') + expect(page).to have_link('Select project to create merge request') + expect(page).not_to have_selector('.issues-filters') + end + + context 'with no open merge requests' do + it 'shows an empty state, button to create merge request and filters bar', :aggregate_failures, :js do + create(:merge_request, :closed, source_project: project, target_project: project) + visit path + + expect(page).to have_selector('.empty-state') + expect(page).to have_link('Select project to create merge request') + expect(page).to have_selector('.issues-filters') + end + end + end end diff --git a/spec/features/groups/navbar_spec.rb b/spec/features/groups/navbar_spec.rb index 70a19445c89..0a159056569 100644 --- a/spec/features/groups/navbar_spec.rb +++ b/spec/features/groups/navbar_spec.rb @@ -11,40 +11,6 @@ RSpec.describe 'Group navbar' do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group) } - let(:structure) do - [ - group_context_nav_item, - group_information_nav_item, - { - nav_item: _('Issues'), - nav_sub_items: issues_nav_items - }, - { - nav_item: _('Merge requests'), - nav_sub_items: [] - }, - (security_and_compliance_nav_item if Gitlab.ee?), - (push_rules_nav_item if Gitlab.ee?), - { - nav_item: _('Kubernetes'), - nav_sub_items: [] - }, - (analytics_nav_item if Gitlab.ee?), - members_nav_item - ].compact - end - - let(:members_nav_item) do - nil - end - - let(:group_context_nav_item) do - { - nav_item: "#{group.name[0, 1].upcase} #{group.name}", - nav_sub_items: [] - } - end - before do insert_package_nav(_('Kubernetes')) @@ -85,44 +51,4 @@ RSpec.describe 'Group navbar' do it_behaves_like 'verified navigation bar' end - - context 'when feature flag :sidebar_refactor is disabled' do - let(:group_context_nav_item) do - nil - end - - let(:group_information_nav_item) do - { - nav_item: _('Group overview'), - nav_sub_items: [ - _('Details'), - _('Activity') - ] - } - end - - let(:members_nav_item) do - { - nav_item: _('Members'), - nav_sub_items: [] - } - end - - let(:issues_nav_items) do - [ - _('List'), - _('Board'), - _('Labels'), - _('Milestones') - ] - end - - before do - stub_feature_flags(sidebar_refactor: false) - - visit group_path(group) - end - - it_behaves_like 'verified navigation bar' - end end diff --git a/spec/features/groups/packages_spec.rb b/spec/features/groups/packages_spec.rb index 60e0c08b3d4..752303fdd78 100644 --- a/spec/features/groups/packages_spec.rb +++ b/spec/features/groups/packages_spec.rb @@ -38,18 +38,22 @@ RSpec.describe 'Group Packages' do context 'when there are packages' do let_it_be(:second_project) { create(:project, name: 'second-project', group: group) } - let_it_be(:conan_package) { create(:conan_package, project: project, name: 'zzz', created_at: 1.day.ago, version: '1.0.0') } + let_it_be(:npm_package) { create(:npm_package, project: project, name: 'zzz', created_at: 1.day.ago, version: '1.0.0') } let_it_be(:maven_package) { create(:maven_package, project: second_project, name: 'aaa', created_at: 2.days.ago, version: '2.0.0') } - let_it_be(:packages) { [conan_package, maven_package] } + let_it_be(:packages) { [npm_package, maven_package] } it_behaves_like 'packages list', check_project_name: true - it_behaves_like 'package details link' + context 'when package_details_apollo feature flag is off' do + before do + stub_feature_flags(package_details_apollo: false) + end + + it_behaves_like 'package details link' + end it 'allows you to navigate to the project page' do - page.within('[data-qa-selector="packages-table"]') do - find('[data-qa-selector="package-path"]', text: project.name).click - end + find('[data-testid="root-link"]', text: project.name).click expect(page).to have_current_path(project_path(project)) expect(page).to have_content(project.name) @@ -58,15 +62,15 @@ RSpec.describe 'Group Packages' do context 'sorting' do it_behaves_like 'shared package sorting' do let_it_be(:package_one) { maven_package } - let_it_be(:package_two) { conan_package } + let_it_be(:package_two) { npm_package } end it_behaves_like 'correctly sorted packages list', 'Project' do - let(:packages) { [maven_package, conan_package] } + let(:packages) { [maven_package, npm_package] } end it_behaves_like 'correctly sorted packages list', 'Project', ascending: true do - let(:packages) { [conan_package, maven_package] } + let(:packages) { [npm_package, maven_package] } end end end diff --git a/spec/features/groups/settings/repository_spec.rb b/spec/features/groups/settings/repository_spec.rb index 3c1609a2605..7082b2b20bd 100644 --- a/spec/features/groups/settings/repository_spec.rb +++ b/spec/features/groups/settings/repository_spec.rb @@ -38,7 +38,7 @@ RSpec.describe 'Group Repository settings' do it 'renders the correct setting section content' do within("#js-default-branch-name") do expect(page).to have_content("Default initial branch name") - expect(page).to have_content("Set the default name of the initial branch when creating new repositories through the user interface.") + expect(page).to have_content("The default name for the initial branch of new repositories created in the group.") end end end diff --git a/spec/features/groups/settings/user_searches_in_settings_spec.rb b/spec/features/groups/settings/user_searches_in_settings_spec.rb index a01514714dd..c258dd41b03 100644 --- a/spec/features/groups/settings/user_searches_in_settings_spec.rb +++ b/spec/features/groups/settings/user_searches_in_settings_spec.rb @@ -24,7 +24,7 @@ RSpec.describe 'User searches group settings', :js do visit group_settings_integrations_path(group) end - it_behaves_like 'can highlight results', 'Project integration management' + it_behaves_like 'can highlight results', 'Group-level integration management' end context 'in Repository page' do @@ -48,6 +48,6 @@ RSpec.describe 'User searches group settings', :js do visit group_settings_packages_and_registries_path(group) end - it_behaves_like 'can highlight results', 'GitLab Packages' + it_behaves_like 'can highlight results', 'Use GitLab as a private registry' end end diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb index 4bcba4c21ed..79226facad4 100644 --- a/spec/features/groups/show_spec.rb +++ b/spec/features/groups/show_spec.rb @@ -208,13 +208,13 @@ RSpec.describe 'Group show page' do expect(page).to have_selector('.content[itemscope][itemtype="https://schema.org/Organization"]') page.within('.group-home-panel') do - expect(page).to have_selector('img.avatar[itemprop="logo"]') + expect(page).to have_selector('[itemprop="logo"]') expect(page).to have_selector('[itemprop="name"]', text: group.name) expect(page).to have_selector('[itemprop="description"]', text: group.description) end page.within('[itemprop="owns"][itemtype="https://schema.org/SoftwareSourceCode"]') do - expect(page).to have_selector('img.avatar[itemprop="image"]') + expect(page).to have_selector('[itemprop="image"]') expect(page).to have_selector('[itemprop="name"]', text: project.name) expect(page).to have_selector('[itemprop="description"]', text: project.description) end @@ -224,12 +224,12 @@ RSpec.describe 'Group show page' do el.click wait_for_all_requests page.within(el) do - expect(page).to have_selector('img.avatar[itemprop="logo"]') + expect(page).to have_selector('[itemprop="logo"]') expect(page).to have_selector('[itemprop="name"]', text: subgroup.name) expect(page).to have_selector('[itemprop="description"]', text: subgroup.description) page.within('[itemprop="owns"][itemtype="https://schema.org/SoftwareSourceCode"]') do - expect(page).to have_selector('img.avatar[itemprop="image"]') + expect(page).to have_selector('[itemprop="image"]') expect(page).to have_selector('[itemprop="name"]', text: subproject.name) expect(page).to have_selector('[itemprop="description"]', text: subproject.description) end diff --git a/spec/features/groups/user_browse_projects_group_page_spec.rb b/spec/features/groups/user_browse_projects_group_page_spec.rb index 999449a94b0..73fde7cafe5 100644 --- a/spec/features/groups/user_browse_projects_group_page_spec.rb +++ b/spec/features/groups/user_browse_projects_group_page_spec.rb @@ -23,7 +23,7 @@ RSpec.describe 'User browse group projects page' do visit projects_group_path(group) expect(page).to have_link project.name - expect(page).to have_xpath("//span[@class='badge badge-warning']", text: 'archived') + expect(page).to have_css('span.badge.badge-warning', text: 'archived') end end end diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb index 5f8079f0436..efde570512f 100644 --- a/spec/features/groups_spec.rb +++ b/spec/features/groups_spec.rb @@ -90,7 +90,7 @@ RSpec.describe 'Group' do fill_in 'group_path', with: user.username wait_for_requests - expect(page).to have_content('Group path is already taken') + expect(page).to have_content("Group path is already taken. We've suggested one that is available.") end it 'does not break after an invalid form submit' do @@ -257,7 +257,7 @@ RSpec.describe 'Group' do fill_in 'Group URL', with: subgroup.path wait_for_requests - expect(page).to have_content('Group path is already taken') + expect(page).to have_content("Group path is already taken. We've suggested one that is available.") end end end @@ -447,35 +447,6 @@ RSpec.describe 'Group' do end end - describe 'new_repo experiment' do - let_it_be(:group) { create_default(:group) } - - it 'when in candidate renders "project/repository"' do - stub_experiments(new_repo: :candidate) - - visit group_path(group) - - find('li.header-new.dropdown').click - - page.within('li.header-new.dropdown') do - expect(page).to have_selector('a', text: 'New project/repository') - end - end - - it 'when in control renders "project/repository"' do - stub_experiments(new_repo: :control) - - visit group_path(group) - - find('li.header-new.dropdown').click - - page.within('li.header-new.dropdown') do - expect(page).to have_selector('a', text: 'New project') - expect(page).to have_no_selector('a', text: 'New project/repository') - end - end - end - def remove_with_confirm(button_text, confirm_with) click_button button_text fill_in 'confirm_name_input', with: confirm_with diff --git a/spec/features/help_pages_spec.rb b/spec/features/help_pages_spec.rb index 90647305281..66ba4dc987c 100644 --- a/spec/features/help_pages_spec.rb +++ b/spec/features/help_pages_spec.rb @@ -65,7 +65,7 @@ RSpec.describe 'Help Pages' do end it 'uses a custom support url' do - expect(page).to have_link "See our website for getting help", href: "http://example.com/help" + expect(page).to have_link "See our website for help", href: "http://example.com/help" end end end diff --git a/spec/features/invites_spec.rb b/spec/features/invites_spec.rb index a72cf033d61..93602033d73 100644 --- a/spec/features/invites_spec.rb +++ b/spec/features/invites_spec.rb @@ -272,54 +272,15 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do end end - context 'with invite_signup_page_interaction experiment on', :experiment do - context 'with control experience' do - before do - stub_experiments(invite_signup_page_interaction: :control) - end - - it 'lands on invite sign up page and tracks the accepted invite' do - expect(experiment(:invite_signup_page_interaction)).to track(:view) - .with_context(actor: group_invite) - .on_next_instance - - visit invite_path(group_invite.raw_invite_token) - - expect(current_path).to eq(new_user_registration_path) - - expect(experiment(:invite_signup_page_interaction)).to track(:form_submission) - .with_context(actor: group_invite) - .on_next_instance - - fill_in_sign_up_form(new_user, 'Register') - - expect(current_path).to eq(users_sign_up_welcome_path) - end - end - - context 'with candidate experience on .com' do - before do - allow(Gitlab).to receive(:dev_env_or_com?).and_return(true) - stub_experiments(invite_signup_page_interaction: :candidate) - end + context 'when accepting an invite without an account' do + it 'lands on sign up page and then registers' do + visit invite_path(group_invite.raw_invite_token) - it 'lands on invite sign up page and tracks the accepted invite' do - expect(experiment(:invite_signup_page_interaction)).to track(:view) - .with_context(actor: group_invite) - .on_next_instance + expect(current_path).to eq(new_user_registration_path) - visit invite_path(group_invite.raw_invite_token) - - expect(current_path).to eq(new_users_sign_up_invite_path) - - expect(experiment(:invite_signup_page_interaction)).to track(:form_submission) - .with_context(actor: group_invite) - .on_next_instance + fill_in_sign_up_form(new_user, 'Register') - fill_in_sign_up_form(new_user, 'Continue') - - expect(current_path).to eq(users_sign_up_welcome_path) - end + expect(current_path).to eq(users_sign_up_welcome_path) end end diff --git a/spec/features/issuables/markdown_references/jira_spec.rb b/spec/features/issuables/markdown_references/jira_spec.rb index a3a259e21a1..ae9c8d31c02 100644 --- a/spec/features/issuables/markdown_references/jira_spec.rb +++ b/spec/features/issuables/markdown_references/jira_spec.rb @@ -81,7 +81,7 @@ RSpec.describe "Jira", :js do context "when both external and internal issues trackers are enabled for the actual project" do before do - create(:jira_service, project: actual_project) + create(:jira_integration, project: actual_project) end include_examples "correct references" do @@ -94,7 +94,7 @@ RSpec.describe "Jira", :js do let(:actual_project) { create(:project, :public, :repository, :issues_disabled) } before do - create(:jira_service, project: actual_project) + create(:jira_integration, project: actual_project) end include_examples "correct references" do @@ -125,7 +125,7 @@ RSpec.describe "Jira", :js do context "when both external and internal issues trackers are enabled for the actual project" do before do - create(:jira_service, project: actual_project) + create(:jira_integration, project: actual_project) end include_examples "correct references" do @@ -138,7 +138,7 @@ RSpec.describe "Jira", :js do let(:actual_project) { create(:project, :public, :repository, :issues_disabled) } before do - create(:jira_service, project: actual_project) + create(:jira_integration, project: actual_project) end include_examples "correct references" do diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb index 381633b0fc9..e873ebb21c4 100644 --- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb @@ -5,15 +5,16 @@ require 'spec_helper' RSpec.describe 'Dropdown assignee', :js do include FilteredSearchHelpers - let!(:project) { create(:project) } - let!(:user) { create(:user, name: 'administrator', username: 'root') } + let_it_be(:project) { create(:project) } + let_it_be(:user) { create(:user, name: 'administrator', username: 'root') } + let_it_be(:issue) { create(:issue, project: project) } + let(:js_dropdown_assignee) { '#js-dropdown-assignee' } let(:filter_dropdown) { find("#{js_dropdown_assignee} .filter-dropdown") } before do project.add_maintainer(user) sign_in(user) - create(:issue, project: project) visit project_issues_path(project) end diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb index 91c85825a17..893ffc6575b 100644 --- a/spec/features/issues/filtered_search/dropdown_author_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb @@ -5,15 +5,16 @@ require 'spec_helper' RSpec.describe 'Dropdown author', :js do include FilteredSearchHelpers - let!(:project) { create(:project) } - let!(:user) { create(:user, name: 'administrator', username: 'root') } + let_it_be(:project) { create(:project) } + let_it_be(:user) { create(:user, name: 'administrator', username: 'root') } + let_it_be(:issue) { create(:issue, project: project) } + let(:js_dropdown_author) { '#js-dropdown-author' } let(:filter_dropdown) { find("#{js_dropdown_author} .filter-dropdown") } before do project.add_maintainer(user) sign_in(user) - create(:issue, project: project) visit project_issues_path(project) end diff --git a/spec/features/issues/filtered_search/dropdown_base_spec.rb b/spec/features/issues/filtered_search/dropdown_base_spec.rb index d730525cb8b..3a304515cab 100644 --- a/spec/features/issues/filtered_search/dropdown_base_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_base_spec.rb @@ -5,8 +5,10 @@ require 'spec_helper' RSpec.describe 'Dropdown base', :js do include FilteredSearchHelpers - let!(:project) { create(:project) } - let!(:user) { create(:user, name: 'administrator', username: 'root') } + let_it_be(:project) { create(:project) } + let_it_be(:user) { create(:user, name: 'administrator', username: 'root') } + let_it_be(:issue) { create(:issue, project: project) } + let(:filtered_search) { find('.filtered-search') } let(:js_dropdown_assignee) { '#js-dropdown-assignee' } let(:filter_dropdown) { find("#{js_dropdown_assignee} .filter-dropdown") } @@ -18,7 +20,6 @@ RSpec.describe 'Dropdown base', :js do before do project.add_maintainer(user) sign_in(user) - create(:issue, project: project) visit project_issues_path(project) end diff --git a/spec/features/issues/filtered_search/dropdown_emoji_spec.rb b/spec/features/issues/filtered_search/dropdown_emoji_spec.rb index c2c933f8a86..f5ab53d5052 100644 --- a/spec/features/issues/filtered_search/dropdown_emoji_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_emoji_spec.rb @@ -5,10 +5,11 @@ require 'spec_helper' RSpec.describe 'Dropdown emoji', :js do include FilteredSearchHelpers - let!(:project) { create(:project, :public) } - let!(:user) { create(:user, name: 'administrator', username: 'root') } - let!(:issue) { create(:issue, project: project) } - let!(:award_emoji_star) { create(:award_emoji, name: 'star', user: user, awardable: issue) } + let_it_be(:project) { create(:project, :public) } + let_it_be(:user) { create(:user, name: 'administrator', username: 'root') } + let_it_be(:issue) { create(:issue, project: project) } + let_it_be(:award_emoji_star) { create(:award_emoji, name: 'star', user: user, awardable: issue) } + let(:filtered_search) { find('.filtered-search') } let(:js_dropdown_emoji) { '#js-dropdown-my-reaction' } let(:filter_dropdown) { find("#{js_dropdown_emoji} .filter-dropdown") } diff --git a/spec/features/issues/filtered_search/dropdown_hint_spec.rb b/spec/features/issues/filtered_search/dropdown_hint_spec.rb index 9edc6e0b593..9cc58a33bb7 100644 --- a/spec/features/issues/filtered_search/dropdown_hint_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_hint_spec.rb @@ -5,8 +5,10 @@ require 'spec_helper' RSpec.describe 'Dropdown hint', :js do include FilteredSearchHelpers - let!(:project) { create(:project, :public) } - let!(:user) { create(:user) } + let_it_be(:project) { create(:project, :public) } + let_it_be(:user) { create(:user) } + let_it_be(:issue) { create(:issue, project: project) } + let(:filtered_search) { find('.filtered-search') } let(:js_dropdown_hint) { '#js-dropdown-hint' } let(:js_dropdown_operator) { '#js-dropdown-operator' } @@ -21,8 +23,6 @@ RSpec.describe 'Dropdown hint', :js do before do project.add_maintainer(user) - create(:issue, project: project) - create(:merge_request, source_project: project, target_project: project) end context 'when user not logged in' do diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb index c0d5fe0d860..1b48810f716 100644 --- a/spec/features/issues/filtered_search/dropdown_label_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb @@ -5,22 +5,23 @@ require 'spec_helper' RSpec.describe 'Dropdown label', :js do include FilteredSearchHelpers - let(:project) { create(:project) } - let(:user) { create(:user) } + let_it_be(:project) { create(:project) } + let_it_be(:user) { create(:user) } + let_it_be(:issue) { create(:issue, project: project) } + let_it_be(:label) { create(:label, project: project, title: 'bug-label') } + let(:filtered_search) { find('.filtered-search') } let(:filter_dropdown) { find('#js-dropdown-label .filter-dropdown') } before do project.add_maintainer(user) sign_in(user) - create(:issue, project: project) visit project_issues_path(project) end describe 'behavior' do it 'loads all the labels when opened' do - create(:label, project: project, title: 'bug-label') filtered_search.set('label:=') expect_filtered_search_dropdown_results(filter_dropdown, 1) diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb index 68afd973f1d..859d1e4a5e5 100644 --- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb @@ -5,10 +5,11 @@ require 'spec_helper' RSpec.describe 'Dropdown milestone', :js do include FilteredSearchHelpers - let!(:project) { create(:project) } - let!(:user) { create(:user) } - let!(:milestone) { create(:milestone, title: 'v1.0', project: project) } - let!(:uppercase_milestone) { create(:milestone, title: 'CAP_MILESTONE', project: project) } + let_it_be(:project) { create(:project) } + let_it_be(:user) { create(:user) } + let_it_be(:milestone) { create(:milestone, title: 'v1.0', project: project) } + let_it_be(:uppercase_milestone) { create(:milestone, title: 'CAP_MILESTONE', project: project) } + let_it_be(:issue) { create(:issue, project: project) } let(:filtered_search) { find('.filtered-search') } let(:filter_dropdown) { find('#js-dropdown-milestone .filter-dropdown') } @@ -16,7 +17,6 @@ RSpec.describe 'Dropdown milestone', :js do before do project.add_maintainer(user) sign_in(user) - create(:issue, project: project) visit project_issues_path(project) end diff --git a/spec/features/issues/filtered_search/dropdown_release_spec.rb b/spec/features/issues/filtered_search/dropdown_release_spec.rb index daf686c2850..2210a26c251 100644 --- a/spec/features/issues/filtered_search/dropdown_release_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_release_spec.rb @@ -5,10 +5,11 @@ require 'spec_helper' RSpec.describe 'Dropdown release', :js do include FilteredSearchHelpers - let!(:project) { create(:project, :repository) } - let!(:user) { create(:user) } - let!(:release) { create(:release, tag: 'v1.0', project: project) } - let!(:crazy_release) { create(:release, tag: '☺!/"#%&\'{}+,-.<>;=@]_`{|}🚀', project: project) } + let_it_be(:project) { create(:project, :repository) } + let_it_be(:user) { create(:user) } + let_it_be(:release) { create(:release, tag: 'v1.0', project: project) } + let_it_be(:crazy_release) { create(:release, tag: '☺!/"#%&\'{}+,-.<>;=@]_`{|}🚀', project: project) } + let_it_be(:issue) { create(:issue, project: project) } let(:filtered_search) { find('.filtered-search') } let(:filter_dropdown) { find('#js-dropdown-release .filter-dropdown') } @@ -16,7 +17,6 @@ RSpec.describe 'Dropdown release', :js do before do project.add_maintainer(user) sign_in(user) - create(:issue, project: project) visit project_issues_path(project) end diff --git a/spec/features/issues/filtered_search/recent_searches_spec.rb b/spec/features/issues/filtered_search/recent_searches_spec.rb index 61c1e35f3c8..3ddcbf1bd01 100644 --- a/spec/features/issues/filtered_search/recent_searches_spec.rb +++ b/spec/features/issues/filtered_search/recent_searches_spec.rb @@ -6,14 +6,15 @@ RSpec.describe 'Recent searches', :js do include FilteredSearchHelpers include MobileHelpers - let(:project_1) { create(:project, :public) } - let(:project_2) { create(:project, :public) } + let_it_be(:project_1) { create(:project, :public) } + let_it_be(:project_2) { create(:project, :public) } + let_it_be(:issue_1) { create(:issue, project: project_1) } + let_it_be(:issue_2) { create(:issue, project: project_2) } + let(:project_1_local_storage_key) { "#{project_1.full_path}-issue-recent-searches" } before do Capybara.ignore_hidden_elements = false - create(:issue, project: project_1) - create(:issue, project: project_2) # Visit any fast-loading page so we can clear local storage without a DOM exception visit '/404' diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb index 2a094281133..1efcc329e32 100644 --- a/spec/features/issues/filtered_search/search_bar_spec.rb +++ b/spec/features/issues/filtered_search/search_bar_spec.rb @@ -5,14 +5,15 @@ require 'spec_helper' RSpec.describe 'Search bar', :js do include FilteredSearchHelpers - let!(:project) { create(:project) } - let!(:user) { create(:user) } + let_it_be(:project) { create(:project) } + let_it_be(:user) { create(:user) } + let_it_be(:issue) { create(:issue, project: project) } + let(:filtered_search) { find('.filtered-search') } before do project.add_maintainer(user) sign_in(user) - create(:issue, project: project) visit project_issues_path(project) end diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb index c585d7f6194..644d7cc4611 100644 --- a/spec/features/issues/filtered_search/visual_tokens_spec.rb +++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb @@ -5,13 +5,14 @@ require 'spec_helper' RSpec.describe 'Visual tokens', :js do include FilteredSearchHelpers - let!(:project) { create(:project) } - let!(:user) { create(:user, name: 'administrator', username: 'root') } - let!(:user_rock) { create(:user, name: 'The Rock', username: 'rock') } - let!(:milestone_nine) { create(:milestone, title: '9.0', project: project) } - let!(:milestone_ten) { create(:milestone, title: '10.0', project: project) } - let!(:label) { create(:label, project: project, title: 'abc') } - let!(:cc_label) { create(:label, project: project, title: 'Community Contribution') } + let_it_be(:project) { create(:project) } + let_it_be(:user) { create(:user, name: 'administrator', username: 'root') } + let_it_be(:user_rock) { create(:user, name: 'The Rock', username: 'rock') } + let_it_be(:milestone_nine) { create(:milestone, title: '9.0', project: project) } + let_it_be(:milestone_ten) { create(:milestone, title: '10.0', project: project) } + let_it_be(:label) { create(:label, project: project, title: 'abc') } + let_it_be(:cc_label) { create(:label, project: project, title: 'Community Contribution') } + let_it_be(:issue) { create(:issue, project: project) } let(:filtered_search) { find('.filtered-search') } let(:filter_author_dropdown) { find("#js-dropdown-author .filter-dropdown") } @@ -27,7 +28,6 @@ RSpec.describe 'Visual tokens', :js do project.add_user(user, :maintainer) project.add_user(user_rock, :maintainer) sign_in(user) - create(:issue, project: project) set_cookie('sidebar_collapsed', 'true') diff --git a/spec/features/issues/incident_issue_spec.rb b/spec/features/issues/incident_issue_spec.rb index d004ee85dd8..3033a138551 100644 --- a/spec/features/issues/incident_issue_spec.rb +++ b/spec/features/issues/incident_issue_spec.rb @@ -3,20 +3,57 @@ require 'spec_helper' RSpec.describe 'Incident Detail', :js do + let_it_be(:project) { create(:project, :public) } + let_it_be(:payload) do + { + 'title' => 'Alert title', + 'start_time' => '2020-04-27T10:10:22.265949279Z', + 'custom' => { + 'alert' => { + 'fields' => %w[one two] + } + }, + 'yet' => { + 'another' => 73 + } + } + end + + let_it_be(:user) { create(:user) } + let_it_be(:started_at) { Time.now.rfc3339 } + let_it_be(:alert) { create(:alert_management_alert, project: project, payload: payload, started_at: started_at) } + let_it_be(:incident) { create(:incident, project: project, description: 'hello', alert_management_alert: alert) } + context 'when user displays the incident' do - it 'shows the incident tabs' do - project = create(:project, :public) - incident = create(:incident, project: project, description: 'hello') + before do + project.add_developer(user) + sign_in(user) visit project_issue_path(project, incident) wait_for_requests + end + it 'shows incident and alert data' do page.within('.issuable-details') do incident_tabs = find('[data-testid="incident-tabs"]') - expect(find('h2')).to have_content(incident.title) - expect(incident_tabs).to have_content('Summary') - expect(incident_tabs).to have_content(incident.description) + aggregate_failures 'shows title and Summary tab' do + expect(find('h2')).to have_content(incident.title) + expect(incident_tabs).to have_content('Summary') + expect(incident_tabs).to have_content(incident.description) + end + + aggregate_failures 'shows the incident highlight bar' do + expect(incident_tabs).to have_content('Alert events: 1') + expect(incident_tabs).to have_content('Original alert: #1') + end + + aggregate_failures 'shows the Alert details tab' do + click_link 'Alert details' + + expect(incident_tabs).to have_content('"title": "Alert title"') + expect(incident_tabs).to have_content('"yet.another": 73') + end end end end diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb index d828b1c1f0c..0e2ef5cc6eb 100644 --- a/spec/features/issues/issue_sidebar_spec.rb +++ b/spec/features/issues/issue_sidebar_spec.rb @@ -259,37 +259,35 @@ RSpec.describe 'Issue Sidebar' do end context 'editing issue milestone', :js do - let_it_be(:milestone_expired) { create(:milestone, project: project, due_date: 5.days.ago) } + let_it_be(:milestone_expired) { create(:milestone, project: project, title: 'Foo - expired', due_date: 5.days.ago) } let_it_be(:milestone_no_duedate) { create(:milestone, project: project, title: 'Foo - No due date') } let_it_be(:milestone1) { create(:milestone, project: project, title: 'Milestone-1', due_date: 20.days.from_now) } let_it_be(:milestone2) { create(:milestone, project: project, title: 'Milestone-2', due_date: 15.days.from_now) } let_it_be(:milestone3) { create(:milestone, project: project, title: 'Milestone-3', due_date: 10.days.from_now) } before do - page.within('[data-testid="milestone_title"]') do - click_on 'Edit' + page.within('.block.milestone') do + click_button 'Edit' end + + wait_for_all_requests end - it 'shows milestons list in the dropdown' do - page.within('.block.milestone .dropdown-content') do + it 'shows milestones list in the dropdown' do + page.within('.block.milestone') do # 5 milestones + "No milestone" = 6 items - expect(page.find('ul')).to have_selector('li[data-milestone-id]', count: 6) + expect(page.find('.gl-new-dropdown-contents')).to have_selector('li.gl-new-dropdown-item', count: 6) end end - it 'shows expired milestone at the bottom of the list' do - page.within('.block.milestone .dropdown-content ul') do + it 'shows expired milestone at the bottom of the list and milestone due earliest at the top of the list', :aggregate_failures do + page.within('.block.milestone .gl-new-dropdown-contents') do expect(page.find('li:last-child')).to have_content milestone_expired.title - end - end - it 'shows milestone due earliest at the top of the list' do - page.within('.block.milestone .dropdown-content ul') do - expect(page.all('li[data-milestone-id]')[1]).to have_content milestone3.title - expect(page.all('li[data-milestone-id]')[2]).to have_content milestone2.title - expect(page.all('li[data-milestone-id]')[3]).to have_content milestone1.title - expect(page.all('li[data-milestone-id]')[4]).to have_content milestone_no_duedate.title + expect(page.all('li.gl-new-dropdown-item')[1]).to have_content milestone3.title + expect(page.all('li.gl-new-dropdown-item')[2]).to have_content milestone2.title + expect(page.all('li.gl-new-dropdown-item')[3]).to have_content milestone1.title + expect(page.all('li.gl-new-dropdown-item')[4]).to have_content milestone_no_duedate.title end end end diff --git a/spec/features/issues/user_bulk_edits_issues_spec.rb b/spec/features/issues/user_bulk_edits_issues_spec.rb index e34c16e27ba..44c23813e3c 100644 --- a/spec/features/issues/user_bulk_edits_issues_spec.rb +++ b/spec/features/issues/user_bulk_edits_issues_spec.rb @@ -13,26 +13,26 @@ RSpec.describe 'Multiple issue updating from issues#index', :js do end context 'status' do - it 'sets to closed' do + it 'sets to closed', :js do visit project_issues_path(project) click_button 'Edit issues' check 'Select all' click_button 'Select status' - click_link 'Closed' + click_button 'Closed' click_update_issues_button expect(page).to have_selector('.issue', count: 0) end - it 'sets to open' do + it 'sets to open', :js do create_closed visit project_issues_path(project, state: 'closed') click_button 'Edit issues' check 'Select all' click_button 'Select status' - click_link 'Open' + click_button 'Open' click_update_issues_button expect(page).to have_selector('.issue', count: 0) diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb index c59cc99467c..e4bba706453 100644 --- a/spec/features/issues/user_edits_issue_spec.rb +++ b/spec/features/issues/user_edits_issue_spec.rb @@ -333,37 +333,40 @@ RSpec.describe "Issues > User edits issue", :js do describe 'update milestone' do context 'by authorized user' do - it 'allows user to select unassigned' do + it 'allows user to select no milestone' do visit project_issue_path(project, issue) + wait_for_requests - page.within('.milestone') do - expect(page).to have_content "None" - end + page.within('.block.milestone') do + expect(page).to have_content 'None' + + click_button 'Edit' + wait_for_requests + click_button 'No milestone' + wait_for_requests - find('.block.milestone .edit-link').click - sleep 2 # wait for ajax stuff to complete - first('.dropdown-content li').click - sleep 2 - page.within('.milestone') do expect(page).to have_content 'None' end end it 'allows user to de-select milestone' do visit project_issue_path(project, issue) + wait_for_requests page.within('.milestone') do - click_link 'Edit' - click_link milestone.title + click_button 'Edit' + wait_for_requests + click_button milestone.title - page.within '.value' do + page.within '[data-testid="select-milestone"]' do expect(page).to have_content milestone.title end - click_link 'Edit' - click_link milestone.title + click_button 'Edit' + wait_for_requests + click_button 'No milestone' - page.within '.value' do + page.within '[data-testid="select-milestone"]' do expect(page).to have_content 'None' end end @@ -371,16 +374,17 @@ RSpec.describe "Issues > User edits issue", :js do it 'allows user to search milestone' do visit project_issue_path(project_with_milestones, issue_with_milestones) + wait_for_requests page.within('.milestone') do - click_link 'Edit' + click_button 'Edit' wait_for_requests # We need to enclose search string in quotes for exact match as all the milestone titles # within tests are prefixed with `My title`. - find('.dropdown-input-field', visible: true).send_keys "\"#{milestones[0].title}\"" + find('.gl-form-input', visible: true).send_keys "\"#{milestones[0].title}\"" wait_for_requests - page.within '.dropdown-content' do + page.within '.gl-new-dropdown-contents' do expect(page).to have_content milestones[0].title end end diff --git a/spec/features/issues/user_interacts_with_awards_spec.rb b/spec/features/issues/user_interacts_with_awards_spec.rb index 2921eea7641..2e52a8d862e 100644 --- a/spec/features/issues/user_interacts_with_awards_spec.rb +++ b/spec/features/issues/user_interacts_with_awards_spec.rb @@ -63,7 +63,7 @@ RSpec.describe 'User interacts with awards' do page.within('.awards') do expect(page).to have_selector('[data-testid="award-button"]') expect(page.find('[data-testid="award-button"].selected .js-counter')).to have_content('1') - expect(page).to have_css('[data-testid="award-button"].selected[title="You"]') + expect(page).to have_css('[data-testid="award-button"].selected[title="You reacted with :8ball:"]') expect do page.find('[data-testid="award-button"].selected').click diff --git a/spec/features/issues/user_sees_breadcrumb_links_spec.rb b/spec/features/issues/user_sees_breadcrumb_links_spec.rb index f5793758a9b..9f8cd2a769d 100644 --- a/spec/features/issues/user_sees_breadcrumb_links_spec.rb +++ b/spec/features/issues/user_sees_breadcrumb_links_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe 'New issue breadcrumb' do let_it_be(:project, reload: true) { create(:project) } + let(:user) { project.creator } before do diff --git a/spec/features/issues/user_sorts_issues_spec.rb b/spec/features/issues/user_sorts_issues_spec.rb index c161e1deb83..48297e9049e 100644 --- a/spec/features/issues/user_sorts_issues_spec.rb +++ b/spec/features/issues/user_sorts_issues_spec.rb @@ -22,11 +22,11 @@ RSpec.describe "User sorts issues" do create(:award_emoji, :upvote, awardable: issue2) sign_in(user) - - visit(project_issues_path(project)) end it 'keeps the sort option' do + visit(project_issues_path(project)) + find('.filter-dropdown-container .dropdown').click page.within('ul.dropdown-menu.dropdown-menu-right li') do @@ -47,11 +47,10 @@ RSpec.describe "User sorts issues" do end it 'sorts by popularity', :js do - find('.filter-dropdown-container .dropdown').click + visit(project_issues_path(project)) - page.within('ul.dropdown-menu.dropdown-menu-right li') do - click_link("Popularity") - end + click_button 'Created date' + click_on 'Popularity' page.within(".issues-list") do page.within("li.issue:nth-child(1)") do @@ -129,7 +128,7 @@ RSpec.describe "User sorts issues" do it 'filters by none' do visit project_issues_path(project, due_date: Issue::NoDueDate.name) - page.within '.issues-holder' do + page.within '.issues-list' do expect(page).not_to have_content('foo') expect(page).not_to have_content('bar') expect(page).to have_content('baz') @@ -139,7 +138,7 @@ RSpec.describe "User sorts issues" do it 'filters by any' do visit project_issues_path(project, due_date: Issue::AnyDueDate.name) - page.within '.issues-holder' do + page.within '.issues-list' do expect(page).to have_content('foo') expect(page).to have_content('bar') expect(page).to have_content('baz') @@ -153,7 +152,7 @@ RSpec.describe "User sorts issues" do visit project_issues_path(project, due_date: Issue::DueThisWeek.name) - page.within '.issues-holder' do + page.within '.issues-list' do expect(page).to have_content('foo') expect(page).to have_content('bar') expect(page).not_to have_content('baz') @@ -167,7 +166,7 @@ RSpec.describe "User sorts issues" do visit project_issues_path(project, due_date: Issue::DueThisMonth.name) - page.within '.issues-holder' do + page.within '.issues-list' do expect(page).to have_content('foo') expect(page).to have_content('bar') expect(page).not_to have_content('baz') @@ -181,7 +180,7 @@ RSpec.describe "User sorts issues" do visit project_issues_path(project, due_date: Issue::Overdue.name) - page.within '.issues-holder' do + page.within '.issues-list' do expect(page).not_to have_content('foo') expect(page).not_to have_content('bar') expect(page).to have_content('baz') @@ -195,7 +194,7 @@ RSpec.describe "User sorts issues" do visit project_issues_path(project, due_date: Issue::DueNextMonthAndPreviousTwoWeeks.name) - page.within '.issues-holder' do + page.within '.issues-list' do expect(page).not_to have_content('foo') expect(page).not_to have_content('bar') expect(page).to have_content('baz') diff --git a/spec/features/markdown/metrics_spec.rb b/spec/features/markdown/metrics_spec.rb index f9781f6c702..44354c9df47 100644 --- a/spec/features/markdown/metrics_spec.rb +++ b/spec/features/markdown/metrics_spec.rb @@ -176,10 +176,11 @@ RSpec.describe 'Metrics rendering', :js, :kubeclient, :use_clean_rails_memory_st create(:clusters_integrations_prometheus, cluster: cluster) stub_kubeclient_discover(cluster.platform.api_url) stub_prometheus_request(/prometheus-prometheus-server/, body: prometheus_values_body) - stub_prometheus_request(/prometheus\/api\/v1/, body: prometheus_values_body) + stub_prometheus_request(%r{prometheus/api/v1}, body: prometheus_values_body) end let_it_be(:cluster) { create(:cluster, :provided_by_gcp, :project, projects: [project], user: user) } + let(:params) { [project.namespace.path, project.path, cluster.id] } let(:query_params) { { group: 'Cluster Health', title: 'CPU Usage', y_label: 'CPU (cores)' } } let(:metrics_url) { urls.namespace_project_cluster_url(*params, **query_params) } diff --git a/spec/features/merge_request/batch_comments_spec.rb b/spec/features/merge_request/batch_comments_spec.rb index 5b11d9cb919..c646698219b 100644 --- a/spec/features/merge_request/batch_comments_spec.rb +++ b/spec/features/merge_request/batch_comments_spec.rb @@ -13,6 +13,8 @@ RSpec.describe 'Merge request > Batch comments', :js do end before do + stub_feature_flags(paginated_notes: false) + project.add_maintainer(user) sign_in(user) @@ -24,7 +26,7 @@ RSpec.describe 'Merge request > Batch comments', :js do end it 'has review bar' do - expect(page).to have_css('.review-bar-component', visible: false) + expect(page).to have_selector('[data-testid="review_bar_component"]', visible: false) end it 'adds draft note' do @@ -32,7 +34,7 @@ RSpec.describe 'Merge request > Batch comments', :js do expect(find('.draft-note-component')).to have_content('Line is wrong') - expect(page).to have_css('.review-bar-component') + expect(page).to have_selector('[data-testid="review_bar_component"]') expect(find('.review-bar-content .btn-confirm')).to have_content('1') end @@ -259,8 +261,8 @@ RSpec.describe 'Merge request > Batch comments', :js do end def write_parallel_comment(line, **params) - find("td[id='#{line}']").hover - find(".is-over button").click + find("div[id='#{line}']").hover + find(".js-add-diff-note-button").click write_comment(selector: "form[data-line-code='#{line}']", **params) end diff --git a/spec/features/merge_request/user_comments_on_diff_spec.rb b/spec/features/merge_request/user_comments_on_diff_spec.rb index 0fd140a00bd..54c3fe738d2 100644 --- a/spec/features/merge_request/user_comments_on_diff_spec.rb +++ b/spec/features/merge_request/user_comments_on_diff_spec.rb @@ -132,7 +132,7 @@ RSpec.describe 'User comments on a diff', :js do # In `files/ruby/popen.rb` it 'allows comments for changes involving both sides' do # click +15, select -13 add and verify comment - click_diff_line(find('div[data-path="files/ruby/popen.rb"] .new_line a[data-linenumber="15"]').find(:xpath, '../..'), 'right') + click_diff_line(find('div[data-path="files/ruby/popen.rb"] .right-side a[data-linenumber="15"]').find(:xpath, '../../..'), 'right') add_comment('-13', '+15') end @@ -141,7 +141,7 @@ RSpec.describe 'User comments on a diff', :js do page.within('[data-path="files/ruby/popen.rb"]') do all('.js-unfold-all')[0].click end - click_diff_line(find('div[data-path="files/ruby/popen.rb"] .old_line a[data-linenumber="9"]').find(:xpath, '../..'), 'left') + click_diff_line(find('div[data-path="files/ruby/popen.rb"] .left-side a[data-linenumber="9"]').find(:xpath, '../..'), 'left') add_comment('1', '-9') end @@ -150,7 +150,7 @@ RSpec.describe 'User comments on a diff', :js do page.within('[data-path="files/ruby/popen.rb"]') do all('.js-unfold-all')[1].click end - click_diff_line(find('div[data-path="files/ruby/popen.rb"] .old_line a[data-linenumber="21"]').find(:xpath, '../..'), 'left') + click_diff_line(find('div[data-path="files/ruby/popen.rb"] .left-side a[data-linenumber="21"]').find(:xpath, '../..'), 'left') add_comment('18', '21') end @@ -159,7 +159,7 @@ RSpec.describe 'User comments on a diff', :js do page.within('[data-path="files/ruby/popen.rb"]') do all('.js-unfold-down')[1].click end - click_diff_line(find('div[data-path="files/ruby/popen.rb"] .old_line a[data-linenumber="30"]').find(:xpath, '../..'), 'left') + click_diff_line(find('div[data-path="files/ruby/popen.rb"] .left-side a[data-linenumber="30"]').find(:xpath, '../..'), 'left') add_comment('+28', '37') end end diff --git a/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb b/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb index ac0c66524f0..3665ad91dd6 100644 --- a/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb +++ b/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb @@ -16,14 +16,14 @@ RSpec.describe 'Batch diffs', :js do wait_for_requests # Add discussion to first line of first file - click_diff_line(find('.diff-file.file-holder:first-of-type tr.line_holder.new:first-of-type')) + click_diff_line(find('.diff-file.file-holder:first-of-type .line_holder .left-side:first-of-type')) page.within('.js-discussion-note-form') do fill_in('note_note', with: 'First Line Comment') click_button('Add comment now') end # Add discussion to first line of last file - click_diff_line(find('.diff-file.file-holder:last-of-type tr.line_holder.new:first-of-type')) + click_diff_line(find('.diff-file.file-holder:last-of-type .line_holder .left-side:first-of-type')) page.within('.js-discussion-note-form') do fill_in('note_note', with: 'Last Line Comment') click_button('Add comment now') diff --git a/spec/features/merge_request/user_posts_diff_notes_spec.rb b/spec/features/merge_request/user_posts_diff_notes_spec.rb index 163ce10132e..c339a7d9976 100644 --- a/spec/features/merge_request/user_posts_diff_notes_spec.rb +++ b/spec/features/merge_request/user_posts_diff_notes_spec.rb @@ -10,7 +10,7 @@ RSpec.describe 'Merge request > User posts diff notes', :js do let(:user) { project.creator } let(:comment_button_class) { '.add-diff-note' } let(:notes_holder_input_class) { 'js-temp-notes-holder' } - let(:notes_holder_input_xpath) { './following-sibling::*[contains(concat(" ", @class, " "), " notes_holder ")]' } + let(:notes_holder_input_xpath) { '..//following-sibling::*[contains(concat(" ", @class, " "), " notes_holder ")]' } let(:test_note_comment) { 'this is a test note!' } before do @@ -27,7 +27,7 @@ RSpec.describe 'Merge request > User posts diff notes', :js do context 'with an old line on the left and no line on the right' do it 'allows commenting on the left side' do - should_allow_commenting(find('[id="6eb14e00385d2fb284765eb1cd8d420d33d63fc9_23_22"]').find(:xpath, '..'), 'left') + should_allow_commenting(find('[id="6eb14e00385d2fb284765eb1cd8d420d33d63fc9_23_22"]'), 'left') end it 'does not allow commenting on the right side' do @@ -67,7 +67,7 @@ RSpec.describe 'Merge request > User posts diff notes', :js do context 'with a match line' do it 'does not allow commenting' do - line_holder = find('.match', match: :first).find(:xpath, '..') + line_holder = find('.match', match: :first) match_should_not_allow_commenting(line_holder) end end @@ -81,17 +81,13 @@ RSpec.describe 'Merge request > User posts diff notes', :js do wait_for_requests end - # The first `.js-unfold` unfolds upwards, therefore the first - # `.line_holder` will be an unfolded line. - let(:line_holder) { first('#a5cc2925ca8258af241be7e5b0381edf30266302 .line_holder') } - it 'allows commenting on the left side' do - should_allow_commenting(line_holder, 'left') + should_allow_commenting(first('#a5cc2925ca8258af241be7e5b0381edf30266302 .line_holder [data-testid="left-side"]')) end it 'allows commenting on the right side' do # Automatically shifts comment box to left side. - should_allow_commenting(line_holder, 'right') + should_allow_commenting(first('#a5cc2925ca8258af241be7e5b0381edf30266302 .line_holder [data-testid="right-side"]')) end end end @@ -149,7 +145,7 @@ RSpec.describe 'Merge request > User posts diff notes', :js do # The first `.js-unfold` unfolds upwards, therefore the first # `.line_holder` will be an unfolded line. - let(:line_holder) { first('.line_holder[id="a5cc2925ca8258af241be7e5b0381edf30266302_1_1"]') } + let(:line_holder) { first('[id="a5cc2925ca8258af241be7e5b0381edf30266302_1_1"]') } it 'allows commenting' do should_allow_commenting line_holder diff --git a/spec/features/merge_request/user_resolves_conflicts_spec.rb b/spec/features/merge_request/user_resolves_conflicts_spec.rb index d9e3bfd6a9c..03ab42aaccd 100644 --- a/spec/features/merge_request/user_resolves_conflicts_spec.rb +++ b/spec/features/merge_request/user_resolves_conflicts_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Merge request > User resolves conflicts', :js do - include Spec::Support::Helpers::Features::EditorLiteSpecHelpers + include Spec::Support::Helpers::Features::SourceEditorSpecHelpers let(:project) { create(:project, :repository) } let(:user) { project.creator } 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 a85700fc721..2f7758143a1 100644 --- a/spec/features/merge_request/user_sees_merge_widget_spec.rb +++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb @@ -373,7 +373,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js do wait_for_requests page.within('.mr-widget-body') do - expect(page).to have_content('Fast-forward merge is not possible') + expect(page).to have_content('Merge Merge blocked: fast-forward merge is not possible. To merge this request, first rebase locally.') end end end diff --git a/spec/features/merge_request/user_sees_pipelines_spec.rb b/spec/features/merge_request/user_sees_pipelines_spec.rb index 2d8fe10b987..a6c8b10f5ca 100644 --- a/spec/features/merge_request/user_sees_pipelines_spec.rb +++ b/spec/features/merge_request/user_sees_pipelines_spec.rb @@ -137,7 +137,7 @@ RSpec.describe 'Merge request > User sees pipelines', :js do check_head_pipeline(expected_project: parent_project) end - it 'does not create a pipeline in the parent project when user cancels the action' do + it 'does not create a pipeline in the parent project when user cancels the action', :clean_gitlab_redis_cache, :clean_gitlab_redis_shared_state do visit project_merge_request_path(parent_project, merge_request) create_merge_request_pipeline diff --git a/spec/features/merge_request/user_sees_versions_spec.rb b/spec/features/merge_request/user_sees_versions_spec.rb index 34ae082750b..5abf4e2f5ad 100644 --- a/spec/features/merge_request/user_sees_versions_spec.rb +++ b/spec/features/merge_request/user_sees_versions_spec.rb @@ -17,8 +17,6 @@ RSpec.describe 'Merge request > User sees versions', :js do let!(:params) { {} } before do - stub_feature_flags(diffs_gradual_load: false) - project.add_maintainer(user) sign_in(user) visit diffs_project_merge_request_path(project, merge_request, params) @@ -30,8 +28,8 @@ RSpec.describe 'Merge request > User sees versions', :js do line_code = "#{file_id}_#{line_code}" page.within(diff_file_selector) do - find(".line_holder[id='#{line_code}'] td:nth-of-type(1)").hover - find(".line_holder[id='#{line_code}'] button").click + first("[id='#{line_code}']").hover + first("[id='#{line_code}'] [role='button']").click page.within("form[data-line-code='#{line_code}']") do fill_in "note[note]", with: comment diff --git a/spec/features/merge_request/user_toggles_whitespace_changes_spec.rb b/spec/features/merge_request/user_toggles_whitespace_changes_spec.rb index b72ac071ecb..19774accaaf 100644 --- a/spec/features/merge_request/user_toggles_whitespace_changes_spec.rb +++ b/spec/features/merge_request/user_toggles_whitespace_changes_spec.rb @@ -20,7 +20,7 @@ RSpec.describe 'Merge request > User toggles whitespace changes', :js do end describe 'clicking "Hide whitespace changes" button' do - it 'toggles the "Hide whitespace changes" button' do + it 'toggles the "Hide whitespace changes" button', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/333793' do find('[data-testid="show-whitespace"]').click visit diffs_project_merge_request_path(project, merge_request) diff --git a/spec/features/merge_request/user_views_diffs_spec.rb b/spec/features/merge_request/user_views_diffs_spec.rb index d5061657c59..09dfe41a718 100644 --- a/spec/features/merge_request/user_views_diffs_spec.rb +++ b/spec/features/merge_request/user_views_diffs_spec.rb @@ -24,7 +24,7 @@ RSpec.describe 'User views diffs', :js do page.within('.file-holder[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd"]') do expect(find('.text-file')).to have_content('fileutils') - expect(page).to have_selector('.new_line [data-linenumber="1"]', count: 1) + expect(page).to have_selector('[data-interop-type="new"] [data-linenumber="1"]') end end @@ -32,8 +32,8 @@ RSpec.describe 'User views diffs', :js do page.within('.file-holder[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd"]') do all('.js-unfold-all')[1].click - expect(page).to have_selector('.new_line [data-linenumber="24"]', count: 1) - expect(page).not_to have_selector('.new_line [data-linenumber="1"]') + expect(page).to have_selector('[data-interop-type="new"] [data-linenumber="24"]', count: 1) + expect(page).not_to have_selector('[data-interop-type="new"] [data-linenumber="1"]') end end diff --git a/spec/features/merge_requests/user_lists_merge_requests_spec.rb b/spec/features/merge_requests/user_lists_merge_requests_spec.rb index 6b8dcd7dbb6..ab6242784fe 100644 --- a/spec/features/merge_requests/user_lists_merge_requests_spec.rb +++ b/spec/features/merge_requests/user_lists_merge_requests_spec.rb @@ -23,7 +23,9 @@ RSpec.describe 'Merge requests > User lists merge requests' do milestone: create(:milestone, project: project, due_date: '2013-12-11'), created_at: 1.minute.ago, updated_at: 1.minute.ago) - create(:merge_request, + @fix.metrics.update_column(:merged_at, 10.seconds.ago) + + @markdown = create(:merge_request, title: 'markdown', source_project: project, source_branch: 'markdown', @@ -32,12 +34,15 @@ RSpec.describe 'Merge requests > User lists merge requests' do milestone: create(:milestone, project: project, due_date: '2013-12-12'), created_at: 2.minutes.ago, updated_at: 2.minutes.ago) - create(:merge_request, + @markdown.metrics.update_column(:merged_at, 50.seconds.ago) + + @merge_test = create(:merge_request, title: 'merge-test', source_project: project, source_branch: 'merge-test', created_at: 3.minutes.ago, updated_at: 10.seconds.ago) + @merge_test.metrics.update_column(:merged_at, 10.seconds.ago) end context 'merge request reviewers' do @@ -102,6 +107,13 @@ RSpec.describe 'Merge requests > User lists merge requests' do expect(count_merge_requests).to eq(3) end + it 'sorts by merged at' do + visit_merge_requests(project, sort: sort_value_merged_date) + + expect(first_merge_request).to include('markdown') + expect(count_merge_requests).to eq(3) + end + it 'filters on one label and sorts by due date' do label = create(:label, project: project) create(:label_link, label: label, target: @fix) diff --git a/spec/features/merge_requests/user_mass_updates_spec.rb b/spec/features/merge_requests/user_mass_updates_spec.rb index 0fe69c5ca5b..46c12784ea8 100644 --- a/spec/features/merge_requests/user_mass_updates_spec.rb +++ b/spec/features/merge_requests/user_mass_updates_spec.rb @@ -18,7 +18,7 @@ RSpec.describe 'Merge requests > User mass updates', :js do visit project_merge_requests_path(project) end - it 'closes merge request' do + it 'closes merge request', :js do change_status('Closed') expect(page).to have_selector('.merge-request', count: 0) @@ -31,7 +31,7 @@ RSpec.describe 'Merge requests > User mass updates', :js do visit project_merge_requests_path(project, state: 'closed') end - it 'reopens merge request' do + it 'reopens merge request', :js do change_status('Open') expect(page).to have_selector('.merge-request', count: 0) @@ -109,7 +109,7 @@ RSpec.describe 'Merge requests > User mass updates', :js do click_button 'Edit merge requests' check 'Select all' click_button 'Select status' - click_link text + click_button text 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 54c9fbef218..99473f3b1ea 100644 --- a/spec/features/merge_requests/user_sorts_merge_requests_spec.rb +++ b/spec/features/merge_requests/user_sorts_merge_requests_spec.rb @@ -60,7 +60,7 @@ RSpec.describe 'User sorts merge requests' do visit(project_issues_path(project)) - expect(find('.issues-filters a.is-active')).not_to have_content('Milestone') + expect(page).not_to have_button('Milestone') end context 'when merge requests have awards' do diff --git a/spec/features/oauth_login_spec.rb b/spec/features/oauth_login_spec.rb index dc27bfbef50..3402bda5a41 100644 --- a/spec/features/oauth_login_spec.rb +++ b/spec/features/oauth_login_spec.rb @@ -18,7 +18,7 @@ RSpec.describe 'OAuth Login', :js, :allow_forgery_protection do providers = [:github, :twitter, :bitbucket, :gitlab, :google_oauth2, :facebook, :cas3, :auth0, :authentiq, :salesforce] - around(:all) do |example| + around do |example| with_omniauth_full_host { example.run } end diff --git a/spec/features/participants_autocomplete_spec.rb b/spec/features/participants_autocomplete_spec.rb index 2781cfffbaf..cc805e7d369 100644 --- a/spec/features/participants_autocomplete_spec.rb +++ b/spec/features/participants_autocomplete_spec.rb @@ -6,6 +6,7 @@ RSpec.describe 'Member autocomplete', :js do let_it_be(:project) { create(:project, :public, :repository) } let_it_be(:user) { create(:user) } let_it_be(:author) { create(:user) } + let(:note) { create(:note, noteable: noteable, project: noteable.project) } before do diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb index 379c25d6002..de511e99182 100644 --- a/spec/features/profiles/personal_access_tokens_spec.rb +++ b/spec/features/profiles/personal_access_tokens_spec.rb @@ -42,10 +42,10 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do name = 'My PAT' visit profile_personal_access_tokens_path - fill_in "Name", with: name + fill_in "Token name", with: name # Set date to 1st of next month - find_field("Expires at").click + find_field("Expiration date").click find(".pika-next").click click_on "1" @@ -66,7 +66,7 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do it "displays an error message" do disallow_personal_access_token_saves! visit profile_personal_access_tokens_path - fill_in "Name", with: 'My PAT' + fill_in "Token name", with: 'My PAT' expect { click_on "Create personal access token" }.not_to change { PersonalAccessToken.count } expect(page).to have_content("Name cannot be nil") @@ -149,4 +149,15 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do expect(page).to have_pushed_frontend_feature_flags(personalAccessTokensScopedToProjects: true) end + + it "prefills token details" do + name = 'My PAT' + scopes = 'api,read_user' + + visit profile_personal_access_tokens_path({ name: name, scopes: scopes }) + + expect(page).to have_field("Token name", with: name) + expect(find("#personal_access_token_scopes_api")).to be_checked + expect(find("#personal_access_token_scopes_read_user")).to be_checked + end end diff --git a/spec/features/projects/active_tabs_spec.rb b/spec/features/projects/active_tabs_spec.rb index 39950adc83f..b8c928004ed 100644 --- a/spec/features/projects/active_tabs_spec.rb +++ b/spec/features/projects/active_tabs_spec.rb @@ -24,17 +24,6 @@ RSpec.describe 'Project active tab' do expect(page).to have_selector('.sidebar-top-level-items > li.active', count: 1) expect(find('.sidebar-top-level-items > li.active')).to have_content(project.name) end - - context 'when feature flag :sidebar_refactor is disabled' do - before do - stub_feature_flags(sidebar_refactor: false) - - visit project_path(project) - end - - it_behaves_like 'page has active tab', 'Project' - it_behaves_like 'page has active sub tab', 'Details' - end end context 'on Project information' do @@ -80,11 +69,7 @@ RSpec.describe 'Project active tab' do end context 'on project Issues' do - let(:feature_flag_value) { true } - before do - stub_feature_flags(sidebar_refactor: feature_flag_value) - visit project_issues_path(project) end @@ -98,21 +83,6 @@ RSpec.describe 'Project active tab' do it_behaves_like 'page has active tab', 'Issues' it_behaves_like 'page has active sub tab', 'Milestones' end - - context 'when feature flag is disabled' do - let(:feature_flag_value) { false } - - %w(Milestones Labels).each do |sub_menu| - context "on project Issues/#{sub_menu}" do - before do - click_tab(sub_menu) - end - - it_behaves_like 'page has active tab', 'Issues' - it_behaves_like 'page has active sub tab', sub_menu - end - end - end end context 'on project Merge Requests' do @@ -168,9 +138,9 @@ RSpec.describe 'Project active tab' do visit project_cycle_analytics_path(project) end - context 'on project Analytics/Value Stream Analytics' do + context 'on project Analytics/Value stream Analytics' do it_behaves_like 'page has active tab', _('Analytics') - it_behaves_like 'page has active sub tab', _('Value Stream') + it_behaves_like 'page has active sub tab', _('Value stream') end context 'on project Analytics/"CI/CD"' do diff --git a/spec/features/projects/activity/user_sees_design_activity_spec.rb b/spec/features/projects/activity/user_sees_design_activity_spec.rb index 27a52b87178..389e86299e5 100644 --- a/spec/features/projects/activity/user_sees_design_activity_spec.rb +++ b/spec/features/projects/activity/user_sees_design_activity_spec.rb @@ -8,7 +8,6 @@ RSpec.describe 'Projects > Activity > User sees design Activity', :js do let_it_be(:uploader) { create(:user) } let_it_be(:editor) { create(:user) } let_it_be(:deleter) { create(:user) } - let_it_be(:archiver) { create(:user) } def design_activity(user, action) [user.name, user.to_reference, action, 'design'].join(' ') @@ -24,7 +23,6 @@ RSpec.describe 'Projects > Activity > User sees design Activity', :js do create(:design_event, :created, author: uploader, **common_attrs) create(:design_event, :updated, author: editor, **common_attrs) create(:design_event, :destroyed, author: deleter, **common_attrs) - create(:design_event, :archived, author: archiver, **common_attrs) end before do @@ -39,7 +37,6 @@ RSpec.describe 'Projects > Activity > User sees design Activity', :js do expect(page).to have_content(design_activity(uploader, 'uploaded')) expect(page).to have_content(design_activity(editor, 'revised')) expect(page).to have_content(design_activity(deleter, 'deleted')) - expect(page).to have_content(design_activity(archiver, 'archived')) end it 'allows filtering out the design events', :aggregate_failures do @@ -48,7 +45,6 @@ RSpec.describe 'Projects > Activity > User sees design Activity', :js do expect(page).not_to have_content(design_activity(uploader, 'uploaded')) expect(page).not_to have_content(design_activity(editor, 'revised')) expect(page).not_to have_content(design_activity(deleter, 'deleted')) - expect(page).not_to have_content(design_activity(archiver, 'archived')) end it 'allows filtering in the design events', :aggregate_failures do @@ -58,7 +54,6 @@ RSpec.describe 'Projects > Activity > User sees design Activity', :js do expect(page).to have_content(design_activity(uploader, 'uploaded')) expect(page).to have_content(design_activity(editor, 'revised')) expect(page).to have_content(design_activity(deleter, 'deleted')) - expect(page).to have_content(design_activity(archiver, 'archived')) end end diff --git a/spec/features/projects/ci/editor_spec.rb b/spec/features/projects/ci/editor_spec.rb index 7012cc6edaa..c0cc12eac66 100644 --- a/spec/features/projects/ci/editor_spec.rb +++ b/spec/features/projects/ci/editor_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Pipeline Editor', :js do - include Spec::Support::Helpers::Features::EditorLiteSpecHelpers + include Spec::Support::Helpers::Features::SourceEditorSpecHelpers let(:project) { create(:project, :repository) } let(:user) { create(:user) } diff --git a/spec/features/projects/ci/lint_spec.rb b/spec/features/projects/ci/lint_spec.rb index 353c8558185..0d9ea6331a7 100644 --- a/spec/features/projects/ci/lint_spec.rb +++ b/spec/features/projects/ci/lint_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'CI Lint', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297782' do - include Spec::Support::Helpers::Features::EditorLiteSpecHelpers + include Spec::Support::Helpers::Features::SourceEditorSpecHelpers let(:project) { create(:project, :repository) } let(:user) { create(:user) } diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb index 8c497cded8e..21e587288f5 100644 --- a/spec/features/projects/clusters/gcp_spec.rb +++ b/spec/features/projects/clusters/gcp_spec.rb @@ -214,7 +214,7 @@ RSpec.describe 'Gcp Cluster', :js do it 'user does not see the offer' do page.within('.as-third-party-offers') do click_button 'Expand' - check 'Do not display offers from third parties within GitLab' + check 'Do not display offers from third parties' click_button 'Save changes' end diff --git a/spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb b/spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb index eaafc7e607b..4af5c91479a 100644 --- a/spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb +++ b/spec/features/projects/feature_flags/user_creates_feature_flag_spec.rb @@ -10,7 +10,6 @@ RSpec.describe 'User creates feature flag', :js do before do project.add_developer(user) - stub_feature_flags(feature_flag_permissions: false) sign_in(user) end diff --git a/spec/features/projects/feature_flags/user_deletes_feature_flag_spec.rb b/spec/features/projects/feature_flags/user_deletes_feature_flag_spec.rb index 581709aacee..43540dc4522 100644 --- a/spec/features/projects/feature_flags/user_deletes_feature_flag_spec.rb +++ b/spec/features/projects/feature_flags/user_deletes_feature_flag_spec.rb @@ -15,7 +15,6 @@ RSpec.describe 'User deletes feature flag', :js do before do project.add_developer(user) - stub_feature_flags(feature_flag_permissions: false) sign_in(user) visit(project_feature_flags_path(project)) diff --git a/spec/features/projects/feature_flags/user_sees_feature_flag_list_spec.rb b/spec/features/projects/feature_flags/user_sees_feature_flag_list_spec.rb index d922bc1f4a0..30bfcb645f4 100644 --- a/spec/features/projects/feature_flags/user_sees_feature_flag_list_spec.rb +++ b/spec/features/projects/feature_flags/user_sees_feature_flag_list_spec.rb @@ -16,33 +16,63 @@ RSpec.describe 'User sees feature flag list', :js do sign_in(user) end - context 'with legacy feature flags' do + context 'with feature flags' do before do - create_flag(project, 'ci_live_trace', false, version: :legacy_flag).tap do |feature_flag| - create_scope(feature_flag, 'review/*', true) + create_flag(project, 'ci_live_trace', false).tap do |feature_flag| + create_strategy(feature_flag).tap do |strat| + create(:operations_scope, strategy: strat, environment_scope: '*') + create(:operations_scope, strategy: strat, environment_scope: 'review/*') + end end - create_flag(project, 'drop_legacy_artifacts', false, version: :legacy_flag) - create_flag(project, 'mr_train', true, version: :legacy_flag).tap do |feature_flag| - create_scope(feature_flag, 'production', false) + create_flag(project, 'drop_legacy_artifacts', false) + create_flag(project, 'mr_train', true).tap do |feature_flag| + create_strategy(feature_flag).tap do |strat| + create(:operations_scope, strategy: strat, environment_scope: 'production') + end end + create(:operations_feature_flag, :new_version_flag, project: project, + name: 'my_flag', active: false) end - it 'shows empty page' do + it 'shows the user the first flag' do visit(project_feature_flags_path(project)) - expect(page).to have_text 'Get started with feature flags' - expect(page).to have_selector('.btn-confirm', text: 'New feature flag') - expect(page).to have_selector('[data-qa-selector="configure_feature_flags_button"]', text: 'Configure') + within_feature_flag_row(1) do + expect(page.find('.js-feature-flag-id')).to have_content('^1') + expect(page.find('.feature-flag-name')).to have_content('ci_live_trace') + expect_status_toggle_button_not_to_be_checked + + within_feature_flag_scopes do + expect(page.find('[data-testid="strategy-badge"]')).to have_content('All Users: All Environments, review/*') + end + end end - end - context 'with new version flags' do - before do - create(:operations_feature_flag, :new_version_flag, project: project, - name: 'my_flag', active: false) + it 'shows the user the second flag' do + visit(project_feature_flags_path(project)) + + within_feature_flag_row(2) do + expect(page.find('.js-feature-flag-id')).to have_content('^2') + expect(page.find('.feature-flag-name')).to have_content('drop_legacy_artifacts') + expect_status_toggle_button_not_to_be_checked + end + end + + it 'shows the user the third flag' do + visit(project_feature_flags_path(project)) + + within_feature_flag_row(3) do + expect(page.find('.js-feature-flag-id')).to have_content('^3') + expect(page.find('.feature-flag-name')).to have_content('mr_train') + expect_status_toggle_button_to_be_checked + + within_feature_flag_scopes do + expect(page.find('[data-testid="strategy-badge"]')).to have_content('All Users: production') + end + end end - it 'user updates the status toggle' do + it 'allows the user to update the status toggle' do visit(project_feature_flags_path(project)) within_feature_flag_row(1) do @@ -58,7 +88,7 @@ RSpec.describe 'User sees feature flag list', :js do visit(project_feature_flags_path(project)) end - it 'shows empty page' do + it 'shows the empty page' do expect(page).to have_text 'Get started with feature flags' expect(page).to have_selector('.btn-confirm', text: 'New feature flag') expect(page).to have_selector('[data-qa-selector="configure_feature_flags_button"]', text: 'Configure') diff --git a/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb b/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb index 9c03a26abc8..f6330491886 100644 --- a/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb +++ b/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb @@ -13,9 +13,6 @@ RSpec.describe 'User updates feature flag', :js do end before do - stub_feature_flags( - feature_flag_permissions: false - ) sign_in(user) end diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb index 2e5a5cef0fd..a7e773dda2d 100644 --- a/spec/features/projects/features_visibility_spec.rb +++ b/spec/features/projects/features_visibility_spec.rb @@ -68,17 +68,6 @@ RSpec.describe 'Edit Project Settings' do expect(page).not_to have_selector('.shortcuts-issues') expect(page).not_to have_selector('.shortcuts-labels') end - - context 'when feature flag :sidebar_refactor is disabled' do - it 'hides issues tab and show labels tab' do - stub_feature_flags(sidebar_refactor: false) - - visit project_path(project) - - expect(page).not_to have_selector('.shortcuts-issues') - expect(page).to have_selector('.shortcuts-labels') - end - end end context "pipelines subtabs" do diff --git a/spec/features/projects/files/dockerfile_dropdown_spec.rb b/spec/features/projects/files/dockerfile_dropdown_spec.rb index 40d19a94b42..11663158b33 100644 --- a/spec/features/projects/files/dockerfile_dropdown_spec.rb +++ b/spec/features/projects/files/dockerfile_dropdown_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Projects > Files > User wants to add a Dockerfile file', :js do - include Spec::Support::Helpers::Features::EditorLiteSpecHelpers + include Spec::Support::Helpers::Features::SourceEditorSpecHelpers before do project = create(:project, :repository) diff --git a/spec/features/projects/files/gitignore_dropdown_spec.rb b/spec/features/projects/files/gitignore_dropdown_spec.rb index a9f2463ecf6..d47eaee2e79 100644 --- a/spec/features/projects/files/gitignore_dropdown_spec.rb +++ b/spec/features/projects/files/gitignore_dropdown_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Projects > Files > User wants to add a .gitignore file', :js do - include Spec::Support::Helpers::Features::EditorLiteSpecHelpers + include Spec::Support::Helpers::Features::SourceEditorSpecHelpers before do project = create(:project, :repository) diff --git a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb index b0ccb5fca94..fc199f66490 100644 --- a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb +++ b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'Projects > Files > User wants to add a .gitlab-ci.yml file', :js do - include Spec::Support::Helpers::Features::EditorLiteSpecHelpers + include Spec::Support::Helpers::Features::SourceEditorSpecHelpers let(:params) { {} } let(:filename) { '.gitlab-ci.yml' } diff --git a/spec/features/projects/files/undo_template_spec.rb b/spec/features/projects/files/undo_template_spec.rb index 09ae595490a..560cb53ead2 100644 --- a/spec/features/projects/files/undo_template_spec.rb +++ b/spec/features/projects/files/undo_template_spec.rb @@ -47,11 +47,11 @@ end def check_undo_button_display expect(page).to have_content('template applied') - expect(page).to have_css('.toasted-container') + expect(page).to have_css('.b-toaster') end def check_content_reverted(template_content) - find('.toasted-container a', text: 'Undo').click + find('.b-toaster a', text: 'Undo').click expect(page).not_to have_content(template_content) expect(page).to have_css('.template-type-selector .dropdown-toggle-text') end diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index 25836514981..a4c57e83bdd 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -62,6 +62,6 @@ RSpec.describe 'Import/Export - project import integration test', :js do end def click_import_project - find('[data-qa-selector="import_project_link"]').click + find('[data-qa-panel-name="import_project"]').click end end diff --git a/spec/features/projects/infrastructure_registry_spec.rb b/spec/features/projects/infrastructure_registry_spec.rb index 9cab4ebeb3a..c3cb3955092 100644 --- a/spec/features/projects/infrastructure_registry_spec.rb +++ b/spec/features/projects/infrastructure_registry_spec.rb @@ -28,13 +28,30 @@ RSpec.describe 'Infrastructure Registry' do visit_project_infrastructure_registry end - context 'when there are packages' do + context 'when there are modules' do let_it_be(:terraform_module) { create(:terraform_module_package, project: project, created_at: 1.day.ago, version: '1.0.0') } let_it_be(:terraform_module2) { create(:terraform_module_package, project: project, created_at: 2.days.ago, version: '2.0.0') } let_it_be(:packages) { [terraform_module, terraform_module2] } it_behaves_like 'packages list' + context 'details link' do + it 'navigates to the correct url' do + page.within(packages_table_selector) do + click_link terraform_module.name + end + + expect(page).to have_current_path(project_infrastructure_registry_path(terraform_module.project, terraform_module)) + + expect(page).to have_css('.packages-app h1[data-testid="title"]', text: terraform_module.name) + + page.within(%Q([name="#{terraform_module.name}"])) do + expect(page).to have_content('Provision instructions') + expect(page).to have_content('Registry setup') + end + end + end + context 'deleting a package' do let_it_be(:project) { create(:project) } let_it_be(:terraform_module) { create(:terraform_module_package, project: project) } diff --git a/spec/features/projects/integrations/user_activates_jira_spec.rb b/spec/features/projects/integrations/user_activates_jira_spec.rb index 10f84aae93f..d7679d38cae 100644 --- a/spec/features/projects/integrations/user_activates_jira_spec.rb +++ b/spec/features/projects/integrations/user_activates_jira_spec.rb @@ -65,7 +65,7 @@ RSpec.describe 'User activates Jira', :js do include JiraServiceHelper before do - stub_jira_service_test + stub_jira_integration_test visit_project_integration('Jira') fill_form(disable: true) click_save_integration @@ -105,14 +105,14 @@ RSpec.describe 'User activates Jira', :js do click_save_integration expect(page).to have_content('Jira settings saved and active.') - expect(project.reload.jira_service.data_fields).to have_attributes( + expect(project.reload.jira_integration.data_fields).to have_attributes( jira_issue_transition_automatic: false, jira_issue_transition_id: '1, 2, 3' ) end it 'using automatic transitions' do - create(:jira_service, project: project, jira_issue_transition_automatic: false, jira_issue_transition_id: '1, 2, 3') + create(:jira_integration, project: project, jira_issue_transition_automatic: false, jira_issue_transition_id: '1, 2, 3') visit_project_integration('Jira') expect(page).to have_field('Enable Jira transitions', checked: true) @@ -123,14 +123,14 @@ RSpec.describe 'User activates Jira', :js do click_save_integration expect(page).to have_content('Jira settings saved and active.') - expect(project.reload.jira_service.data_fields).to have_attributes( + expect(project.reload.jira_integration.data_fields).to have_attributes( jira_issue_transition_automatic: true, jira_issue_transition_id: '' ) end it 'disabling issue transitions' do - create(:jira_service, project: project, jira_issue_transition_automatic: true, jira_issue_transition_id: '1, 2, 3') + create(:jira_integration, project: project, jira_issue_transition_automatic: true, jira_issue_transition_id: '1, 2, 3') visit_project_integration('Jira') expect(page).to have_field('Enable Jira transitions', checked: true) @@ -140,7 +140,7 @@ RSpec.describe 'User activates Jira', :js do click_save_integration expect(page).to have_content('Jira settings saved and active.') - expect(project.reload.jira_service.data_fields).to have_attributes( + expect(project.reload.jira_integration.data_fields).to have_attributes( jira_issue_transition_automatic: false, jira_issue_transition_id: '' ) diff --git a/spec/features/projects/integrations/user_activates_pivotaltracker_spec.rb b/spec/features/projects/integrations/user_activates_pivotaltracker_spec.rb index 83f66d4fa7b..ea34a766719 100644 --- a/spec/features/projects/integrations/user_activates_pivotaltracker_spec.rb +++ b/spec/features/projects/integrations/user_activates_pivotaltracker_spec.rb @@ -10,11 +10,11 @@ RSpec.describe 'User activates PivotalTracker' do end it 'activates service', :js do - visit_project_integration('PivotalTracker') + visit_project_integration('Pivotal Tracker') fill_in('Token', with: 'verySecret') click_test_then_save_integration(expect_test_to_fail: false) - expect(page).to have_content('PivotalTracker settings saved and active.') + expect(page).to have_content('Pivotal Tracker settings saved and active.') end end diff --git a/spec/features/projects/navbar_spec.rb b/spec/features/projects/navbar_spec.rb index bce11e6bc8a..876bc82d16c 100644 --- a/spec/features/projects/navbar_spec.rb +++ b/spec/features/projects/navbar_spec.rb @@ -14,134 +14,54 @@ RSpec.describe 'Project navbar' do before do sign_in(user) - end - context 'when sidebar refactor feature flag is disabled' do - let(:project_context_nav_item) do - nil - end + stub_config(registry: { enabled: false }) + insert_package_nav(_('Infrastructure')) + insert_infrastructure_registry_nav + end + it_behaves_like 'verified navigation bar' do before do - stub_feature_flags(sidebar_refactor: false) - insert_package_nav(_('Operations')) - insert_infrastructure_registry_nav - - insert_after_sub_nav_item( - _('Boards'), - within: _('Issues'), - new_sub_nav_item_name: _('Labels') - ) - - insert_after_nav_item( - _('Snippets'), - new_nav_item: { - nav_item: _('Members'), - nav_sub_items: [] - } - ) - - stub_config(registry: { enabled: false }) + visit project_path(project) end + end - it_behaves_like 'verified navigation bar' do - before do - visit project_path(project) - end + context 'when value stream is available' do + before do + visit project_path(project) end - context 'when value stream is available' do - before do - visit project_path(project) + it 'redirects to value stream when Analytics item is clicked' do + page.within('.sidebar-top-level-items') do + find('.shortcuts-analytics').click end - it 'redirects to value stream when Analytics item is clicked' do - page.within('.sidebar-top-level-items') do - find('.shortcuts-analytics').click - end - - wait_for_requests + wait_for_requests - expect(page).to have_current_path(project_cycle_analytics_path(project)) - end - end - - context 'when pages are available' do - before do - stub_config(pages: { enabled: true }) - - insert_after_sub_nav_item( - _('Operations'), - within: _('Settings'), - new_sub_nav_item_name: _('Pages') - ) - - visit project_path(project) - end - - it_behaves_like 'verified navigation bar' - end - - context 'when container registry is available' do - before do - stub_config(registry: { enabled: true }) - - insert_container_nav - - visit project_path(project) - end - - it_behaves_like 'verified navigation bar' + expect(page).to have_current_path(project_cycle_analytics_path(project)) end end - context 'when sidebar refactor feature flag is enabled' do - let(:monitor_nav_item) do - { - nav_item: _('Monitor'), - nav_sub_items: monitor_menu_items - } - end + context 'when pages are available' do + before do + stub_config(pages: { enabled: true }) - let(:monitor_menu_items) do - [ - _('Metrics'), - _('Logs'), - _('Tracing'), - _('Error Tracking'), - _('Alerts'), - _('Incidents'), - _('Product Analytics') - ] - end + insert_after_sub_nav_item( + _('Monitor'), + within: _('Settings'), + new_sub_nav_item_name: _('Pages') + ) - let(:project_information_nav_item) do - { - nav_item: _('Project information'), - nav_sub_items: [ - _('Activity'), - _('Labels'), - _('Members') - ] - } + visit project_path(project) end - let(:settings_menu_items) do - [ - _('General'), - _('Integrations'), - _('Webhooks'), - _('Access Tokens'), - _('Repository'), - _('CI/CD'), - _('Monitor') - ] - end + it_behaves_like 'verified navigation bar' + end + context 'when container registry is available' do before do - stub_feature_flags(sidebar_refactor: true) stub_config(registry: { enabled: true }) - insert_package_nav(_('Monitor')) - insert_infrastructure_registry_nav + insert_container_nav insert_after_sub_nav_item( @@ -150,30 +70,6 @@ RSpec.describe 'Project navbar' do new_sub_nav_item_name: _('Packages & Registries') ) - insert_after_nav_item( - _('Monitor'), - new_nav_item: { - nav_item: _('Infrastructure'), - nav_sub_items: [ - _('Kubernetes clusters'), - _('Serverless platform'), - _('Terraform') - ] - } - ) - - insert_after_nav_item( - _('Security & Compliance'), - new_nav_item: { - nav_item: _('Deployments'), - nav_sub_items: [ - _('Feature Flags'), - _('Environments'), - _('Releases') - ] - } - ) - visit project_path(project) end diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb index c57432ae94e..ef28979798f 100644 --- a/spec/features/projects/new_project_spec.rb +++ b/spec/features/projects/new_project_spec.rb @@ -14,82 +14,13 @@ RSpec.describe 'New project', :js do sign_in(user) end - context 'new repo experiment', :experiment do - it 'when in control renders "project"' do - stub_experiments(new_repo: :control) - - visit new_project_path - - find('li.header-new.dropdown').click - - page.within('li.header-new.dropdown') do - expect(page).to have_selector('a', text: 'New project') - expect(page).to have_no_selector('a', text: 'New project/repository') - end - - expect(page).to have_selector('h3', text: 'Create blank project') - expect(page).to have_no_selector('h3', text: 'Create blank project/repository') - end - - it 'when in candidate renders "project/repository"' do - stub_experiments(new_repo: :candidate) - - visit new_project_path - - find('li.header-new.dropdown').click - - page.within('li.header-new.dropdown') do - expect(page).to have_selector('a', text: 'New project/repository') - end - - expect(page).to have_selector('h3', text: 'Create blank project/repository') - end - - it 'when in control it renders "project" in the new projects dropdown' do - stub_experiments(new_repo: :control) - - visit new_project_path - - open_top_nav_projects - - within_top_nav do - if Feature.enabled?(:combined_menu, default_enabled: :yaml) - expect(page).to have_selector('a', text: 'Create new project') - expect(page).to have_no_selector('a', text: 'Create blank project/repository') - else - expect(page).to have_selector('a', text: 'Create blank project') - expect(page).to have_selector('a', text: 'Import project') - expect(page).to have_no_selector('a', text: 'Create blank project/repository') - expect(page).to have_no_selector('a', text: 'Import project/repository') - end - end - end - - it 'when in candidate it renders "project/repository" in the new projects dropdown' do - stub_experiments(new_repo: :candidate) - - visit new_project_path - - open_top_nav_projects - - within_top_nav do - if Feature.enabled?(:combined_menu, default_enabled: :yaml) - expect(page).to have_selector('a', text: 'Create new project') - else - expect(page).to have_selector('a', text: 'Create blank project/repository') - expect(page).to have_selector('a', text: 'Import project/repository') - end - end - end - end - it 'shows a message if multiple levels are restricted' do Gitlab::CurrentSettings.update!( restricted_visibility_levels: [Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::INTERNAL] ) visit new_project_path - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click expect(page).to have_content 'Other visibility settings have been disabled by the administrator.' end @@ -100,7 +31,7 @@ RSpec.describe 'New project', :js do ) visit new_project_path - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click expect(page).to have_content 'Visibility settings have been disabled by the administrator.' end @@ -115,14 +46,14 @@ RSpec.describe 'New project', :js do it 'shows "New project" page', :js do visit new_project_path - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click expect(page).to have_content('Project name') expect(page).to have_content('Project URL') expect(page).to have_content('Project slug') click_link('New project') - find('[data-qa-selector="import_project_link"]').click + find('[data-qa-panel-name="import_project"]').click expect(page).to have_link('GitHub') expect(page).to have_link('Bitbucket') @@ -135,7 +66,7 @@ RSpec.describe 'New project', :js do before do visit new_project_path - find('[data-qa-selector="import_project_link"]').click + find('[data-qa-panel-name="import_project"]').click end it 'has Manifest file' do @@ -149,7 +80,7 @@ RSpec.describe 'New project', :js do stub_application_setting(default_project_visibility: level) visit new_project_path - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click page.within('#blank-project-pane') do expect(find_field("project_visibility_level_#{level}")).to be_checked end @@ -157,7 +88,7 @@ RSpec.describe 'New project', :js do it "saves visibility level #{level} on validation error" do visit new_project_path - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click choose(key) click_button('Create project') @@ -177,7 +108,7 @@ RSpec.describe 'New project', :js do context 'when admin mode is enabled', :enable_admin_mode do it 'has private selected' do visit new_project_path(namespace_id: group.id) - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click page.within('#blank-project-pane') do expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked @@ -204,7 +135,7 @@ RSpec.describe 'New project', :js do context 'when admin mode is enabled', :enable_admin_mode do it 'has private selected' do visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE }) - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click page.within('#blank-project-pane') do expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked @@ -225,7 +156,7 @@ RSpec.describe 'New project', :js do context 'Readme selector' do it 'shows the initialize with Readme checkbox on "Blank project" tab' do visit new_project_path - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click expect(page).to have_css('input#project_initialize_with_readme') expect(page).to have_content('Initialize repository with a README') @@ -233,7 +164,7 @@ RSpec.describe 'New project', :js do it 'does not show the initialize with Readme checkbox on "Create from template" tab' do visit new_project_path - find('[data-qa-selector="create_from_template_link"]').click + find('[data-qa-panel-name="create_from_template"]').click first('.choose-template').click page.within '.project-fields-form' do @@ -244,7 +175,7 @@ RSpec.describe 'New project', :js do it 'does not show the initialize with Readme checkbox on "Import project" tab' do visit new_project_path - find('[data-qa-selector="import_project_link"]').click + find('[data-qa-panel-name="import_project"]').click first('.js-import-git-toggle-button').click page.within '#import-project-pane' do @@ -258,7 +189,7 @@ RSpec.describe 'New project', :js do context 'with user namespace' do before do visit new_project_path - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click end it 'selects the user namespace' do @@ -274,7 +205,7 @@ RSpec.describe 'New project', :js do before do group.add_owner(user) visit new_project_path(namespace_id: group.id) - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click end it 'selects the group namespace' do @@ -291,7 +222,7 @@ RSpec.describe 'New project', :js do before do group.add_maintainer(user) visit new_project_path(namespace_id: subgroup.id) - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click end it 'selects the group namespace' do @@ -311,7 +242,7 @@ RSpec.describe 'New project', :js do internal_group.add_owner(user) private_group.add_owner(user) visit new_project_path(namespace_id: public_group.id) - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click end it 'enables the correct visibility options' do @@ -341,7 +272,7 @@ RSpec.describe 'New project', :js do context 'Import project options', :js do before do visit new_project_path - find('[data-qa-selector="import_project_link"]').click + find('[data-qa-panel-name="import_project"]').click end context 'from git repository url, "Repo by URL"' do @@ -362,6 +293,14 @@ RSpec.describe 'New project', :js do expect(git_import_instructions).to have_content 'Git repository URL' end + it 'reports error if repo URL does not end with .git' do + fill_in 'project_import_url', with: 'http://foo/bar' + # simulate blur event + find('body').click + + expect(page).to have_text('A repository URL usually ends in a .git suffix') + end + it 'keeps "Import project" tab open after form validation error' do collision_project = create(:project, name: 'test-name-collision', namespace: user.namespace) @@ -405,7 +344,7 @@ RSpec.describe 'New project', :js do before do group.add_developer(user) visit new_project_path(namespace_id: group.id) - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click end it 'selects the group namespace' do diff --git a/spec/features/projects/package_files_spec.rb b/spec/features/projects/package_files_spec.rb index bea9a9929b9..c5c03396d71 100644 --- a/spec/features/projects/package_files_spec.rb +++ b/spec/features/projects/package_files_spec.rb @@ -23,12 +23,18 @@ RSpec.describe 'PackageFiles' do expect(status_code).to eq(200) end - it 'renders the download link with the correct url', :js do - visit project_package_path(project, package) + context 'when package_details_apollo feature flag is off' do + before do + stub_feature_flags(package_details_apollo: false) + end - download_url = download_project_package_file_path(project, package_file) + it 'renders the download link with the correct url', :js do + visit project_package_path(project, package) - expect(page).to have_link(package_file.file_name, href: download_url) + download_url = download_project_package_file_path(project, package_file) + + expect(page).to have_link(package_file.file_name, href: download_url) + end end it 'does not allow download of package belonging to different project' do diff --git a/spec/features/projects/packages_spec.rb b/spec/features/projects/packages_spec.rb index e5c684bdff5..fa4c57c305d 100644 --- a/spec/features/projects/packages_spec.rb +++ b/spec/features/projects/packages_spec.rb @@ -31,13 +31,19 @@ RSpec.describe 'Packages' do end context 'when there are packages' do - let_it_be(:conan_package) { create(:conan_package, project: project, name: 'zzz', created_at: 1.day.ago, version: '1.0.0') } + let_it_be(:npm_package) { create(:npm_package, project: project, name: 'zzz', created_at: 1.day.ago, version: '1.0.0') } let_it_be(:maven_package) { create(:maven_package, project: project, name: 'aaa', created_at: 2.days.ago, version: '2.0.0') } - let_it_be(:packages) { [conan_package, maven_package] } + let_it_be(:packages) { [npm_package, maven_package] } it_behaves_like 'packages list' - it_behaves_like 'package details link' + context 'when package_details_apollo feature flag is off' do + before do + stub_feature_flags(package_details_apollo: false) + end + + it_behaves_like 'package details link' + end context 'deleting a package' do let_it_be(:project) { create(:project) } @@ -54,7 +60,7 @@ RSpec.describe 'Packages' do it_behaves_like 'shared package sorting' do let_it_be(:package_one) { maven_package } - let_it_be(:package_two) { conan_package } + let_it_be(:package_two) { npm_package } end end diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index 70dc0bd04e8..0958e1d1891 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -7,7 +7,8 @@ RSpec.describe 'Pipeline', :js do include ProjectForksHelper include ::ExclusiveLeaseHelpers - let(:project) { create(:project) } + let_it_be(:project) { create(:project) } + let(:user) { create(:user) } let(:role) { :developer } @@ -59,8 +60,9 @@ RSpec.describe 'Pipeline', :js do describe 'GET /:project/-/pipelines/:id' do include_context 'pipeline builds' - let(:group) { create(:group) } - let(:project) { create(:project, :repository, group: group) } + let_it_be(:group) { create(:group) } + let_it_be(:project, reload: true) { create(:project, :repository, group: group) } + let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id, user: user) } subject(:visit_pipeline) { visit project_pipeline_path(project, pipeline) } @@ -246,6 +248,8 @@ RSpec.describe 'Pipeline', :js do end context 'when pipeline has a delayed job' do + let(:project) { create(:project, :repository, group: group) } + it 'shows the scheduled icon and an unschedule action for the delayed job' do page.within('#ci-badge-delayed-job') do expect(page).to have_selector('.js-ci-status-icon-scheduled') @@ -434,30 +438,44 @@ RSpec.describe 'Pipeline', :js do end end - context 'deleting pipeline' do - context 'when user can not delete' do - before do - visit_pipeline + shared_context 'delete pipeline' do + context 'deleting pipeline' do + context 'when user can not delete' do + before do + visit_pipeline + end + + it { expect(page).not_to have_button('Delete') } end - it { expect(page).not_to have_button('Delete') } - end + context 'when deleting' do + before do + group.add_owner(user) - context 'when deleting' do - before do - group.add_owner(user) + visit_pipeline - visit_pipeline + click_button 'Delete' + click_button 'Delete pipeline' + end - click_button 'Delete' - click_button 'Delete pipeline' + it 'redirects to pipeline overview page', :sidekiq_inline do + expect(page).to have_content('The pipeline has been deleted') + expect(current_path).to eq(project_pipelines_path(project)) + end end + end + end - it 'redirects to pipeline overview page', :sidekiq_might_not_need_inline do - expect(page).to have_content('The pipeline has been deleted') - expect(current_path).to eq(project_pipelines_path(project)) - end + context 'when cancel_pipelines_prior_to_destroy is enabled' do + include_context 'delete pipeline' + end + + context 'when cancel_pipelines_prior_to_destroy is disabled' do + before do + stub_feature_flags(cancel_pipelines_prior_to_destroy: false) end + + include_context 'delete pipeline' end context 'when pipeline ref does not exist in repository anymore' do @@ -550,6 +568,7 @@ RSpec.describe 'Pipeline', :js do end context 'when pipeline is merge request pipeline' do + let(:project) { create(:project, :repository, group: group) } let(:source_project) { project } let(:target_project) { project } @@ -634,7 +653,8 @@ RSpec.describe 'Pipeline', :js do describe 'GET /:project/-/pipelines/:id' do include_context 'pipeline builds' - let(:project) { create(:project, :repository) } + let_it_be(:project) { create(:project, :repository) } + let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id, user: user) } before do @@ -997,7 +1017,8 @@ RSpec.describe 'Pipeline', :js do describe 'GET /:project/-/pipelines/:id/builds' do include_context 'pipeline builds' - let(:project) { create(:project, :repository) } + let_it_be(:project) { create(:project, :repository) } + let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) } before do @@ -1234,7 +1255,8 @@ RSpec.describe 'Pipeline', :js do describe 'GET /:project/-/pipelines/:id/dag' do include_context 'pipeline builds' - let(:project) { create(:project, :repository) } + let_it_be(:project) { create(:project, :repository) } + let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) } before do @@ -1263,7 +1285,7 @@ RSpec.describe 'Pipeline', :js do end context 'when user sees pipeline flags in a pipeline detail page' do - let(:project) { create(:project, :repository) } + let_it_be(:project) { create(:project, :repository) } context 'when pipeline is latest' do include_context 'pipeline builds' diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index f1672af1019..1de0eea4657 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -783,7 +783,7 @@ RSpec.describe 'Pipelines', :js do end it 'renders empty state' do - expect(page).to have_content 'Build with confidence' + expect(page).to have_content 'Use a sample CI/CD template' end end 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 024c0a227c5..561b283ee15 100644 --- a/spec/features/projects/releases/user_views_edit_release_spec.rb +++ b/spec/features/projects/releases/user_views_edit_release_spec.rb @@ -4,9 +4,11 @@ require 'spec_helper' RSpec.describe 'User edits Release', :js do let_it_be(:project) { create(:project, :repository) } - let_it_be(:release) { create(:release, :with_milestones, milestones_count: 1, project: project, name: 'The first release' ) } let_it_be(:user) { create(:user) } + let(:release) { create(:release, :with_milestones, milestones_count: 1, project: project, name: 'The first release' ) } + let(:release_link) { create(:release_link, release: release) } + before do project.add_developer(user) @@ -68,6 +70,14 @@ RSpec.describe 'User edits Release', :js do expect(release.description).to eq('Updated Release notes') end + it 'does not affect the asset link' do + fill_out_form_and_click 'Save changes' + + expected_filepath = release_link.filepath + release_link.reload + expect(release_link.filepath).to eq(expected_filepath) + end + it 'redirects to the previous page when "Cancel" is clicked when the url includes a back_url query parameter' do back_path = project_releases_path(project, params: { page: 2 }) visit edit_project_release_path(project, release, params: { back_url: back_path }) diff --git a/spec/features/projects/releases/user_views_releases_spec.rb b/spec/features/projects/releases/user_views_releases_spec.rb index fcb1b6a0015..6bc4c66b8ca 100644 --- a/spec/features/projects/releases/user_views_releases_spec.rb +++ b/spec/features/projects/releases/user_views_releases_spec.rb @@ -14,9 +14,14 @@ RSpec.describe 'User views releases', :js do let_it_be(:maintainer) { create(:user) } let_it_be(:guest) { create(:user) } + let_it_be(:internal_link) { create(:release_link, release: release_v1, name: 'An internal link', url: "#{project.web_url}/-/jobs/1/artifacts/download", filepath: nil) } + let_it_be(:internal_link_with_redirect) { create(:release_link, release: release_v1, name: 'An internal link with a redirect', url: "#{project.web_url}/-/jobs/2/artifacts/download", filepath: '/binaries/linux-amd64' ) } + let_it_be(:external_link) { create(:release_link, release: release_v1, name: 'An external link', url: "https://example.com/an/external/link", filepath: nil) } + before do project.add_maintainer(maintainer) project.add_guest(guest) + stub_default_url_options(host: 'localhost') end shared_examples 'releases index page' do @@ -25,6 +30,8 @@ RSpec.describe 'User views releases', :js do sign_in(maintainer) visit project_releases_path(project) + + wait_for_requests end it 'sees the release' do @@ -35,38 +42,18 @@ RSpec.describe 'User views releases', :js do end end - context 'when there is a link as an asset' do - let!(:release_link) { create(:release_link, release: release_v1, url: url ) } - let(:url) { "#{project.web_url}/-/jobs/1/artifacts/download" } - let(:direct_asset_link) { Gitlab::Routing.url_helpers.project_release_url(project, release_v1) << "/downloads#{release_link.filepath}" } + it 'renders the correct links', :aggregate_failures do + page.within("##{release_v1.tag} .js-assets-list") do + external_link_indicator_selector = '[data-testid="external-link-indicator"]' - it 'sees the link' do - page.within("##{release_v1.tag} .js-assets-list") do - expect(page).to have_link release_link.name, href: direct_asset_link - expect(page).not_to have_css('[data-testid="external-link-indicator"]') - end - end + 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) - context 'when there is a link redirect' do - let!(:release_link) { create(:release_link, release: release_v1, name: 'linux-amd64 binaries', filepath: '/binaries/linux-amd64', url: url) } - let(:url) { "#{project.web_url}/-/jobs/1/artifacts/download" } + 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) - it 'sees the link', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/329301' do - page.within("##{release_v1.tag} .js-assets-list") do - expect(page).to have_link release_link.name, href: direct_asset_link - expect(page).not_to have_css('[data-testid="external-link-indicator"]') - end - end - end - - context 'when url points to external resource' do - let(:url) { 'http://google.com/download' } - - it 'sees that the link is external resource', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/329302' do - page.within("##{release_v1.tag} .js-assets-list") do - expect(page).to have_css('[data-testid="external-link-indicator"]') - end - end + 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) end end diff --git a/spec/features/projects/services/prometheus_external_alerts_spec.rb b/spec/features/projects/services/prometheus_external_alerts_spec.rb index 4c32905a8c5..c2ae72ddb5e 100644 --- a/spec/features/projects/services/prometheus_external_alerts_spec.rb +++ b/spec/features/projects/services/prometheus_external_alerts_spec.rb @@ -10,7 +10,7 @@ RSpec.describe 'Prometheus external alerts', :js do context 'with manual configuration' do before do - create(:prometheus_service, project: project, api_url: 'http://prometheus.example.com', manual_configuration: '1', active: true) + create(:prometheus_integration, project: project, api_url: 'http://prometheus.example.com', manual_configuration: '1', active: true) end it 'shows the Alerts section' do diff --git a/spec/features/projects/services/user_activates_prometheus_spec.rb b/spec/features/projects/services/user_activates_prometheus_spec.rb index b89e89d250f..73ad8088be2 100644 --- a/spec/features/projects/services/user_activates_prometheus_spec.rb +++ b/spec/features/projects/services/user_activates_prometheus_spec.rb @@ -17,6 +17,6 @@ RSpec.describe 'User activates Prometheus' do click_button('Save changes') expect(page).not_to have_content('Prometheus settings saved and active.') - expect(page).to have_content('Fields on this page has been deprecated.') + expect(page).to have_content('Fields on this page have been deprecated.') end end diff --git a/spec/features/projects/services/user_activates_slack_notifications_spec.rb b/spec/features/projects/services/user_activates_slack_notifications_spec.rb index dec83ff1489..d5fe8b083ba 100644 --- a/spec/features/projects/services/user_activates_slack_notifications_spec.rb +++ b/spec/features/projects/services/user_activates_slack_notifications_spec.rb @@ -20,12 +20,12 @@ RSpec.describe 'User activates Slack notifications', :js do end context 'when service is already configured' do - let(:service) { Integrations::Slack.new } - let(:project) { create(:project, slack_service: service) } + let(:integration) { Integrations::Slack.new } + let(:project) { create(:project, slack_integration: integration) } before do - service.fields - service.update!( + integration.fields + integration.update!( push_channel: 1, issue_channel: 2, merge_request_channel: 3, @@ -34,7 +34,7 @@ RSpec.describe 'User activates Slack notifications', :js do pipeline_channel: 6, wiki_page_channel: 7) - visit(edit_project_service_path(project, service)) + visit(edit_project_service_path(project, integration)) end it 'filters events by channel' do diff --git a/spec/features/projects/settings/access_tokens_spec.rb b/spec/features/projects/settings/access_tokens_spec.rb index 76d5d7308d1..33e2623522e 100644 --- a/spec/features/projects/settings/access_tokens_spec.rb +++ b/spec/features/projects/settings/access_tokens_spec.rb @@ -51,10 +51,10 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do name = 'My project access token' visit project_settings_access_tokens_path(project) - fill_in 'Name', with: name + fill_in 'Token name', with: name # Set date to 1st of next month - find_field('Expires at').click + find_field('Expiration date').click find('.pika-next').click click_on '1' @@ -68,6 +68,7 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do expect(active_project_access_tokens).to have_text('In') expect(active_project_access_tokens).to have_text('api') expect(active_project_access_tokens).to have_text('read_api') + expect(active_project_access_tokens).to have_text('Maintainer') expect(created_project_access_token).not_to be_empty end diff --git a/spec/features/projects/settings/monitor_settings_spec.rb b/spec/features/projects/settings/monitor_settings_spec.rb index 971a747e64f..2d8c418b7d0 100644 --- a/spec/features/projects/settings/monitor_settings_spec.rb +++ b/spec/features/projects/settings/monitor_settings_spec.rb @@ -18,17 +18,6 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do expect(page).to have_selector('.sidebar-sub-level-items a[aria-label="Monitor"]', text: 'Monitor', visible: false) end - - context 'when feature flag sidebar_refactor is disabled' do - it 'renders the menu "Operations" in the sidebar' do - stub_feature_flags(sidebar_refactor: false) - - visit project_path(project) - wait_for_requests - - expect(page).to have_selector('.sidebar-sub-level-items a[aria-label="Operations"]', text: 'Operations', visible: false) - end - end end describe 'Settings > Monitor' do @@ -53,7 +42,7 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do expect(find_field(send_email)).to be_checked end - it 'updates form values' do + it 'updates form values', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/333665' do check(create_issue) uncheck(send_email) click_on('No template selected') diff --git a/spec/features/projects/settings/registry_settings_spec.rb b/spec/features/projects/settings/registry_settings_spec.rb index 1cc54b71d4a..3f9f2dae453 100644 --- a/spec/features/projects/settings/registry_settings_spec.rb +++ b/spec/features/projects/settings/registry_settings_spec.rb @@ -11,125 +11,105 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p let(:container_registry_enabled) { true } let(:container_registry_enabled_on_project) { true } - shared_examples 'an expiration policy form' do - before do - project.update!(container_registry_enabled: container_registry_enabled_on_project) - project.container_expiration_policy.update!(enabled: true) + subject { visit project_settings_packages_and_registries_path(project) } - sign_in(user) - stub_container_registry_config(enabled: container_registry_enabled) - end - - context 'as owner' do - it 'shows available section' do - subject - - settings_block = find('[data-testid="registry-settings-app"]') - expect(settings_block).to have_text 'Clean up image tags' - end + before do + project.update!(container_registry_enabled: container_registry_enabled_on_project) + project.container_expiration_policy.update!(enabled: true) - it 'saves cleanup policy submit the form' do - subject - - within '[data-testid="registry-settings-app"]' do - select('Every day', from: 'Run cleanup') - select('50 tags per image name', from: 'Keep the most recent:') - fill_in('Keep tags matching:', with: 'stable') - select('7 days', from: 'Remove tags older than:') - fill_in('Remove tags matching:', with: '.*-production') - - submit_button = find('[data-testid="save-button"') - expect(submit_button).not_to be_disabled - submit_button.click - end + sign_in(user) + stub_container_registry_config(enabled: container_registry_enabled) + end - expect(find('.gl-toast')).to have_content('Cleanup policy successfully saved.') - end + context 'as owner' do + it 'shows available section' do + subject - it 'does not save cleanup policy submit form with invalid regex' do - subject + settings_block = find('[data-testid="registry-settings-app"]') + expect(settings_block).to have_text 'Clean up image tags' + end - within '[data-testid="registry-settings-app"]' do - fill_in('Remove tags matching:', with: '*-production') + it 'saves cleanup policy submit the form' do + subject - submit_button = find('[data-testid="save-button"') - expect(submit_button).not_to be_disabled - submit_button.click - end + within '[data-testid="registry-settings-app"]' do + select('Every day', from: 'Run cleanup') + select('50 tags per image name', from: 'Keep the most recent:') + fill_in('Keep tags matching:', with: 'stable') + select('7 days', from: 'Remove tags older than:') + fill_in('Remove tags matching:', with: '.*-production') - expect(find('.gl-toast')).to have_content('Something went wrong while updating the cleanup policy.') + submit_button = find('[data-testid="save-button"') + expect(submit_button).not_to be_disabled + submit_button.click end + + expect(find('.gl-toast')).to have_content('Cleanup policy successfully saved.') end - context 'with a project without expiration policy' do - where(:application_setting, :feature_flag, :result) do - true | true | :available_section - true | false | :available_section - false | true | :available_section - false | false | :disabled_message - end + it 'does not save cleanup policy submit form with invalid regex' do + subject - with_them do - before do - project.container_expiration_policy.destroy! - stub_feature_flags(container_expiration_policies_historic_entry: false) - stub_application_setting(container_expiration_policies_enable_historic_entries: application_setting) - stub_feature_flags(container_expiration_policies_historic_entry: project) if feature_flag - end + within '[data-testid="registry-settings-app"]' do + fill_in('Remove tags matching:', with: '*-production') - it 'displays the expected result' do - subject - - within '[data-testid="registry-settings-app"]' do - case result - when :available_section - expect(find('[data-testid="enable-toggle"]')).to have_content('Disabled - Tags will not be automatically deleted.') - when :disabled_message - expect(find('.gl-alert-title')).to have_content('Cleanup policy for tags is disabled') - end - end - end + submit_button = find('[data-testid="save-button"') + expect(submit_button).not_to be_disabled + submit_button.click end - end - - context 'when registry is disabled' do - let(:container_registry_enabled) { false } - it 'does not exists' do - subject + expect(find('.gl-toast')).to have_content('Something went wrong while updating the cleanup policy.') + end + end - expect(page).not_to have_selector('[data-testid="registry-settings-app"]') - end + context 'with a project without expiration policy' do + where(:application_setting, :feature_flag, :result) do + true | true | :available_section + true | false | :available_section + false | true | :available_section + false | false | :disabled_message end - context 'when container registry is disabled on project' do - let(:container_registry_enabled_on_project) { false } + with_them do + before do + project.container_expiration_policy.destroy! + stub_feature_flags(container_expiration_policies_historic_entry: false) + stub_application_setting(container_expiration_policies_enable_historic_entries: application_setting) + stub_feature_flags(container_expiration_policies_historic_entry: project) if feature_flag + end - it 'does not exists' do + it 'displays the expected result' do subject - expect(page).not_to have_selector('[data-testid="registry-settings-app"]') + within '[data-testid="registry-settings-app"]' do + case result + when :available_section + expect(find('[data-testid="enable-toggle"]')).to have_content('Disabled - Tags will not be automatically deleted.') + when :disabled_message + expect(find('.gl-alert-title')).to have_content('Cleanup policy for tags is disabled') + end + end end end end - context 'with sidebar feature flag off' do - subject { visit project_settings_ci_cd_path(project) } + context 'when registry is disabled' do + let(:container_registry_enabled) { false } - before do - stub_feature_flags(sidebar_refactor: false) - end + it 'does not exists' do + subject - it_behaves_like 'an expiration policy form' + expect(page).not_to have_selector('[data-testid="registry-settings-app"]') + end end - context 'with sidebar feature flag on' do - subject { visit project_settings_packages_and_registries_path(project) } + context 'when container registry is disabled on project' do + let(:container_registry_enabled_on_project) { false } - before do - stub_feature_flags(sidebar_refactor: true) - end + it 'does not exists' do + subject - it_behaves_like 'an expiration policy form' + expect(page).not_to have_selector('[data-testid="registry-settings-app"]') + end end end diff --git a/spec/features/projects/settings/user_searches_in_settings_spec.rb b/spec/features/projects/settings/user_searches_in_settings_spec.rb index a60743f0e47..7ed96d01189 100644 --- a/spec/features/projects/settings/user_searches_in_settings_spec.rb +++ b/spec/features/projects/settings/user_searches_in_settings_spec.rb @@ -39,7 +39,7 @@ RSpec.describe 'User searches project settings', :js do visit project_settings_access_tokens_path(project) end - it_behaves_like 'can highlight results', 'Expires at' + it_behaves_like 'can highlight results', 'Expiration date' end context 'in Repository page' do diff --git a/spec/features/projects/terraform_spec.rb b/spec/features/projects/terraform_spec.rb index 55b906c2bc5..d080d101285 100644 --- a/spec/features/projects/terraform_spec.rb +++ b/spec/features/projects/terraform_spec.rb @@ -58,7 +58,7 @@ RSpec.describe 'Terraform', :js do context 'when clicking on the delete button' do let(:additional_state) { create(:terraform_state, project: project) } - it 'removes the state', :aggregate_failures do + it 'removes the state', :aggregate_failures, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/333640' do visit project_terraform_index_path(project) expect(page).to have_content(additional_state.name) diff --git a/spec/features/projects/tree/create_directory_spec.rb b/spec/features/projects/tree/create_directory_spec.rb index 54b081161e5..e2ae858cb9b 100644 --- a/spec/features/projects/tree/create_directory_spec.rb +++ b/spec/features/projects/tree/create_directory_spec.rb @@ -47,7 +47,7 @@ RSpec.describe 'Multi-file editor new directory', :js do find('.js-ide-commit-mode').click # Compact mode depends on the size of window. If it is shorter than MAX_WINDOW_HEIGHT_COMPACT, - # (as it is with CHROME_HEADLESS=0), this initial commit button will exist. Otherwise, if it is + # (as it is with WEBDRIVER_HEADLESS=0), this initial commit button will exist. Otherwise, if it is # taller (as it is by default with chrome headless) then the button will not exist. if page.has_css?('.qa-begin-commit-button') find('.qa-begin-commit-button').click diff --git a/spec/features/projects/tree/create_file_spec.rb b/spec/features/projects/tree/create_file_spec.rb index cefb84e6f5e..956b8898854 100644 --- a/spec/features/projects/tree/create_file_spec.rb +++ b/spec/features/projects/tree/create_file_spec.rb @@ -37,7 +37,7 @@ RSpec.describe 'Multi-file editor new file', :js do find('.js-ide-commit-mode').click # Compact mode depends on the size of window. If it is shorter than MAX_WINDOW_HEIGHT_COMPACT, - # (as it is with CHROME_HEADLESS=0), this initial commit button will exist. Otherwise, if it is + # (as it is with WEBDRIVER_HEADLESS=0), this initial commit button will exist. Otherwise, if it is # taller (as it is by default with chrome headless) then the button will not exist. if page.has_css?('.qa-begin-commit-button') find('.qa-begin-commit-button').click diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb index aff3022bd4e..a5b51bac747 100644 --- a/spec/features/projects/user_creates_project_spec.rb +++ b/spec/features/projects/user_creates_project_spec.rb @@ -15,7 +15,7 @@ RSpec.describe 'User creates a project', :js do it 'creates a new project' do visit(new_project_path) - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click fill_in(:project_name, with: 'Empty') # part of the new_project_readme experiment @@ -46,7 +46,7 @@ RSpec.describe 'User creates a project', :js do it 'creates a new project' do visit(new_project_path) - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click fill_in :project_name, with: 'A Subgroup Project' fill_in :project_path, with: 'a-subgroup-project' @@ -75,7 +75,7 @@ RSpec.describe 'User creates a project', :js do it 'creates a new project' do visit(new_project_path) - find('[data-qa-selector="blank_project_link"]').click + find('[data-qa-panel-name="blank_project"]').click fill_in :project_name, with: 'a-new-project' fill_in :project_path, with: 'a-new-project' diff --git a/spec/features/projects/user_sees_user_popover_spec.rb b/spec/features/projects/user_sees_user_popover_spec.rb index db451578ff8..0bbe7f26cd4 100644 --- a/spec/features/projects/user_sees_user_popover_spec.rb +++ b/spec/features/projects/user_sees_user_popover_spec.rb @@ -5,9 +5,9 @@ require 'spec_helper' RSpec.describe 'User sees user popover', :js do include Spec::Support::Helpers::Features::NotesHelpers - let_it_be(:project) { create(:project, :repository) } + let_it_be(:user) { create(:user, pronouns: 'they/them') } + let_it_be(:project) { create(:project, :repository, creator: user) } - let(:user) { project.creator } let(:merge_request) do create(:merge_request, source_project: project, target_project: project) end @@ -32,7 +32,7 @@ RSpec.describe 'User sees user popover', :js do expect(page).to have_css(popover_selector, visible: true) page.within(popover_selector) do - expect(page).to have_content(user.name) + expect(page).to have_content("#{user.name} (they/them)") end end diff --git a/spec/features/projects/user_uses_shortcuts_spec.rb b/spec/features/projects/user_uses_shortcuts_spec.rb index 2f7844ff615..7bb15451538 100644 --- a/spec/features/projects/user_uses_shortcuts_spec.rb +++ b/spec/features/projects/user_uses_shortcuts_spec.rb @@ -77,20 +77,6 @@ RSpec.describe 'User uses shortcuts', :js do expect(page).to have_active_navigation(project.name) end - context 'when feature flag :sidebar_refactor is disabled' do - it 'redirects to the details page' do - stub_feature_flags(sidebar_refactor: false) - - visit project_issues_path(project) - - find('body').native.send_key('g') - find('body').native.send_key('p') - - expect(page).to have_active_navigation('Project') - expect(page).to have_active_sub_navigation('Details') - end - end - it 'redirects to the activity page' do find('body').native.send_key('g') find('body').native.send_key('v') @@ -196,36 +182,6 @@ RSpec.describe 'User uses shortcuts', :js do expect(page).to have_active_navigation('Monitor') expect(page).to have_active_sub_navigation('Metrics') end - - context 'when feature flag :sidebar_refactor is disabled' do - before do - stub_feature_flags(sidebar_refactor: false) - end - - it 'redirects to the Operations page' do - find('body').native.send_key('g') - find('body').native.send_key('l') - - expect(page).to have_active_navigation('Operations') - expect(page).to have_active_sub_navigation('Metrics') - end - - it 'redirects to the Kubernetes page with active Operations' do - find('body').native.send_key('g') - find('body').native.send_key('k') - - expect(page).to have_active_navigation('Operations') - expect(page).to have_active_sub_navigation('Kubernetes') - end - - it 'redirects to the Environments page' do - find('body').native.send_key('g') - find('body').native.send_key('e') - - expect(page).to have_active_navigation('Operations') - expect(page).to have_active_sub_navigation('Environments') - end - end end context 'when navigating to the Infrastructure pages' do diff --git a/spec/features/projects/user_views_empty_project_spec.rb b/spec/features/projects/user_views_empty_project_spec.rb index cce38456df9..696a7f4ee8a 100644 --- a/spec/features/projects/user_views_empty_project_spec.rb +++ b/spec/features/projects/user_views_empty_project_spec.rb @@ -7,10 +7,12 @@ RSpec.describe 'User views an empty project' do let_it_be(:user) { create(:user) } shared_examples 'allowing push to default branch' do - it 'shows push-to-master instructions' do + let(:default_branch) { project.default_branch_or_main } + + it 'shows push-to-default-branch instructions' do visit project_path(project) - expect(page).to have_content('git push -u origin master') + expect(page).to have_content("git push -u origin #{default_branch}") end end @@ -47,7 +49,7 @@ RSpec.describe 'User views an empty project' do it 'does not show push-to-master instructions' do visit project_path(project) - expect(page).not_to have_content('git push -u origin master') + expect(page).not_to have_content('git push -u origin') end end end @@ -61,7 +63,7 @@ RSpec.describe 'User views an empty project' do it 'does not show push-to-master instructions nor invite members link', :aggregate_failures, :js do visit project_path(project) - expect(page).not_to have_content('git push -u origin master') + expect(page).not_to have_content('git push -u origin') expect(page).not_to have_button(text: 'Invite members') end end diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb index 2ac829d406c..a3d134d49eb 100644 --- a/spec/features/projects_spec.rb +++ b/spec/features/projects_spec.rb @@ -16,7 +16,7 @@ RSpec.describe 'Project' do shared_examples 'creates from template' do |template, sub_template_tab = nil| it "is created from template", :js do - find('[data-qa-selector="create_from_template_link"]').click + find('[data-qa-panel-name="create_from_template"]').click find(".project-template #{sub_template_tab}").click if sub_template_tab find("label[for=#{template.name}]").click fill_in("project_name", with: template.name) @@ -256,7 +256,7 @@ RSpec.describe 'Project' do expect(page).to have_selector '#confirm_name_input:focus' end - it 'deletes a project', :sidekiq_might_not_need_inline do + it 'deletes a project', :sidekiq_inline do expect { remove_with_confirm('Delete project', project.path, 'Yes, delete project') }.to change { Project.count }.by(-1) expect(page).to have_content "Project '#{project.full_name}' is in the process of being deleted." expect(Project.all.count).to be_zero diff --git a/spec/features/search/user_searches_for_code_spec.rb b/spec/features/search/user_searches_for_code_spec.rb index 094b31ba784..ef7af0ba138 100644 --- a/spec/features/search/user_searches_for_code_spec.rb +++ b/spec/features/search/user_searches_for_code_spec.rb @@ -21,7 +21,8 @@ RSpec.describe 'User searches for code' do 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: /master\/files\/js\/application.js/) + expect(page).to have_link('application.js', href: %r{master/files/js/application.js}) + expect(page).to have_button('Copy file path') end context 'when on a project page', :js do @@ -37,6 +38,7 @@ RSpec.describe 'User searches for code' do end include_examples 'top right search form' + include_examples 'search timeouts', 'blobs' it 'finds code' do fill_in('dashboard_search', with: 'rspec') @@ -45,7 +47,7 @@ RSpec.describe 'User searches for code' do expect(page).to have_selector('.results', text: 'Update capybara, rspec-rails, poltergeist to recent versions') find("#L3").click - expect(current_url).to match(/master\/.gitignore#L3/) + expect(current_url).to match(%r{master/.gitignore#L3}) end it 'search mutiple words with refs switching' do @@ -63,7 +65,7 @@ RSpec.describe 'User searches for code' do expect(page).to have_selector('.results', text: expected_result) expect(find_field('dashboard_search').value).to eq(search) - expect(find("#L1502")[:href]).to match(/v1.0.0\/files\/markdown\/ruby-style-guide.md#L1502/) + expect(find("#L1502")[:href]).to match(%r{v1.0.0/files/markdown/ruby-style-guide.md#L1502}) 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 2a12b22b457..5185a2460dc 100644 --- a/spec/features/search/user_searches_for_comments_spec.rb +++ b/spec/features/search/user_searches_for_comments_spec.rb @@ -13,6 +13,8 @@ RSpec.describe 'User searches for comments' do visit(project_path(project)) end + include_examples 'search timeouts', 'notes' + 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') } diff --git a/spec/features/search/user_searches_for_commits_spec.rb b/spec/features/search/user_searches_for_commits_spec.rb index 1a882050126..279db686aa9 100644 --- a/spec/features/search/user_searches_for_commits_spec.rb +++ b/spec/features/search/user_searches_for_commits_spec.rb @@ -14,6 +14,8 @@ RSpec.describe 'User searches for commits', :js do visit(search_path(project_id: project.id)) end + include_examples 'search timeouts', 'commits' + context 'when searching by SHA' do it 'finds a commit and redirects to its page' do submit_search(sha) diff --git a/spec/features/search/user_searches_for_issues_spec.rb b/spec/features/search/user_searches_for_issues_spec.rb index 184f8ba0d36..b0902096770 100644 --- a/spec/features/search/user_searches_for_issues_spec.rb +++ b/spec/features/search/user_searches_for_issues_spec.rb @@ -23,6 +23,7 @@ RSpec.describe 'User searches for issues', :js do end include_examples 'top right search form' + include_examples 'search timeouts', 'issues' it 'finds an issue' do search_for_issue(issue1.title) 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 32952a127d3..d7f490ba9bc 100644 --- a/spec/features/search/user_searches_for_merge_requests_spec.rb +++ b/spec/features/search/user_searches_for_merge_requests_spec.rb @@ -22,6 +22,7 @@ RSpec.describe 'User searches for merge requests', :js do end include_examples 'top right search form' + include_examples 'search timeouts', 'merge_requests' it 'finds a merge request' do search_for_mr(merge_request1.title) diff --git a/spec/features/search/user_searches_for_milestones_spec.rb b/spec/features/search/user_searches_for_milestones_spec.rb index e81abb44ba5..7a1ec16385c 100644 --- a/spec/features/search/user_searches_for_milestones_spec.rb +++ b/spec/features/search/user_searches_for_milestones_spec.rb @@ -16,6 +16,7 @@ RSpec.describe 'User searches for milestones', :js do end include_examples 'top right search form' + include_examples 'search timeouts', 'milestones' it 'finds a milestone' do fill_in('dashboard_search', with: milestone1.title) diff --git a/spec/features/search/user_searches_for_projects_spec.rb b/spec/features/search/user_searches_for_projects_spec.rb index e34ae031679..c38ad077cd0 100644 --- a/spec/features/search/user_searches_for_projects_spec.rb +++ b/spec/features/search/user_searches_for_projects_spec.rb @@ -12,6 +12,7 @@ RSpec.describe 'User searches for projects', :js do end include_examples 'top right search form' + include_examples 'search timeouts', 'projects' it 'finds a project' do visit(search_path) diff --git a/spec/features/search/user_searches_for_users_spec.rb b/spec/features/search/user_searches_for_users_spec.rb index 826ed73c9bf..a5cf12fa068 100644 --- a/spec/features/search/user_searches_for_users_spec.rb +++ b/spec/features/search/user_searches_for_users_spec.rb @@ -11,6 +11,8 @@ RSpec.describe 'User searches for users' do sign_in(user1) end + include_examples 'search timeouts', 'users' + context 'when on the dashboard' do it 'finds the user', :js do visit dashboard_projects_path 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 8913f1fe9ee..06545d8640f 100644 --- a/spec/features/search/user_searches_for_wiki_pages_spec.rb +++ b/spec/features/search/user_searches_for_wiki_pages_spec.rb @@ -15,6 +15,7 @@ RSpec.describe 'User searches for wiki pages', :js do end include_examples 'top right search form' + include_examples 'search timeouts', 'wiki_blobs' shared_examples 'search wiki blobs' do it 'finds a page' do diff --git a/spec/features/snippets/embedded_snippet_spec.rb b/spec/features/snippets/embedded_snippet_spec.rb index b799fb2fc00..90d877d29b7 100644 --- a/spec/features/snippets/embedded_snippet_spec.rb +++ b/spec/features/snippets/embedded_snippet_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe 'Embedded Snippets' do let_it_be(:snippet) { create(:personal_snippet, :public, :repository) } + let(:blobs) { snippet.blobs.first(3) } it 'loads snippet', :js do @@ -27,8 +28,8 @@ RSpec.describe 'Embedded Snippets' do blobs.each do |blob| expect(page).to have_content(blob.path) expect(page.find(".snippet-file-content .blob-content[data-blob-id='#{blob.id}'] code")).to have_content(blob.data.squish) - expect(page).to have_link('Open raw', href: /-\/snippets\/#{snippet.id}\/raw\/master\/#{blob.path}/) - expect(page).to have_link('Download', href: /-\/snippets\/#{snippet.id}\/raw\/master\/#{blob.path}\?inline=false/) + expect(page).to have_link('Open raw', href: %r{-/snippets/#{snippet.id}/raw/master/#{blob.path}}) + expect(page).to have_link('Download', href: %r{-/snippets/#{snippet.id}/raw/master/#{blob.path}\?inline=false}) end end end diff --git a/spec/features/unsubscribe_links_spec.rb b/spec/features/unsubscribe_links_spec.rb index b2d0f29808c..b7471720008 100644 --- a/spec/features/unsubscribe_links_spec.rb +++ b/spec/features/unsubscribe_links_spec.rb @@ -9,7 +9,7 @@ RSpec.describe 'Unsubscribe links', :sidekiq_might_not_need_inline do let(:author) { create(:user) } let(:project) { create(:project, :public) } let(:params) { { title: 'A bug!', description: 'Fix it!', assignees: [recipient] } } - let(:issue) { Issues::CreateService.new(project: project, current_user: author, params: params).execute } + let(:issue) { Issues::CreateService.new(project: project, current_user: author, params: params, spam_params: nil).execute } let(:mail) { ActionMailer::Base.deliveries.last } let(:body) { Capybara::Node::Simple.new(mail.default_part_body.to_s) } diff --git a/spec/features/usage_stats_consent_spec.rb b/spec/features/usage_stats_consent_spec.rb index 6fa1d7d76b5..69bd6f35558 100644 --- a/spec/features/usage_stats_consent_spec.rb +++ b/spec/features/usage_stats_consent_spec.rb @@ -27,7 +27,7 @@ RSpec.describe 'Usage stats consent' do expect(page).to have_content(message) - click_link 'Send usage data' + click_link 'Send service data' expect(page).not_to have_content(message) expect(page).to have_content('Application settings saved successfully') diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb index 7010059a7ff..6c38d5d8b24 100644 --- a/spec/features/users/login_spec.rb +++ b/spec/features/users/login_spec.rb @@ -97,6 +97,8 @@ RSpec.describe 'Login' do describe 'with an unconfirmed email address' do let!(:user) { create(:user, confirmed_at: nil) } let(:grace_period) { 2.days } + let(:alert_title) { 'Please confirm your email address' } + let(:alert_message) { "To continue, you need to select the link in the confirmation email we sent to verify your email address. If you didn't get our email, select Resend confirmation email" } before do stub_application_setting(send_user_confirmation_email: true) @@ -109,13 +111,14 @@ RSpec.describe 'Login' do gitlab_sign_in(user) - expect(page).not_to have_content(I18n.t('devise.failure.unconfirmed')) + expect(page).not_to have_content(alert_title) + expect(page).not_to have_content(alert_message) expect(page).not_to have_link('Resend confirmation email', href: new_user_confirmation_path) end end context 'when the confirmation grace period is expired' do - it 'prevents the user from logging in and renders a resend confirmation email link' do + it 'prevents the user from logging in and renders a resend confirmation email link', :js do travel_to((grace_period + 1.day).from_now) do expect(authentication_metrics) .to increment(:user_unauthenticated_counter) @@ -123,7 +126,8 @@ RSpec.describe 'Login' do gitlab_sign_in(user) - expect(page).to have_content(I18n.t('devise.failure.unconfirmed')) + expect(page).to have_content(alert_title) + expect(page).to have_content(alert_message) expect(page).to have_link('Resend confirmation email', href: new_user_confirmation_path) end end @@ -889,6 +893,8 @@ RSpec.describe 'Login' do context 'when sending confirmation email and not yet confirmed' do let!(:user) { create(:user, confirmed_at: nil) } let(:grace_period) { 2.days } + let(:alert_title) { 'Please confirm your email address' } + let(:alert_message) { "To continue, you need to select the link in the confirmation email we sent to verify your email address. If you didn't get our email, select Resend confirmation email" } before do stub_application_setting(send_user_confirmation_email: true) @@ -906,7 +912,7 @@ RSpec.describe 'Login' do end context "when not having confirmed within Devise's allow_unconfirmed_access_for time" do - it 'does not allow login and shows a flash alert to confirm the email address' do + it 'does not allow login and shows a flash alert to confirm the email address', :js do travel_to((grace_period + 1.day).from_now) do expect(authentication_metrics) .to increment(:user_unauthenticated_counter) @@ -915,7 +921,9 @@ RSpec.describe 'Login' do gitlab_sign_in(user) expect(current_path).to eq new_user_session_path - expect(page).to have_content(I18n.t('devise.failure.unconfirmed')) + expect(page).to have_content(alert_title) + expect(page).to have_content(alert_message) + expect(page).to have_link('Resend confirmation email', href: new_user_confirmation_path) end end end 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 ded90be3924..5e7d7b76843 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 @@ -125,7 +125,7 @@ RSpec.describe 'Users > User browses projects on user page', :js do end before do - Issues::CreateService.new(project: contributed_project, current_user: user, params: { title: 'Bug in old browser' }).execute + Issues::CreateService.new(project: 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 |