summaryrefslogtreecommitdiff
path: root/spec/features
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-06-16 18:25:58 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-06-16 18:25:58 +0000
commita5f4bba440d7f9ea47046a0a561d49adf0a1e6d4 (patch)
treefb69158581673816a8cd895f9d352dcb3c678b1e /spec/features
parentd16b2e8639e99961de6ddc93909f3bb5c1445ba1 (diff)
downloadgitlab-ce-a5f4bba440d7f9ea47046a0a561d49adf0a1e6d4.tar.gz
Add latest changes from gitlab-org/gitlab@14-0-stable-eev14.0.0-rc42
Diffstat (limited to 'spec/features')
-rw-r--r--spec/features/admin/admin_appearance_spec.rb20
-rw-r--r--spec/features/admin/admin_hooks_spec.rb18
-rw-r--r--spec/features/admin/admin_mode/logout_spec.rb31
-rw-r--r--spec/features/admin/admin_mode_spec.rb77
-rw-r--r--spec/features/admin/admin_runners_spec.rb58
-rw-r--r--spec/features/admin/admin_search_settings_spec.rb2
-rw-r--r--spec/features/admin/admin_sees_background_migrations_spec.rb84
-rw-r--r--spec/features/admin/admin_settings_spec.rb46
-rw-r--r--spec/features/admin/clusters/applications_spec.rb22
-rw-r--r--spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb16
-rw-r--r--spec/features/admin/users/user_spec.rb30
-rw-r--r--spec/features/admin/users/users_spec.rb458
-rw-r--r--spec/features/alert_management/alert_management_list_spec.rb24
-rw-r--r--spec/features/alerts_settings/user_views_alerts_settings_spec.rb2
-rw-r--r--spec/features/boards/boards_spec.rb42
-rw-r--r--spec/features/boards/issue_ordering_spec.rb2
-rw-r--r--spec/features/boards/multi_select_spec.rb4
-rw-r--r--spec/features/boards/new_issue_spec.rb34
-rw-r--r--spec/features/boards/sidebar_assignee_spec.rb2
-rw-r--r--spec/features/boards/sidebar_milestones_spec.rb4
-rw-r--r--spec/features/calendar_spec.rb13
-rw-r--r--spec/features/clusters/cluster_detail_page_spec.rb24
-rw-r--r--spec/features/clusters/cluster_health_dashboard_spec.rb12
-rw-r--r--spec/features/clusters/installing_applications_shared_examples.rb252
-rw-r--r--spec/features/contextual_sidebar_spec.rb8
-rw-r--r--spec/features/cycle_analytics_spec.rb4
-rw-r--r--spec/features/dashboard/active_tab_spec.rb21
-rw-r--r--spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb19
-rw-r--r--spec/features/dashboard/group_spec.rb2
-rw-r--r--spec/features/dashboard/shortcuts_spec.rb18
-rw-r--r--spec/features/frequently_visited_projects_and_groups_spec.rb14
-rw-r--r--spec/features/groups/clusters/applications_spec.rb23
-rw-r--r--spec/features/groups/group_settings_spec.rb20
-rw-r--r--spec/features/groups/import_export/connect_instance_spec.rb4
-rw-r--r--spec/features/groups/import_export/import_file_spec.rb14
-rw-r--r--spec/features/groups/integrations/user_activates_mattermost_slash_command_spec.rb16
-rw-r--r--spec/features/groups/members/manage_groups_spec.rb76
-rw-r--r--spec/features/groups/members/manage_members_spec.rb59
-rw-r--r--spec/features/groups/members/tabs_spec.rb6
-rw-r--r--spec/features/groups/milestones/gfm_autocomplete_spec.rb1
-rw-r--r--spec/features/groups/navbar_spec.rb12
-rw-r--r--spec/features/groups/settings/user_searches_in_settings_spec.rb2
-rw-r--r--spec/features/groups_spec.rb38
-rw-r--r--spec/features/incidents/incident_details_spec.rb38
-rw-r--r--spec/features/issues/csv_spec.rb4
-rw-r--r--spec/features/issues/issue_detail_spec.rb63
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb4
-rw-r--r--spec/features/issues/user_creates_issue_spec.rb48
-rw-r--r--spec/features/issues/user_edits_issue_spec.rb5
-rw-r--r--spec/features/issues/user_interacts_with_awards_spec.rb10
-rw-r--r--spec/features/issues/user_resets_their_incoming_email_token_spec.rb4
-rw-r--r--spec/features/issues/user_toggles_subscription_spec.rb71
-rw-r--r--spec/features/markdown/mermaid_spec.rb97
-rw-r--r--spec/features/markdown/metrics_spec.rb2
-rw-r--r--spec/features/merge_request/user_allows_commits_from_memebers_who_can_merge_spec.rb6
-rw-r--r--spec/features/merge_request/user_awards_emoji_spec.rb4
-rw-r--r--spec/features/merge_request/user_edits_assignees_sidebar_spec.rb4
-rw-r--r--spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb61
-rw-r--r--spec/features/merge_request/user_merges_immediately_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_merge_widget_spec.rb12
-rw-r--r--spec/features/merge_request/user_sees_versions_spec.rb8
-rw-r--r--spec/features/merge_request/user_views_diffs_spec.rb1
-rw-r--r--spec/features/merge_requests/user_exports_as_csv_spec.rb8
-rw-r--r--spec/features/nav/top_nav_responsive_spec.rb53
-rw-r--r--spec/features/profile_spec.rb4
-rw-r--r--spec/features/profiles/personal_access_tokens_spec.rb11
-rw-r--r--spec/features/profiles/user_edit_profile_spec.rb2
-rw-r--r--spec/features/profiles/user_search_settings_spec.rb2
-rw-r--r--spec/features/projects/active_tabs_spec.rb25
-rw-r--r--spec/features/projects/badges/pipeline_badge_spec.rb2
-rw-r--r--spec/features/projects/blobs/blob_show_spec.rb22
-rw-r--r--spec/features/projects/branches/user_deletes_branch_spec.rb33
-rw-r--r--spec/features/projects/branches/user_views_branches_spec.rb11
-rw-r--r--spec/features/projects/branches_spec.rb67
-rw-r--r--spec/features/projects/clusters/applications_spec.rb23
-rw-r--r--spec/features/projects/confluence/user_views_confluence_page_spec.rb2
-rw-r--r--spec/features/projects/environments/environment_spec.rb22
-rw-r--r--spec/features/projects/environments/environments_spec.rb2
-rw-r--r--spec/features/projects/environments_pod_logs_spec.rb2
-rw-r--r--spec/features/projects/feature_flag_user_lists/user_deletes_feature_flag_user_list_spec.rb7
-rw-r--r--spec/features/projects/feature_flags/user_sees_feature_flag_list_spec.rb58
-rw-r--r--spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb8
-rw-r--r--spec/features/projects/features_visibility_spec.rb4
-rw-r--r--spec/features/projects/import_export/import_file_spec.rb10
-rw-r--r--spec/features/projects/infrastructure_registry_spec.rb61
-rw-r--r--spec/features/projects/integrations/user_activates_flowdock_spec.rb (renamed from spec/features/projects/services/user_activates_flowdock_spec.rb)0
-rw-r--r--spec/features/projects/integrations/user_activates_jira_spec.rb (renamed from spec/features/projects/services/user_activates_jira_spec.rb)0
-rw-r--r--spec/features/projects/integrations/user_activates_pivotaltracker_spec.rb (renamed from spec/features/projects/services/user_activates_pivotaltracker_spec.rb)0
-rw-r--r--spec/features/projects/members/invite_group_spec.rb8
-rw-r--r--spec/features/projects/members/list_spec.rb50
-rw-r--r--spec/features/projects/members/tabs_spec.rb4
-rw-r--r--spec/features/projects/members/user_requests_access_spec.rb7
-rw-r--r--spec/features/projects/navbar_spec.rb4
-rw-r--r--spec/features/projects/new_project_spec.rb52
-rw-r--r--spec/features/projects/pages/user_edits_settings_spec.rb6
-rw-r--r--spec/features/projects/releases/user_views_releases_spec.rb172
-rw-r--r--spec/features/projects/serverless/functions_spec.rb1
-rw-r--r--spec/features/projects/services/disable_triggers_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb35
-rw-r--r--spec/features/projects/services/user_activates_slack_notifications_spec.rb2
-rw-r--r--spec/features/projects/settings/monitor_settings_spec.rb16
-rw-r--r--spec/features/projects/settings/registry_settings_spec.rb12
-rw-r--r--spec/features/projects/settings/service_desk_setting_spec.rb19
-rw-r--r--spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb6
-rw-r--r--spec/features/projects/settings/user_searches_in_settings_spec.rb2
-rw-r--r--spec/features/projects/show/schema_markup_spec.rb4
-rw-r--r--spec/features/projects/show/user_sees_collaboration_links_spec.rb12
-rw-r--r--spec/features/projects/user_uses_shortcuts_spec.rb8
-rw-r--r--spec/features/projects/user_views_empty_project_spec.rb23
-rw-r--r--spec/features/projects/wiki/user_views_wiki_empty_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb7
-rw-r--r--spec/features/projects_spec.rb14
-rw-r--r--spec/features/protected_branches_spec.rb52
-rw-r--r--spec/features/search/user_searches_for_code_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_issues_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_merge_requests_spec.rb7
-rw-r--r--spec/features/search/user_searches_for_milestones_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_wiki_pages_spec.rb2
-rw-r--r--spec/features/search/user_uses_header_search_field_spec.rb4
-rw-r--r--spec/features/search/user_uses_search_filters_spec.rb8
-rw-r--r--spec/features/security/project/snippet/private_access_spec.rb81
-rw-r--r--spec/features/users/show_spec.rb8
-rw-r--r--spec/features/users/signup_spec.rb2
124 files changed, 1805 insertions, 1352 deletions
diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb
index 603e757096f..5596ad7bf21 100644
--- a/spec/features/admin/admin_appearance_spec.rb
+++ b/spec/features/admin/admin_appearance_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'Admin Appearance' do
it 'create new appearance' do
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
- visit admin_appearances_path
+ visit admin_application_settings_appearances_path
fill_in 'appearance_title', with: 'MyCompany'
fill_in 'appearance_description', with: 'dev server'
@@ -17,7 +17,7 @@ RSpec.describe 'Admin Appearance' do
fill_in 'appearance_profile_image_guidelines', with: 'Custom profile image guidelines'
click_button 'Update appearance settings'
- expect(current_path).to eq admin_appearances_path
+ expect(current_path).to eq admin_application_settings_appearances_path
expect(page).to have_content 'Appearance'
expect(page).to have_field('appearance_title', with: 'MyCompany')
@@ -31,7 +31,7 @@ RSpec.describe 'Admin Appearance' do
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
- visit admin_appearances_path
+ visit admin_application_settings_appearances_path
click_link "Sign-in page"
expect_custom_sign_in_appearance(appearance)
@@ -41,7 +41,7 @@ RSpec.describe 'Admin Appearance' do
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
- visit admin_appearances_path
+ visit admin_application_settings_appearances_path
click_link "New project page"
expect_custom_new_project_appearance(appearance)
@@ -55,7 +55,7 @@ RSpec.describe 'Admin Appearance' do
context 'when system header and footer messages are empty' do
it 'shows custom system header and footer fields' do
- visit admin_appearances_path
+ visit admin_application_settings_appearances_path
expect(page).to have_field('appearance_header_message', with: '')
expect(page).to have_field('appearance_footer_message', with: '')
@@ -70,7 +70,7 @@ RSpec.describe 'Admin Appearance' do
end
it 'shows custom system header and footer fields' do
- visit admin_appearances_path
+ visit admin_application_settings_appearances_path
expect(page).to have_field('appearance_header_message', with: appearance.header_message)
expect(page).to have_field('appearance_footer_message', with: appearance.footer_message)
@@ -99,7 +99,7 @@ RSpec.describe 'Admin Appearance' do
before do
sign_in(create(:admin))
gitlab_enable_admin_mode_sign_in(admin)
- visit admin_appearances_path
+ visit admin_application_settings_appearances_path
fill_in 'appearance_profile_image_guidelines', with: 'Custom profile image guidelines, please :smile:!'
click_button 'Update appearance settings'
end
@@ -115,7 +115,7 @@ RSpec.describe 'Admin Appearance' do
it 'appearance logo' do
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
- visit admin_appearances_path
+ visit admin_application_settings_appearances_path
attach_file(:appearance_logo, logo_fixture)
click_button 'Update appearance settings'
@@ -128,7 +128,7 @@ RSpec.describe 'Admin Appearance' do
it 'header logos' do
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
- visit admin_appearances_path
+ visit admin_application_settings_appearances_path
attach_file(:appearance_header_logo, logo_fixture)
click_button 'Update appearance settings'
@@ -141,7 +141,7 @@ RSpec.describe 'Admin Appearance' do
it 'Favicon' do
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
- visit admin_appearances_path
+ visit admin_application_settings_appearances_path
attach_file(:appearance_favicon, logo_fixture)
click_button 'Update appearance settings'
diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb
index 3fed402267c..a501efd82ed 100644
--- a/spec/features/admin/admin_hooks_spec.rb
+++ b/spec/features/admin/admin_hooks_spec.rb
@@ -37,24 +37,6 @@ RSpec.describe 'Admin::Hooks' do
expect(page).to have_content('foo.rb')
expect(page).to have_content('bar.clj')
end
-
- context 'deprecation warning' do
- it 'shows warning for plugins directory' do
- allow(Gitlab::FileHook).to receive(:files).and_return(['plugins/foo.rb'])
-
- visit admin_hooks_path
-
- expect(page).to have_content('Plugins directory is deprecated and will be removed in 14.0')
- end
-
- it 'does not show warning for file_hooks directory' do
- allow(Gitlab::FileHook).to receive(:files).and_return(['file_hooks/foo.rb'])
-
- visit admin_hooks_path
-
- expect(page).not_to have_content('Plugins directory is deprecated and will be removed in 14.0')
- end
- end
end
describe 'New Hook' do
diff --git a/spec/features/admin/admin_mode/logout_spec.rb b/spec/features/admin/admin_mode/logout_spec.rb
index 664eb51e58f..efb4baa8164 100644
--- a/spec/features/admin/admin_mode/logout_spec.rb
+++ b/spec/features/admin/admin_mode/logout_spec.rb
@@ -5,28 +5,32 @@ require 'spec_helper'
RSpec.describe 'Admin Mode Logout', :js do
include TermsHelper
include UserLoginHelper
+ include Spec::Support::Helpers::Features::TopNavSpecHelpers
let(:user) { create(:admin) }
shared_examples 'combined_menu: feature flag examples' do
before do
- gitlab_sign_in(user)
+ # TODO: This used to use gitlab_sign_in, instead of sign_in, but that is buggy. See
+ # this issue to look into why: https://gitlab.com/gitlab-org/gitlab/-/issues/331851
+ sign_in(user)
gitlab_enable_admin_mode_sign_in(user)
visit admin_root_path
end
it 'disable removes admin mode and redirects to root page' do
- pending_on_combined_menu_flag
-
gitlab_disable_admin_mode
expect(current_path).to eq root_path
- expect(page).to have_link(href: new_admin_session_path)
+
+ open_top_nav
+
+ within_top_nav do
+ expect(page).to have_link(href: new_admin_session_path)
+ end
end
it 'disable shows flash notice' do
- pending_on_combined_menu_flag
-
gitlab_disable_admin_mode
expect(page).to have_selector('.flash-notice')
@@ -38,17 +42,20 @@ RSpec.describe 'Admin Mode Logout', :js do
end
it 'disable removes admin mode and redirects to root page' do
- pending_on_combined_menu_flag
-
gitlab_disable_admin_mode
expect(current_path).to eq root_path
- expect(page).to have_link(href: new_admin_session_path)
+
+ open_top_nav
+
+ within_top_nav do
+ expect(page).to have_link(href: new_admin_session_path)
+ end
end
end
end
- context 'with combined_menu: feature flag on' do
+ context 'with combined_menu feature flag on' do
let(:needs_rewrite_for_combined_menu_flag_on) { true }
before do
@@ -67,8 +74,4 @@ RSpec.describe 'Admin Mode Logout', :js do
it_behaves_like 'combined_menu: feature flag examples'
end
-
- def pending_on_combined_menu_flag
- pending 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587' if needs_rewrite_for_combined_menu_flag_on
- end
end
diff --git a/spec/features/admin/admin_mode_spec.rb b/spec/features/admin/admin_mode_spec.rb
index 4df035b13e8..9fd83f4af6d 100644
--- a/spec/features/admin/admin_mode_spec.rb
+++ b/spec/features/admin/admin_mode_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe 'Admin mode' do
include MobileHelpers
+ include Spec::Support::Helpers::Features::TopNavSpecHelpers
include StubENV
let(:admin) { create(:admin) }
@@ -21,6 +22,7 @@ RSpec.describe 'Admin mode' do
context 'when not in admin mode' do
it 'has no leave admin mode button' do
visit new_admin_session_path
+ open_top_nav
page.within('.navbar-sub-nav') do
expect(page).not_to have_link(href: destroy_admin_session_path)
@@ -28,12 +30,11 @@ RSpec.describe 'Admin mode' do
end
it 'can open pages not in admin scope' do
- pending_on_combined_menu_flag
-
visit new_admin_session_path
+ open_top_nav_projects
- page.within('.navbar-sub-nav') do
- find_all('a', text: 'Projects').first.click
+ within_top_nav do
+ click_link('Your projects')
end
expect(page).to have_current_path(dashboard_projects_path)
@@ -78,71 +79,66 @@ RSpec.describe 'Admin mode' do
end
it 'contains link to leave admin mode' do
- pending_on_combined_menu_flag
+ open_top_nav
- page.within('.navbar-sub-nav') do
+ within_top_nav do
expect(page).to have_link(href: destroy_admin_session_path)
end
end
it 'can leave admin mode using main dashboard link', :js do
- pending_on_combined_menu_flag
+ gitlab_disable_admin_mode
- page.within('.navbar-sub-nav') do
- click_on 'Leave Admin Mode'
+ open_top_nav
+ within_top_nav do
expect(page).to have_link(href: new_admin_session_path)
end
end
it 'can leave admin mode using dropdown menu on smaller screens', :js do
- pending_on_combined_menu_flag
+ skip('pending responsive development under :combined_menu feature flag') if Feature.enabled?(:combined_menu, default_enabled: :yaml)
resize_screen_xs
visit root_dashboard_path
- find('.header-more').click
+ find('.header-more').click unless Feature.enabled?(:combined_menu, default_enabled: :yaml)
- page.within '.navbar-sub-nav' do
- click_on 'Leave Admin Mode'
+ gitlab_disable_admin_mode
- find('.header-more').click
+ open_top_nav
+ find('.header-more').click unless Feature.enabled?(:combined_menu, default_enabled: :yaml)
- expect(page).to have_link(href: new_admin_session_path)
- end
+ expect(page).to have_link(href: new_admin_session_path)
end
it 'can open pages not in admin scope' do
- pending_on_combined_menu_flag
-
- page.within('.navbar-sub-nav') do
- find_all('a', text: 'Projects').first.click
+ open_top_nav_projects
- expect(page).to have_current_path(dashboard_projects_path)
+ within_top_nav do
+ click_link('Your projects')
end
+
+ expect(page).to have_current_path(dashboard_projects_path)
end
context 'nav bar' do
it 'shows admin dashboard links on bigger screen' do
- pending_on_combined_menu_flag
-
visit root_dashboard_path
+ open_top_nav
- page.within '.navbar' do
- expect(page).to have_link(text: 'Admin Area', href: admin_root_path, visible: true)
- expect(page).to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true)
- end
+ link_text = Feature.enabled?(:combined_menu, default_enabled: :yaml) ? 'Admin' : 'Admin Area'
+ expect(page).to have_link(text: link_text, href: admin_root_path, visible: true)
+ expect(page).to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true)
end
it 'relocates admin dashboard links to dropdown list on smaller screen', :js do
- pending_on_combined_menu_flag
+ skip('pending responsive development under :combined_menu feature flag') if Feature.enabled?(:combined_menu, default_enabled: :yaml)
resize_screen_xs
visit root_dashboard_path
- page.within '.navbar' do
- expect(page).not_to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true)
- end
+ expect(page).not_to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true)
find('.header-more').click
@@ -159,11 +155,11 @@ RSpec.describe 'Admin mode' do
end
it 'can leave admin mode', :js do
- pending_on_combined_menu_flag
+ gitlab_disable_admin_mode
- page.within('.navbar-sub-nav') do
- click_on 'Leave Admin Mode'
+ open_top_nav
+ within_top_nav do
expect(page).to have_link(href: new_admin_session_path)
end
end
@@ -179,16 +175,15 @@ RSpec.describe 'Admin mode' do
it 'shows no admin mode buttons in navbar' do
visit admin_root_path
+ open_top_nav
- page.within('.navbar-sub-nav') do
- expect(page).not_to have_link(href: new_admin_session_path)
- expect(page).not_to have_link(href: destroy_admin_session_path)
- end
+ expect(page).not_to have_link(href: new_admin_session_path)
+ expect(page).not_to have_link(href: destroy_admin_session_path)
end
end
end
- context 'with combined_menu: feature flag on' do
+ context 'with combined_menu feature flag on', :js do
let(:needs_rewrite_for_combined_menu_flag_on) { true }
before do
@@ -207,8 +202,4 @@ RSpec.describe 'Admin mode' do
it_behaves_like 'combined_menu: feature flag examples'
end
-
- def pending_on_combined_menu_flag
- pending 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587' if needs_rewrite_for_combined_menu_flag_on
- end
end
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index 4e0dcbdf075..d7a267fec69 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -17,6 +17,10 @@ RSpec.describe "Admin Runners" do
describe "Runners page" do
let(:pipeline) { create(:ci_pipeline) }
+ before do
+ stub_feature_flags(runner_list_view_vue_ui: false)
+ end
+
context "when there are runners" do
it 'has all necessary texts' do
runner = create(:ci_runner, contacted_at: Time.now)
@@ -240,7 +244,7 @@ RSpec.describe "Admin Runners" do
it 'shows the label and does not show the project count' do
visit admin_runners_path
- within "#runner_#{runner.id}" do
+ within "[data-testid='runner-row-#{runner.id}']" do
expect(page).to have_selector '.badge', text: 'group'
expect(page).to have_text 'n/a'
end
@@ -253,7 +257,7 @@ RSpec.describe "Admin Runners" do
visit admin_runners_path
- within "#runner_#{runner.id}" do
+ within "[data-testid='runner-row-#{runner.id}']" do
expect(page).to have_selector '.badge', text: 'shared'
expect(page).to have_text 'n/a'
end
@@ -267,12 +271,36 @@ RSpec.describe "Admin Runners" do
visit admin_runners_path
- within "#runner_#{runner.id}" do
+ 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 }
+
+ before do
+ visit admin_runners_path
+ end
+
+ it 'has a registration token' do
+ 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 }
+
+ before do
+ click_button 'Reset registration token'
+ end
+
+ it 'changes registration token' do
+ expect(page_token).not_to eq token
+ end
+ end
+ end
end
describe "Runner show page" do
@@ -381,28 +409,4 @@ RSpec.describe "Admin Runners" do
end
end
end
-
- describe 'runners registration token' do
- let!(:token) { Gitlab::CurrentSettings.runners_registration_token }
-
- before do
- visit admin_runners_path
- end
-
- it 'has a registration token' do
- expect(page.find('#registration_token')).to have_content(token)
- end
-
- describe 'reload registration token' do
- let(:page_token) { find('#registration_token').text }
-
- before do
- click_button 'Reset registration token'
- end
-
- it 'changes registration token' do
- expect(page_token).not_to eq token
- end
- end
- end
end
diff --git a/spec/features/admin/admin_search_settings_spec.rb b/spec/features/admin/admin_search_settings_spec.rb
index cd61a1db6f3..989cb7cc787 100644
--- a/spec/features/admin/admin_search_settings_spec.rb
+++ b/spec/features/admin/admin_search_settings_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe 'Admin searches application settings', :js do
context 'in appearances page' do
before do
- visit(admin_appearances_path)
+ visit(admin_application_settings_appearances_path)
end
it_behaves_like 'cannot search settings'
diff --git a/spec/features/admin/admin_sees_background_migrations_spec.rb b/spec/features/admin/admin_sees_background_migrations_spec.rb
new file mode 100644
index 00000000000..d848a8352bc
--- /dev/null
+++ b/spec/features/admin/admin_sees_background_migrations_spec.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe "Admin > Admin sees background migrations" do
+ let_it_be(:admin) { create(:admin) }
+
+ let_it_be(:active_migration) { create(:batched_background_migration, table_name: 'active', status: :active) }
+ let_it_be(:failed_migration) { create(:batched_background_migration, table_name: 'failed', status: :failed, total_tuple_count: 100) }
+ let_it_be(:finished_migration) { create(:batched_background_migration, table_name: 'finished', status: :finished) }
+
+ before_all do
+ create(:batched_background_migration_job, batched_migration: failed_migration, batch_size: 30, status: :succeeded)
+ end
+
+ before do
+ sign_in(admin)
+ gitlab_enable_admin_mode_sign_in(admin)
+ end
+
+ it 'can navigate to background migrations' do
+ visit admin_root_path
+
+ within '.nav-sidebar' do
+ link = find_link 'Background Migrations'
+
+ link.click
+
+ expect(page).to have_current_path(admin_background_migrations_path)
+ expect(link).to have_ancestor(:css, 'li.active')
+ end
+ end
+
+ it 'can view queued migrations' do
+ visit admin_background_migrations_path
+
+ within '#content-body' do
+ expect(page).to have_selector('tbody tr', count: 1)
+
+ 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)
+ end
+ end
+
+ it 'can view failed migrations' do
+ visit admin_background_migrations_path
+
+ within '#content-body' do
+ tab = find_link 'Failed'
+ tab.click
+
+ expect(page).to have_current_path(admin_background_migrations_path(tab: 'failed'))
+ expect(tab[:class]).to include('gl-tab-nav-item-active', 'gl-tab-nav-item-active-indigo')
+
+ expect(page).to have_selector('tbody tr', count: 1)
+
+ expect(page).to have_content(failed_migration.job_class_name)
+ expect(page).to have_content(failed_migration.table_name)
+ expect(page).to have_content('30.00%')
+ expect(page).to have_content(failed_migration.status.humanize)
+ end
+ end
+
+ it 'can view finished migrations' do
+ visit admin_background_migrations_path
+
+ within '#content-body' do
+ tab = find_link 'Finished'
+ tab.click
+
+ expect(page).to have_current_path(admin_background_migrations_path(tab: 'finished'))
+ expect(tab[:class]).to include('gl-tab-nav-item-active', 'gl-tab-nav-item-active-indigo')
+
+ expect(page).to have_selector('tbody tr', count: 1)
+
+ expect(page).to have_content(finished_migration.job_class_name)
+ expect(page).to have_content(finished_migration.table_name)
+ expect(page).to have_content('100.00%')
+ expect(page).to have_content(finished_migration.status.humanize)
+ end
+ end
+end
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 0a7113a5559..c289c18126d 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -8,9 +8,11 @@ RSpec.describe 'Admin updates settings' do
include UsageDataHelpers
let(:admin) { create(:admin) }
+ let(:dot_com?) { false }
context 'application setting :admin_mode is enabled', :request_store do
before do
+ allow(Gitlab).to receive(:com?).and_return(dot_com?)
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
@@ -127,6 +129,37 @@ RSpec.describe 'Admin updates settings' do
expect(user_internal_regex['placeholder']).to eq 'Regex pattern'
end
+ context 'Dormant users' do
+ context 'when Gitlab.com' do
+ let(:dot_com?) { true }
+
+ it 'does not expose the setting' do
+ expect(page).to have_no_selector('#application_setting_deactivate_dormant_users')
+ end
+ end
+
+ context 'when not Gitlab.com' do
+ let(:dot_com?) { false }
+
+ it 'change Dormant users' do
+ expect(page).to have_unchecked_field('Deactivate dormant users after 90 days of inactivity')
+ expect(current_settings.deactivate_dormant_users).to be_falsey
+
+ page.within('.as-account-limit') do
+ check 'application_setting_deactivate_dormant_users'
+ click_button 'Save changes'
+ end
+
+ expect(page).to have_content "Application settings saved successfully"
+
+ page.refresh
+
+ expect(current_settings.deactivate_dormant_users).to be_truthy
+ expect(page).to have_checked_field('Deactivate dormant users after 90 days of inactivity')
+ end
+ end
+ end
+
context 'Change Sign-up restrictions' do
context 'Require Admin approval for new signup setting' do
it 'changes the setting', :js do
@@ -315,19 +348,6 @@ RSpec.describe 'Admin updates settings' do
visit integrations_admin_application_settings_path
end
- it 'allows user to dismiss deprecation notice' do
- expect(page).to have_content('Some settings have moved')
-
- click_button 'Dismiss'
- wait_for_requests
-
- expect(page).not_to have_content('Some settings have moved')
-
- visit integrations_admin_application_settings_path
-
- expect(page).not_to have_content('Some settings have moved')
- end
-
it 'shows integrations table' do
expect(page).to have_selector '[data-testid="inactive-integrations-table"]'
end
diff --git a/spec/features/admin/clusters/applications_spec.rb b/spec/features/admin/clusters/applications_spec.rb
deleted file mode 100644
index e083e4fee4c..00000000000
--- a/spec/features/admin/clusters/applications_spec.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_relative '../../../../spec/features/clusters/installing_applications_shared_examples'
-
-RSpec.describe 'Instance-level Cluster Applications', :js do
- include GoogleApi::CloudPlatformHelpers
-
- let(:user) { create(:admin) }
-
- before do
- sign_in(user)
- gitlab_enable_admin_mode_sign_in(user)
- end
-
- describe 'Installing applications' do
- include_examples "installing applications on a cluster" do
- let(:cluster_path) { admin_cluster_path(cluster) }
- let(:cluster_factory_args) { [:instance] }
- end
- end
-end
diff --git a/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb b/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb
new file mode 100644
index 00000000000..6f091d37995
--- /dev/null
+++ b/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User activates the instance-level Mattermost Slash Command integration', :js do
+ include_context 'instance integration activation'
+
+ before do
+ stub_mattermost_setting(enabled: true)
+ visit_instance_integration('Mattermost slash commands')
+ end
+
+ let(:edit_path) { edit_admin_application_settings_integration_path(:mattermost_slash_commands) }
+
+ include_examples 'user activates the Mattermost Slash Command integration'
+end
diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb
index 01341398135..3599658ee56 100644
--- a/spec/features/admin/users/user_spec.rb
+++ b/spec/features/admin/users/user_spec.rb
@@ -356,27 +356,19 @@ RSpec.describe 'Admin::Users::User' do
end
end
- [true, false].each do |vue_admin_users|
- context "with vue_admin_users feature flag set to #{vue_admin_users}", js: vue_admin_users do
- before do
- stub_feature_flags(vue_admin_users: vue_admin_users)
- end
-
- describe 'GET /admin/users' do
- context 'user pending approval' do
- it 'shows user info', :aggregate_failures do
- user = create(:user, :blocked_pending_approval)
+ describe 'GET /admin/users', :js do
+ context 'user pending approval' do
+ it 'shows user info', :aggregate_failures do
+ user = create(:user, :blocked_pending_approval)
- visit admin_users_path
- click_link 'Pending approval'
- click_link user.name
+ visit admin_users_path
+ click_link 'Pending approval'
+ click_link user.name
- 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')
- end
- end
+ 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')
end
end
end
diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb
index d3931373ee3..187fa6fc2a4 100644
--- a/spec/features/admin/users/users_spec.rb
+++ b/spec/features/admin/users/users_spec.rb
@@ -11,294 +11,318 @@ RSpec.describe 'Admin::Users' do
gitlab_enable_admin_mode_sign_in(current_user)
end
- [true, false].each do |vue_admin_users|
- context "with vue_admin_users feature flag set to #{vue_admin_users}", js: vue_admin_users do
- before do
- stub_feature_flags(vue_admin_users: vue_admin_users)
- end
+ describe 'GET /admin/users', :js do
+ before do
+ visit admin_users_path
+ end
- describe 'GET /admin/users' do
- before do
- visit admin_users_path
- end
+ it "is ok" do
+ expect(current_path).to eq(admin_users_path)
+ end
- it "is ok" do
- expect(current_path).to eq(admin_users_path)
- end
+ it "has users list" do
+ current_user.reload
- it "has users list" do
- current_user.reload
+ expect(page).to have_content(current_user.email)
+ expect(page).to have_content(current_user.name)
+ expect(page).to have_content(current_user.created_at.strftime('%e %b, %Y'))
+ expect(page).to have_content(user.email)
+ expect(page).to have_content(user.name)
+ expect(page).to have_content('Projects')
- expect(page).to have_content(current_user.email)
- expect(page).to have_content(current_user.name)
- expect(page).to have_content(current_user.created_at.strftime('%e %b, %Y'))
- expect(page).to have_content(user.email)
- expect(page).to have_content(user.name)
- expect(page).to have_content('Projects')
+ click_user_dropdown_toggle(user.id)
- 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
- 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
+ it 'clicking edit user takes us to edit page', :aggregate_failures do
+ page.within("[data-testid='user-actions-#{user.id}']") do
+ click_link 'Edit'
+ end
- it 'clicking edit user takes us to edit page', :aggregate_failures do
- page.within("[data-testid='user-actions-#{user.id}']") do
- click_link 'Edit'
- end
+ expect(page).to have_content('Name')
+ expect(page).to have_content('Password')
+ end
- expect(page).to have_content('Name')
- expect(page).to have_content('Password')
- end
+ describe 'view extra user information' do
+ it 'shows the user popover on hover', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/11290' do
+ expect(page).not_to have_selector('#__BV_popover_1__')
- describe 'view extra user information' do
- it 'shows the user popover on hover', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/11290' do
- expect(page).not_to have_selector('#__BV_popover_1__')
+ first_user_link = page.first('.js-user-link')
+ first_user_link.hover
- first_user_link = page.first('.js-user-link')
- first_user_link.hover
+ expect(page).to have_selector('#__BV_popover_1__')
+ end
+ end
- expect(page).to have_selector('#__BV_popover_1__')
- end
- end
+ context 'user project count' do
+ before do
+ project = create(:project)
+ project.add_maintainer(current_user)
+ end
- context 'user project count' do
- before do
- project = create(:project)
- project.add_maintainer(current_user)
- end
+ it 'displays count of users projects' do
+ visit admin_users_path
- it 'displays count of users projects' do
- visit admin_users_path
+ expect(page.find("[data-testid='user-project-count-#{current_user.id}']").text).to eq("1")
+ end
+ end
+
+ describe 'tabs' do
+ it 'has multiple tabs to filter users' do
+ expect(page).to have_link('Active', href: admin_users_path)
+ expect(page).to have_link('Admins', href: admin_users_path(filter: 'admins'))
+ expect(page).to have_link('2FA Enabled', href: admin_users_path(filter: 'two_factor_enabled'))
+ expect(page).to have_link('2FA Disabled', href: admin_users_path(filter: 'two_factor_disabled'))
+ expect(page).to have_link('External', href: admin_users_path(filter: 'external'))
+ expect(page).to have_link('Blocked', href: admin_users_path(filter: 'blocked'))
+ expect(page).to have_link('Deactivated', href: admin_users_path(filter: 'deactivated'))
+ expect(page).to have_link('Without projects', href: admin_users_path(filter: 'wop'))
+ end
- expect(page.find("[data-testid='user-project-count-#{current_user.id}']").text).to eq("1")
- end
+ context '`Pending approval` tab' do
+ before do
+ visit admin_users_path
end
- describe 'tabs' do
- it 'has multiple tabs to filter users' do
- expect(page).to have_link('Active', href: admin_users_path)
- expect(page).to have_link('Admins', href: admin_users_path(filter: 'admins'))
- expect(page).to have_link('2FA Enabled', href: admin_users_path(filter: 'two_factor_enabled'))
- expect(page).to have_link('2FA Disabled', href: admin_users_path(filter: 'two_factor_disabled'))
- expect(page).to have_link('External', href: admin_users_path(filter: 'external'))
- expect(page).to have_link('Blocked', href: admin_users_path(filter: 'blocked'))
- expect(page).to have_link('Banned', href: admin_users_path(filter: 'banned'))
- expect(page).to have_link('Deactivated', href: admin_users_path(filter: 'deactivated'))
- expect(page).to have_link('Without projects', href: admin_users_path(filter: 'wop'))
- end
-
- context '`Pending approval` tab' do
- before do
- visit admin_users_path
- end
-
- it 'shows the `Pending approval` tab' do
- expect(page).to have_link('Pending approval', href: admin_users_path(filter: 'blocked_pending_approval'))
- end
- end
+ it 'shows the `Pending approval` tab' do
+ expect(page).to have_link('Pending approval', href: admin_users_path(filter: 'blocked_pending_approval'))
end
+ end
+ end
- describe 'search and sort' do
- before_all do
- create(:user, name: 'Foo Bar', last_activity_on: 3.days.ago)
- create(:user, name: 'Foo Baz', last_activity_on: 2.days.ago)
- create(:user, name: 'Dmitriy')
- end
+ describe 'search and sort' do
+ before_all do
+ create(:user, name: 'Foo Bar', last_activity_on: 3.days.ago)
+ create(:user, name: 'Foo Baz', last_activity_on: 2.days.ago)
+ create(:user, name: 'Dmitriy')
+ end
- it 'searches users by name' do
- visit admin_users_path(search_query: 'Foo')
+ it 'searches users by name' do
+ visit admin_users_path(search_query: 'Foo')
- expect(page).to have_content('Foo Bar')
- expect(page).to have_content('Foo Baz')
- expect(page).not_to have_content('Dmitriy')
- end
+ expect(page).to have_content('Foo Bar')
+ expect(page).to have_content('Foo Baz')
+ expect(page).not_to have_content('Dmitriy')
+ end
- it 'sorts users by name' do
- visit admin_users_path
+ it 'sorts users by name' do
+ visit admin_users_path
- sort_by('Name')
+ sort_by('Name')
- expect(first_row.text).to include('Dmitriy')
- expect(second_row.text).to include('Foo Bar')
- end
+ expect(first_row.text).to include('Dmitriy')
+ expect(second_row.text).to include('Foo Bar')
+ end
- it 'sorts search results only' do
- visit admin_users_path(search_query: 'Foo')
+ it 'sorts search results only' do
+ visit admin_users_path(search_query: 'Foo')
- sort_by('Name')
- expect(page).not_to have_content('Dmitriy')
- expect(first_row.text).to include('Foo Bar')
- expect(second_row.text).to include('Foo Baz')
- end
+ sort_by('Name')
+ expect(page).not_to have_content('Dmitriy')
+ expect(first_row.text).to include('Foo Bar')
+ expect(second_row.text).to include('Foo Baz')
+ end
- it 'searches with respect of sorting' do
- visit admin_users_path(sort: 'Name')
+ it 'searches with respect of sorting' do
+ visit admin_users_path(sort: 'Name')
- fill_in :search_query, with: 'Foo'
- click_button('Search users')
+ fill_in :search_query, with: 'Foo'
+ click_button('Search users')
- expect(first_row.text).to include('Foo Bar')
- expect(second_row.text).to include('Foo Baz')
- end
+ expect(first_row.text).to include('Foo Bar')
+ expect(second_row.text).to include('Foo Baz')
+ end
- it 'sorts users by recent last activity' do
- visit admin_users_path(search_query: 'Foo')
+ it 'sorts users by recent last activity' do
+ visit admin_users_path(search_query: 'Foo')
- sort_by('Recent last activity')
+ sort_by('Recent last activity')
- expect(first_row.text).to include('Foo Baz')
- expect(second_row.text).to include('Foo Bar')
- end
+ expect(first_row.text).to include('Foo Baz')
+ expect(second_row.text).to include('Foo Bar')
+ end
- it 'sorts users by oldest last activity' do
- visit admin_users_path(search_query: 'Foo')
+ it 'sorts users by oldest last activity' do
+ visit admin_users_path(search_query: 'Foo')
- sort_by('Oldest last activity')
+ sort_by('Oldest last activity')
- expect(first_row.text).to include('Foo Bar')
- expect(second_row.text).to include('Foo Baz')
- end
+ expect(first_row.text).to include('Foo Bar')
+ expect(second_row.text).to include('Foo Baz')
+ end
+ end
+
+ describe 'Two-factor Authentication filters' do
+ it 'counts users who have enabled 2FA' do
+ create(:user, :two_factor)
+
+ visit admin_users_path
+
+ page.within('.filter-two-factor-enabled small') do
+ expect(page).to have_content('1')
end
+ end
- describe 'Two-factor Authentication filters' do
- it 'counts users who have enabled 2FA' do
- create(:user, :two_factor)
+ it 'filters by users who have enabled 2FA' do
+ user = create(:user, :two_factor)
- visit admin_users_path
+ visit admin_users_path
+ click_link '2FA Enabled'
- page.within('.filter-two-factor-enabled small') do
- expect(page).to have_content('1')
- end
- end
+ expect(page).to have_content(user.email)
+ end
- it 'filters by users who have enabled 2FA' do
- user = create(:user, :two_factor)
+ it 'counts users who have not enabled 2FA' do
+ visit admin_users_path
- visit admin_users_path
- click_link '2FA Enabled'
+ page.within('.filter-two-factor-disabled small') do
+ expect(page).to have_content('2') # Including admin
+ end
+ end
- expect(page).to have_content(user.email)
- end
+ it 'filters by users who have not enabled 2FA' do
+ visit admin_users_path
+ click_link '2FA Disabled'
- it 'counts users who have not enabled 2FA' do
- visit admin_users_path
+ expect(page).to have_content(user.email)
+ end
+ end
- page.within('.filter-two-factor-disabled small') do
- expect(page).to have_content('2') # Including admin
- end
- end
+ describe 'Pending approval filter' do
+ it 'counts users who are pending approval' do
+ create_list(:user, 2, :blocked_pending_approval)
- it 'filters by users who have not enabled 2FA' do
- visit admin_users_path
- click_link '2FA Disabled'
+ visit admin_users_path
- expect(page).to have_content(user.email)
- end
+ page.within('.filter-blocked-pending-approval small') do
+ expect(page).to have_content('2')
end
+ end
- describe 'Pending approval filter' do
- it 'counts users who are pending approval' do
- create_list(:user, 2, :blocked_pending_approval)
+ it 'filters by users who are pending approval' do
+ user = create(:user, :blocked_pending_approval)
- visit admin_users_path
+ visit admin_users_path
+ click_link 'Pending approval'
- page.within('.filter-blocked-pending-approval small') do
- expect(page).to have_content('2')
- end
- end
+ expect(page).to have_content(user.email)
+ end
+ end
- it 'filters by users who are pending approval' do
- user = create(:user, :blocked_pending_approval)
+ context 'when blocking/unblocking a user' do
+ it 'shows confirmation and allows blocking and unblocking', :js do
+ expect(page).to have_content(user.email)
- visit admin_users_path
- click_link 'Pending approval'
+ click_action_in_user_dropdown(user.id, 'Block')
- expect(page).to have_content(user.email)
- end
- end
+ wait_for_requests
- context 'when blocking/unblocking a user' do
- it 'shows confirmation and allows blocking and unblocking', :js do
- expect(page).to have_content(user.email)
+ expect(page).to have_content('Block user')
+ expect(page).to have_content('Blocking user has the following effects')
+ expect(page).to have_content('User will not be able to login')
+ expect(page).to have_content('Owned groups will be left')
- click_action_in_user_dropdown(user.id, 'Block')
+ find('.modal-footer button', text: 'Block').click
- wait_for_requests
+ wait_for_requests
- expect(page).to have_content('Block user')
- expect(page).to have_content('Blocking user has the following effects')
- expect(page).to have_content('User will not be able to login')
- expect(page).to have_content('Owned groups will be left')
+ expect(page).to have_content('Successfully blocked')
+ expect(page).not_to have_content(user.email)
- find('.modal-footer button', text: 'Block').click
+ click_link 'Blocked'
- wait_for_requests
+ wait_for_requests
- expect(page).to have_content('Successfully blocked')
- expect(page).not_to have_content(user.email)
+ expect(page).to have_content(user.email)
- click_link 'Blocked'
+ click_action_in_user_dropdown(user.id, 'Unblock')
- wait_for_requests
+ expect(page).to have_content('Unblock user')
+ expect(page).to have_content('You can always block their account again if needed.')
- expect(page).to have_content(user.email)
+ find('.modal-footer button', text: 'Unblock').click
- click_action_in_user_dropdown(user.id, 'Unblock')
+ wait_for_requests
- expect(page).to have_content('Unblock user')
- expect(page).to have_content('You can always block their account again if needed.')
+ expect(page).to have_content('Successfully unblocked')
+ expect(page).not_to have_content(user.email)
+ end
+ end
- find('.modal-footer button', text: 'Unblock').click
+ context 'when deactivating/re-activating a user' do
+ it 'shows confirmation and allows deactivating and re-activating', :js do
+ expect(page).to have_content(user.email)
- wait_for_requests
+ click_action_in_user_dropdown(user.id, 'Deactivate')
- expect(page).to have_content('Successfully unblocked')
- expect(page).not_to have_content(user.email)
- end
- end
+ expect(page).to have_content('Deactivate user')
+ expect(page).to have_content('Deactivating a user has the following effects')
+ expect(page).to have_content('The user will be logged out')
+ expect(page).to have_content('Personal projects, group and user history will be left intact')
- context 'when deactivating/re-activating a user' do
- it 'shows confirmation and allows deactivating and re-activating', :js do
- expect(page).to have_content(user.email)
+ find('.modal-footer button', text: 'Deactivate').click
- click_action_in_user_dropdown(user.id, 'Deactivate')
+ wait_for_requests
- expect(page).to have_content('Deactivate user')
- expect(page).to have_content('Deactivating a user has the following effects')
- expect(page).to have_content('The user will be logged out')
- expect(page).to have_content('Personal projects, group and user history will be left intact')
+ expect(page).to have_content('Successfully deactivated')
+ expect(page).not_to have_content(user.email)
- find('.modal-footer button', text: 'Deactivate').click
+ click_link 'Deactivated'
- wait_for_requests
+ wait_for_requests
- expect(page).to have_content('Successfully deactivated')
- expect(page).not_to have_content(user.email)
+ expect(page).to have_content(user.email)
- click_link 'Deactivated'
+ click_action_in_user_dropdown(user.id, 'Activate')
- wait_for_requests
+ expect(page).to have_content('Activate user')
+ expect(page).to have_content('You can always deactivate their account again if needed.')
- expect(page).to have_content(user.email)
+ find('.modal-footer button', text: 'Activate').click
- click_action_in_user_dropdown(user.id, 'Activate')
+ wait_for_requests
- expect(page).to have_content('Activate user')
- expect(page).to have_content('You can always deactivate their account again if needed.')
+ expect(page).to have_content('Successfully activated')
+ expect(page).not_to have_content(user.email)
+ end
+ end
- find('.modal-footer button', text: 'Activate').click
+ describe 'internal users' do
+ context 'when showing a `Ghost User`' do
+ let_it_be(:ghost_user) { create(:user, :ghost) }
- wait_for_requests
+ it 'does not render actions dropdown' do
+ expect(page).not_to have_css("[data-testid='user-actions-#{ghost_user.id}'] [data-testid='dropdown-toggle']")
+ end
+ end
+
+ context 'when showing a `Bot User`' do
+ let_it_be(:bot_user) { create(:user, user_type: :alert_bot) }
- expect(page).to have_content('Successfully activated')
- expect(page).not_to have_content(user.email)
- end
+ it 'does not render actions dropdown' do
+ expect(page).not_to have_css("[data-testid='user-actions-#{bot_user.id}'] [data-testid='dropdown-toggle']")
end
end
end
+
+ context 'user group count', :js do
+ before do
+ group = create(:group)
+ group.add_developer(current_user)
+ project = create(:project, group: create(:group))
+ project.add_reporter(current_user)
+ end
+
+ it 'displays count of the users authorized groups' do
+ wait_for_requests
+
+ expect(page.find("[data-testid='user-group-count-#{current_user.id}']").text).to eq("2")
+ end
+ end
end
describe 'GET /admin/users/new' do
@@ -548,32 +572,6 @@ RSpec.describe 'Admin::Users' do
end
end
- # TODO: Move to main GET /admin/users block once feature flag is removed. Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/290737
- context 'with vue_admin_users feature flag enabled', :js do
- before do
- stub_feature_flags(vue_admin_users: true)
- end
-
- describe 'GET /admin/users' do
- context 'user group count', :js do
- before do
- group = create(:group)
- group.add_developer(current_user)
- project = create(:project, group: create(:group))
- project.add_reporter(current_user)
- end
-
- it 'displays count of the users authorized groups' do
- visit admin_users_path
-
- wait_for_requests
-
- expect(page.find("[data-testid='user-group-count-#{current_user.id}']").text).to eq("2")
- end
- end
- end
- end
-
def click_user_dropdown_toggle(user_id)
page.within("[data-testid='user-actions-#{user_id}']") do
find("[data-testid='dropdown-toggle']").click
diff --git a/spec/features/alert_management/alert_management_list_spec.rb b/spec/features/alert_management/alert_management_list_spec.rb
index 44ed2f3d60c..aeaadacb38d 100644
--- a/spec/features/alert_management/alert_management_list_spec.rb
+++ b/spec/features/alert_management/alert_management_list_spec.rb
@@ -55,4 +55,28 @@ RSpec.describe 'Alert Management index', :js do
it_behaves_like 'alert page with title, filtered search, and table'
end
end
+
+ describe 'managed_alerts_deprecation feature flag' do
+ subject { page }
+
+ before do
+ stub_feature_flags(managed_alerts_deprecation: feature_flag_value)
+ sign_in(developer)
+
+ visit project_alert_management_index_path(project)
+ wait_for_requests
+ end
+
+ context 'feature flag on' do
+ let(:feature_flag_value) { true }
+
+ it { is_expected.to have_pushed_frontend_feature_flags(managedAlertsDeprecation: true) }
+ end
+
+ context 'feature flag off' do
+ let(:feature_flag_value) { false }
+
+ it { is_expected.to have_pushed_frontend_feature_flags(managedAlertsDeprecation: false) }
+ end
+ end
end
diff --git a/spec/features/alerts_settings/user_views_alerts_settings_spec.rb b/spec/features/alerts_settings/user_views_alerts_settings_spec.rb
index 6675abd6b42..60f2f776595 100644
--- a/spec/features/alerts_settings/user_views_alerts_settings_spec.rb
+++ b/spec/features/alerts_settings/user_views_alerts_settings_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe 'Alert integrations settings form', :js do
it 'shows the alerts setting form title' do
page.within('#js-alert-management-settings') do
- expect(find('h4')).to have_content('Alert integrations')
+ expect(find('h4')).to have_content('Alerts')
end
end
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index 5d9bb8d8087..02bb7574fb0 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -147,14 +147,23 @@ RSpec.describe 'Project issue boards', :js do
end
it 'infinite scrolls list' do
- create_list(:labeled_issue, 50, project: project, labels: [planning])
+ create_list(:labeled_issue, 30, project: project, labels: [planning])
visit_project_board_path_without_query_limit(project, board)
page.within(find('.board:nth-child(2)')) do
- expect(page.find('.board-header')).to have_content('58')
+ expect(page.find('.board-header')).to have_content('38')
+ expect(page).to have_selector('.board-card', count: 10)
+ expect(page).to have_content('Showing 10 of 38 issues')
+
+ find('.board .board-list')
+
+ inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
+ evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
+ end
+
expect(page).to have_selector('.board-card', count: 20)
- expect(page).to have_content('Showing 20 of 58 issues')
+ expect(page).to have_content('Showing 20 of 38 issues')
find('.board .board-list')
@@ -162,8 +171,8 @@ RSpec.describe 'Project issue boards', :js do
evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
end
- expect(page).to have_selector('.board-card', count: 40)
- expect(page).to have_content('Showing 40 of 58 issues')
+ expect(page).to have_selector('.board-card', count: 30)
+ expect(page).to have_content('Showing 30 of 38 issues')
find('.board .board-list')
@@ -171,7 +180,7 @@ RSpec.describe 'Project issue boards', :js do
evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
end
- expect(page).to have_selector('.board-card', count: 58)
+ expect(page).to have_selector('.board-card', count: 38)
expect(page).to have_content('Showing all issues')
end
end
@@ -464,7 +473,7 @@ RSpec.describe 'Project issue boards', :js do
end
it 'infinite scrolls list with label filter' do
- create_list(:labeled_issue, 50, project: project, labels: [planning, testing])
+ create_list(:labeled_issue, 30, project: project, labels: [planning, testing])
set_filter("label", testing.title)
click_filter_link(testing.title)
@@ -475,9 +484,18 @@ RSpec.describe 'Project issue boards', :js do
wait_for_requests
page.within(find('.board:nth-child(2)')) do
- expect(page.find('.board-header')).to have_content('51')
+ expect(page.find('.board-header')).to have_content('31')
+ expect(page).to have_selector('.board-card', count: 10)
+ expect(page).to have_content('Showing 10 of 31 issues')
+
+ find('.board .board-list')
+
+ inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
+ evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
+ end
+
expect(page).to have_selector('.board-card', count: 20)
- expect(page).to have_content('Showing 20 of 51 issues')
+ expect(page).to have_content('Showing 20 of 31 issues')
find('.board .board-list')
@@ -485,15 +503,15 @@ RSpec.describe 'Project issue boards', :js do
evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
end
- expect(page).to have_selector('.board-card', count: 40)
- expect(page).to have_content('Showing 40 of 51 issues')
+ expect(page).to have_selector('.board-card', count: 30)
+ expect(page).to have_content('Showing 30 of 31 issues')
find('.board .board-list')
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
evaluate_script("document.querySelectorAll('.board .board-list')[1].scrollTop = document.querySelectorAll('.board .board-list')[1].scrollHeight")
end
- expect(page).to have_selector('.board-card', count: 51)
+ expect(page).to have_selector('.board-card', count: 31)
expect(page).to have_content('Showing all issues')
end
end
diff --git a/spec/features/boards/issue_ordering_spec.rb b/spec/features/boards/issue_ordering_spec.rb
index 87d29eed68d..57f2bf26752 100644
--- a/spec/features/boards/issue_ordering_spec.rb
+++ b/spec/features/boards/issue_ordering_spec.rb
@@ -157,7 +157,7 @@ RSpec.describe 'Issue Boards', :js do
end
it 'moves to bottom of another list' do
- drag(list_from_index: 1, list_to_index: 2, to_index: 2, duration: 1020)
+ drag(list_from_index: 1, list_to_index: 2, to_index: 3, duration: 1020)
wait_for_requests
diff --git a/spec/features/boards/multi_select_spec.rb b/spec/features/boards/multi_select_spec.rb
index ca322355b8f..057464326fa 100644
--- a/spec/features/boards/multi_select_spec.rb
+++ b/spec/features/boards/multi_select_spec.rb
@@ -41,9 +41,9 @@ RSpec.describe 'Multi Select Issue', :js do
before do
project.add_maintainer(user)
- # multi-drag disabled with feature flag for now
+ # Multi select drag&drop support is temporarily disabled
# https://gitlab.com/gitlab-org/gitlab/-/issues/289797
- stub_feature_flags(graphql_board_lists: false)
+ stub_feature_flags(graphql_board_lists: false, board_multi_select: project)
sign_in(user)
end
diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb
index 129d03d17f3..e055e8092d4 100644
--- a/spec/features/boards/new_issue_spec.rb
+++ b/spec/features/boards/new_issue_spec.rb
@@ -120,6 +120,32 @@ RSpec.describe 'Issue Boards new issue', :js do
expect(page).to have_content 'Label 1'
end
end
+
+ it 'allows creating an issue in newly created list' do
+ click_button 'Create list'
+ wait_for_all_requests
+
+ click_button 'Select a label'
+ find('label', text: label.title).click
+ click_button 'Add to board'
+
+ wait_for_all_requests
+
+ page.within('.board:nth-child(2)') do
+ click_button('New issue')
+
+ page.within(first('.board-new-issue-form')) do
+ find('.form-control').set('new issue')
+ click_button 'Create issue'
+ end
+
+ wait_for_all_requests
+
+ page.within('.board-card') do
+ expect(page).to have_content 'new issue'
+ end
+ end
+ end
end
context 'unauthorized user' do
@@ -128,8 +154,8 @@ RSpec.describe 'Issue Boards new issue', :js do
wait_for_requests
end
- it 'displays new issue button in open list' do
- expect(first('.board')).to have_button('New issue', count: 1)
+ it 'does not display new issue button in open list' do
+ expect(first('.board')).not_to have_button('New issue')
end
it 'does not display new issue button in label list' do
@@ -166,8 +192,8 @@ RSpec.describe 'Issue Boards new issue', :js do
context 'when backlog list already exists' do
let_it_be(:backlog_list) { create(:backlog_list, board: group_board) }
- it 'displays new issue button in open list' do
- expect(first('.board')).to have_button('New issue', count: 1)
+ it 'does not display new issue button in open list' do
+ expect(first('.board')).not_to have_button('New issue')
end
it 'does not display new issue button in label list' do
diff --git a/spec/features/boards/sidebar_assignee_spec.rb b/spec/features/boards/sidebar_assignee_spec.rb
index d6adefea6e3..63553cec89b 100644
--- a/spec/features/boards/sidebar_assignee_spec.rb
+++ b/spec/features/boards/sidebar_assignee_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Project issue boards sidebar assignee', :js do
+RSpec.describe 'Project issue boards sidebar assignee', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/332230' do
include BoardHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/features/boards/sidebar_milestones_spec.rb b/spec/features/boards/sidebar_milestones_spec.rb
index 54182781a30..be7435263b1 100644
--- a/spec/features/boards/sidebar_milestones_spec.rb
+++ b/spec/features/boards/sidebar_milestones_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe 'Project issue boards sidebar milestones', :js do
wait_for_requests
- page.within('.value') do
+ page.within('[data-testid="select-milestone"]') do
expect(page).to have_content(milestone.title)
end
end
@@ -56,7 +56,7 @@ RSpec.describe 'Project issue boards sidebar milestones', :js do
wait_for_requests
- page.within('.value') do
+ page.within('[data-testid="select-milestone"]') do
expect(page).not_to have_content(milestone.title)
end
end
diff --git a/spec/features/calendar_spec.rb b/spec/features/calendar_spec.rb
index 1281d890ef7..21da92c9f43 100644
--- a/spec/features/calendar_spec.rb
+++ b/spec/features/calendar_spec.rb
@@ -15,10 +15,9 @@ RSpec.describe 'Contributions Calendar', :js do
issue_title = 'Bug in old browser'
issue_params = { title: issue_title }
- def get_cell_color_selector(contributions)
- activity_colors = ["#ededed", "rgb(172, 213, 242)", "rgb(127, 168, 201)", "rgb(82, 123, 160)", "rgb(37, 78, 119)"]
+ def get_cell_level_selector(contributions)
# We currently don't actually test the cases with contributions >= 20
- activity_colors_index =
+ activity_level_index =
if contributions > 0 && contributions < 10
1
elsif contributions >= 10 && contributions < 20
@@ -31,7 +30,7 @@ RSpec.describe 'Contributions Calendar', :js do
0
end
- ".user-contrib-cell[fill='#{activity_colors[activity_colors_index]}']"
+ ".user-contrib-cell:not(.contrib-legend)[data-level='#{activity_level_index}']"
end
def get_cell_date_selector(contributions, date)
@@ -42,7 +41,7 @@ RSpec.describe 'Contributions Calendar', :js do
"#{contributions} #{'contribution'.pluralize(contributions)}"
end
- "#{get_cell_color_selector(contributions)}[title='#{contribution_text}<br /><span class=\"gl-text-gray-300\">#{date}</span>']"
+ "#{get_cell_level_selector(contributions)}[title='#{contribution_text}<br /><span class=\"gl-text-gray-300\">#{date}</span>']"
end
def push_code_contribution
@@ -137,7 +136,7 @@ RSpec.describe 'Contributions Calendar', :js do
include_context 'visit user page'
it 'displays calendar activity square for 1 contribution', :sidekiq_might_not_need_inline do
- expect(find('#js-overview')).to have_selector(get_cell_color_selector(contribution_count), count: 1)
+ expect(find('#js-overview')).to have_selector(get_cell_level_selector(contribution_count), count: 1)
today = Date.today.strftime(date_format)
expect(find('#js-overview')).to have_selector(get_cell_date_selector(contribution_count, today), count: 1)
@@ -187,7 +186,7 @@ RSpec.describe 'Contributions Calendar', :js do
include_context 'visit user page'
it 'displays calendar activity squares for both days', :sidekiq_might_not_need_inline do
- expect(find('#js-overview')).to have_selector(get_cell_color_selector(1), count: 2)
+ expect(find('#js-overview')).to have_selector(get_cell_level_selector(1), count: 2)
end
it 'displays calendar activity square for yesterday', :sidekiq_might_not_need_inline do
diff --git a/spec/features/clusters/cluster_detail_page_spec.rb b/spec/features/clusters/cluster_detail_page_spec.rb
index 84a18a45d35..cba8aaef1ef 100644
--- a/spec/features/clusters/cluster_detail_page_spec.rb
+++ b/spec/features/clusters/cluster_detail_page_spec.rb
@@ -31,30 +31,6 @@ RSpec.describe 'Clusterable > Show page' do
expect(page).to have_content('Kubernetes cluster was successfully updated.')
end
- context 'when there is a cluster with ingress and external ip', :js do
- before do
- cluster.create_application_ingress!(external_ip: '192.168.1.100')
-
- visit cluster_path
- end
-
- it 'shows help text with the domain as an alternative to custom domain', :js do
- within '.js-cluster-details-form' do
- expect(find(cluster_ingress_help_text_selector).text).to include('192.168.1.100')
- end
- end
- end
-
- context 'when there is no ingress' do
- it 'alternative to custom domain is not shown' do
- visit cluster_path
-
- within '.js-cluster-details-form' do
- expect(page).not_to have_selector(cluster_ingress_help_text_selector)
- end
- end
- end
-
it 'does not show the environments tab' do
visit cluster_path
diff --git a/spec/features/clusters/cluster_health_dashboard_spec.rb b/spec/features/clusters/cluster_health_dashboard_spec.rb
index 862f34768c4..20c07f4d6ac 100644
--- a/spec/features/clusters/cluster_health_dashboard_spec.rb
+++ b/spec/features/clusters/cluster_health_dashboard_spec.rb
@@ -27,8 +27,8 @@ RSpec.describe 'Cluster Health board', :js, :kubeclient, :use_clean_rails_memory
expect(page).to have_css('.cluster-health-graphs')
end
- context 'no prometheus installed' do
- it 'shows install prometheus message' do
+ context 'no prometheus available' do
+ it 'shows enable Prometheus message' do
visit cluster_path
click_link 'Health'
@@ -37,9 +37,9 @@ RSpec.describe 'Cluster Health board', :js, :kubeclient, :use_clean_rails_memory
end
end
- context 'when there is cluster with installed prometheus' do
+ context 'when there is cluster with enabled prometheus' do
before do
- create(:clusters_applications_prometheus, :installed, cluster: cluster)
+ create(:clusters_integrations_prometheus, enabled: true, cluster: cluster)
stub_kubeclient_discover(cluster.platform.api_url)
end
@@ -82,12 +82,12 @@ RSpec.describe 'Cluster Health board', :js, :kubeclient, :use_clean_rails_memory
def stub_empty_response
stub_prometheus_request(/prometheus-prometheus-server/, status: 204, body: {})
- stub_prometheus_request(/prometheus\/api\/v1/, status: 204, body: {})
+ stub_prometheus_request(%r{prometheus/api/v1}, status: 204, body: {})
end
def stub_connected
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
end
end
diff --git a/spec/features/clusters/installing_applications_shared_examples.rb b/spec/features/clusters/installing_applications_shared_examples.rb
deleted file mode 100644
index c422aa2be72..00000000000
--- a/spec/features/clusters/installing_applications_shared_examples.rb
+++ /dev/null
@@ -1,252 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.shared_examples "installing applications for a cluster" do
- before do
- # Reduce interval from 10 seconds which is too long for an automated test
- stub_const("#{Clusters::ClustersController}::STATUS_POLLING_INTERVAL", 500)
-
- visit cluster_path
- end
-
- context 'when cluster is being created' do
- let(:cluster) { create(:cluster, :providing_by_gcp, *cluster_factory_args) }
-
- it 'user is unable to install applications' do
- expect(page).not_to have_text('Helm')
- expect(page).not_to have_text('Install')
- end
- end
-
- context 'when cluster is created' do
- let(:cluster) { create(:cluster, :provided_by_gcp, *cluster_factory_args) }
-
- before do
- page.within('.js-edit-cluster-form') do
- click_link 'Applications'
- end
- end
-
- it 'user can install applications' do
- wait_for_requests
-
- application_row = '.js-cluster-application-row-ingress'
-
- page.within(application_row) do
- expect(page).not_to have_css('.js-cluster-application-install-button[disabled]')
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Install')
- end
- end
-
- it 'does not show the Helm application' do
- expect(page).not_to have_selector(:css, '.js-cluster-application-row-helm')
- end
-
- context 'when user installs Knative' do
- context 'on an abac cluster' do
- let(:cluster) { create(:cluster, :provided_by_gcp, :rbac_disabled, *cluster_factory_args) }
-
- it 'shows info block and not be installable' do
- page.within('.js-cluster-application-row-knative') do
- expect(page).to have_css('.rbac-notice')
- expect(page.find(:css, '.js-cluster-application-install-button')['disabled']).to eq('true')
- end
- end
- end
-
- context 'on an rbac cluster' do
- let(:cluster) { create(:cluster, :provided_by_gcp, *cluster_factory_args) }
-
- it 'does not show callout block and be installable' do
- page.within('.js-cluster-application-row-knative') do
- expect(page).not_to have_css('p', text: 'You must have an RBAC-enabled cluster', visible: :all)
- expect(page).to have_css('.js-cluster-application-install-button:not([disabled])')
- end
- end
-
- describe 'when user clicks install button' do
- before do
- allow(ClusterInstallAppWorker).to receive(:perform_async)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_in)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_async)
-
- page.within('.js-cluster-application-row-knative') do
- expect(page).to have_css('.js-cluster-application-install-button:not([disabled])')
-
- page.find('.js-knative-domainname').set("domain.example.org")
-
- click_button 'Install'
-
- wait_for_requests
-
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_knative.make_installing!
- Clusters::Cluster.last.application_knative.make_installed!
- Clusters::Cluster.last.application_knative.update_attribute(:external_ip, '127.0.0.1')
- end
- end
-
- it 'shows status transition' do
- page.within('.js-cluster-application-row-knative') do
- expect(page).to have_field('Knative Domain Name:', with: 'domain.example.org')
- expect(page).to have_css('.js-cluster-application-uninstall-button', exact_text: 'Uninstall')
- end
-
- expect(page).to have_content('Knative was successfully installed on your Kubernetes cluster')
- expect(page).to have_css('.js-knative-save-domain-button'), exact_text: 'Save changes'
- end
-
- it 'can then update the domain' do
- page.within('.js-cluster-application-row-knative') do
- expect(ClusterPatchAppWorker).to receive(:perform_async)
-
- expect(page).to have_field('Knative Domain Name:', with: 'domain.example.org')
-
- page.find('.js-knative-domainname').set("new.domain.example.org")
-
- click_button 'Save changes'
-
- wait_for_requests
-
- expect(page).to have_field('Knative Domain Name:', with: 'new.domain.example.org')
- end
- end
- end
- end
- end
-
- context 'when user installs Cert Manager' do
- before do
- allow(ClusterInstallAppWorker).to receive(:perform_async)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_in)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_async)
- end
-
- it 'shows status transition' do
- page.within('.js-cluster-application-row-cert_manager') do
- click_button 'Install'
- wait_for_requests
-
- expect(page).to have_field('Issuer Email', with: cluster.user.email)
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_cert_manager.make_installing!
-
- expect(page).to have_field('Issuer Email', with: cluster.user.email)
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_cert_manager.make_installed!
-
- expect(page).to have_field('Issuer Email', with: cluster.user.email)
- expect(page).to have_css('.js-cluster-application-uninstall-button', exact_text: 'Uninstall')
- end
-
- expect(page).to have_content('Cert-Manager was successfully installed on your Kubernetes cluster')
- end
-
- it 'installs with custom email' do
- custom_email = 'new_email@example.org'
-
- page.within('.js-cluster-application-row-cert_manager') do
- # Wait for the polling to finish
- wait_for_requests
-
- page.find('.js-email').set(custom_email)
- click_button 'Install'
- wait_for_requests
-
- expect(page).to have_field('Issuer Email', with: custom_email)
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_cert_manager.make_installing!
-
- expect(page).to have_field('Issuer Email', with: custom_email)
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_cert_manager.make_installed!
-
- expect(page).to have_field('Issuer Email', with: custom_email)
- expect(page).to have_css('.js-cluster-application-uninstall-button', exact_text: 'Uninstall')
- end
- end
- end
-
- context 'when user installs Elastic Stack' do
- before do
- allow(ClusterInstallAppWorker).to receive(:perform_async)
-
- page.within('.js-cluster-application-row-elastic_stack') do
- click_button 'Install'
- end
-
- wait_for_requests
- end
-
- it 'shows status transition' do
- page.within('.js-cluster-application-row-elastic_stack') do
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_elastic_stack.make_installing!
-
- expect(page).to have_css('.js-cluster-application-install-button', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_elastic_stack.make_installed!
-
- expect(page).to have_css('.js-cluster-application-uninstall-button', exact_text: 'Uninstall')
- end
-
- expect(page).to have_content('Elastic Stack was successfully installed on your Kubernetes cluster')
- end
- end
-
- context 'when user installs Ingress' do
- before do
- allow(ClusterInstallAppWorker).to receive(:perform_async)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_in)
- allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_async)
-
- page.within('.js-cluster-application-row-ingress') do
- expect(page).to have_css('.js-cluster-application-install-button:not([disabled])')
- page.find(:css, '.js-cluster-application-install-button').click
-
- wait_for_requests
- end
- end
-
- it 'shows the status transition' do
- page.within('.js-cluster-application-row-ingress') do
- # FE sends request and gets the response, then the buttons is "Installing"
- expect(page).to have_css('.js-cluster-application-install-button[disabled]', exact_text: 'Installing')
-
- Clusters::Cluster.last.application_ingress.make_installing!
-
- # FE starts polling and update the buttons to "Installing"
- expect(page).to have_css('.js-cluster-application-install-button[disabled]', exact_text: 'Installing')
-
- # The application becomes installed but we keep waiting for external IP address
- Clusters::Cluster.last.application_ingress.make_installed!
-
- expect(page).to have_css('.js-cluster-application-install-button[disabled]', exact_text: 'Installed')
- expect(page).to have_selector('.js-no-endpoint-message')
- expect(page).to have_selector('.js-ingress-ip-loading-icon')
-
- # We receive the external IP address and display
- Clusters::Cluster.last.application_ingress.update!(external_ip: '192.168.1.100')
-
- expect(page).not_to have_css('button', exact_text: 'Install', visible: :all)
- expect(page).not_to have_css('button', exact_text: 'Installing', visible: :all)
- expect(page).to have_css('.js-cluster-application-uninstall-button:not([disabled])', exact_text: 'Uninstall')
- expect(page).not_to have_css('p', text: 'The endpoint is in the process of being assigned', visible: :all)
- expect(page.find('.js-endpoint').value).to eq('192.168.1.100')
- end
-
- expect(page).to have_content('Ingress was successfully installed on your Kubernetes cluster')
- end
- end
- end
-end
-
-RSpec.shared_examples "installing applications on a cluster" do
- it_behaves_like "installing applications for a cluster", false
- it_behaves_like "installing applications for a cluster", true
-end
diff --git a/spec/features/contextual_sidebar_spec.rb b/spec/features/contextual_sidebar_spec.rb
index 8ea1ebac6b7..39881a28b11 100644
--- a/spec/features/contextual_sidebar_spec.rb
+++ b/spec/features/contextual_sidebar_spec.rb
@@ -3,17 +3,17 @@
require 'spec_helper'
RSpec.describe 'Contextual sidebar', :js do
- let(:user) { create(:user) }
- let(:project) { create(:project) }
+ let_it_be(:project) { create(:project) }
+
+ let(:user) { project.owner }
before do
- project.add_maintainer(user)
sign_in(user)
visit project_path(project)
end
- it 'shows flyout navs when collapsed or expanded apart from on the active item when expanded' do
+ it 'shows flyout navs when collapsed or expanded apart from on the active item when expanded', :aggregate_failures do
expect(page).not_to have_selector('.js-sidebar-collapsed')
find('.rspec-link-pipelines').hover
diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb
index 233a93c2054..8c7564535b5 100644
--- a/spec/features/cycle_analytics_spec.rb
+++ b/spec/features/cycle_analytics_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe 'Value Stream Analytics', :js do
end
it 'shows active stage with empty message' do
- expect(page).to have_selector('.stage-nav-item.active', text: 'Issue')
+ expect(page).to have_selector('.gl-path-active-item-indigo', text: 'Issue')
expect(page).to have_content("We don't have enough data to show this stage.")
end
end
@@ -171,7 +171,7 @@ RSpec.describe 'Value Stream Analytics', :js do
end
def click_stage(stage_name)
- find('.stage-nav li', text: stage_name).click
+ find('.gl-path-nav-list-item', text: stage_name).click
wait_for_requests
end
end
diff --git a/spec/features/dashboard/active_tab_spec.rb b/spec/features/dashboard/active_tab_spec.rb
index a1fb0beda70..aa767d75c00 100644
--- a/spec/features/dashboard/active_tab_spec.rb
+++ b/spec/features/dashboard/active_tab_spec.rb
@@ -2,6 +2,9 @@
require 'spec_helper'
+# TODO: This entire spec file can be deleted once the combined_menu feature is fully rolled
+# out and the flag is removed, because it will then be irrelevant (there will be no more tabs).
+# Feature flag removal issue: https://gitlab.com/gitlab-org/gitlab/-/issues/324086
RSpec.describe 'Dashboard Active Tab', :js do
shared_examples 'combined_menu: feature flag examples' do
before do
@@ -10,8 +13,6 @@ RSpec.describe 'Dashboard Active Tab', :js do
shared_examples 'page has active tab' do |title|
it "#{title} tab" do
- pending_on_combined_menu_flag
-
subject
expect(page).to have_selector('.navbar-sub-nav li.active', count: 1)
@@ -32,27 +33,11 @@ RSpec.describe 'Dashboard Active Tab', :js do
end
end
- context 'with combined_menu: feature flag on' do
- let(:needs_rewrite_for_combined_menu_flag_on) { true }
-
- before do
- stub_feature_flags(combined_menu: true)
- end
-
- it_behaves_like 'combined_menu: feature flag examples'
- end
-
context 'with combined_menu feature flag off' do
- let(:needs_rewrite_for_combined_menu_flag_on) { false }
-
before do
stub_feature_flags(combined_menu: false)
end
it_behaves_like 'combined_menu: feature flag examples'
end
-
- def pending_on_combined_menu_flag
- pending 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587' if needs_rewrite_for_combined_menu_flag_on
- end
end
diff --git a/spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb b/spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb
index 0620f819332..3dd993b4bb5 100644
--- a/spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb
+++ b/spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe 'The group dashboard' do
include ExternalAuthorizationServiceHelpers
+ include Spec::Support::Helpers::Features::TopNavSpecHelpers
let(:user) { create(:user) }
@@ -14,11 +15,11 @@ RSpec.describe 'The group dashboard' do
describe 'The top navigation' do
it 'has all the expected links' do
- pending_on_combined_menu_flag
-
visit dashboard_groups_path
- within('.navbar') do
+ open_top_nav
+
+ within_top_nav do
expect(page).to have_button('Projects')
expect(page).to have_button('Groups')
expect(page).to have_link('Activity')
@@ -28,12 +29,12 @@ RSpec.describe 'The group dashboard' do
end
it 'hides some links when an external authorization service is enabled' do
- pending_on_combined_menu_flag
-
enable_external_authorization_service_check
visit dashboard_groups_path
- within('.navbar') do
+ open_top_nav
+
+ within_top_nav do
expect(page).to have_button('Projects')
expect(page).to have_button('Groups')
expect(page).not_to have_link('Activity')
@@ -44,7 +45,7 @@ RSpec.describe 'The group dashboard' do
end
end
- context 'with combined_menu: feature flag on' do
+ context 'with combined_menu feature flag on', :js do
let(:needs_rewrite_for_combined_menu_flag_on) { true }
before do
@@ -63,8 +64,4 @@ RSpec.describe 'The group dashboard' do
it_behaves_like 'combined_menu: feature flag examples'
end
-
- def pending_on_combined_menu_flag
- pending 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587' if needs_rewrite_for_combined_menu_flag_on
- end
end
diff --git a/spec/features/dashboard/group_spec.rb b/spec/features/dashboard/group_spec.rb
index bc6f449edc5..02cbdc7c777 100644
--- a/spec/features/dashboard/group_spec.rb
+++ b/spec/features/dashboard/group_spec.rb
@@ -16,6 +16,8 @@ RSpec.describe 'Dashboard Group' do
it 'creates new group', :js do
visit dashboard_groups_path
find('[data-testid="new-group-button"]').click
+ click_link 'Create group'
+
new_name = 'Samurai'
fill_in 'group_name', with: new_name
diff --git a/spec/features/dashboard/shortcuts_spec.rb b/spec/features/dashboard/shortcuts_spec.rb
index 5f60832dbc9..7439bfd334b 100644
--- a/spec/features/dashboard/shortcuts_spec.rb
+++ b/spec/features/dashboard/shortcuts_spec.rb
@@ -15,8 +15,6 @@ RSpec.describe 'Dashboard shortcuts', :js do
end
it 'navigate to tabs' do
- pending_on_combined_menu_flag
-
find('body').send_keys([:shift, 'I'])
check_page_title('Issues')
@@ -40,6 +38,10 @@ RSpec.describe 'Dashboard shortcuts', :js do
find('body').send_keys([:shift, 'A'])
check_page_title('Activity')
+
+ find('body').send_keys([:shift, 'L'])
+
+ check_page_title('Milestones')
end
end
@@ -49,8 +51,6 @@ RSpec.describe 'Dashboard shortcuts', :js do
end
it 'navigate to tabs' do
- pending_on_combined_menu_flag
-
find('body').send_keys([:shift, 'G'])
find('.nothing-here-block')
@@ -73,9 +73,7 @@ RSpec.describe 'Dashboard shortcuts', :js do
end
end
- context 'with combined_menu: feature flag on' do
- let(:needs_rewrite_for_combined_menu_flag_on) { true }
-
+ context 'with combined_menu feature flag on' do
before do
stub_feature_flags(combined_menu: true)
end
@@ -84,16 +82,10 @@ RSpec.describe 'Dashboard shortcuts', :js do
end
context 'with combined_menu feature flag off' do
- let(:needs_rewrite_for_combined_menu_flag_on) { false }
-
before do
stub_feature_flags(combined_menu: false)
end
it_behaves_like 'combined_menu: feature flag examples'
end
-
- def pending_on_combined_menu_flag
- pending 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587' if needs_rewrite_for_combined_menu_flag_on
- end
end
diff --git a/spec/features/frequently_visited_projects_and_groups_spec.rb b/spec/features/frequently_visited_projects_and_groups_spec.rb
index 9110c7ad65a..5ea42ce39e3 100644
--- a/spec/features/frequently_visited_projects_and_groups_spec.rb
+++ b/spec/features/frequently_visited_projects_and_groups_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Frequently visited items', :js do
+ include Spec::Support::Helpers::Features::TopNavSpecHelpers
+
let_it_be(:user) { create(:user) }
shared_examples 'combined_menu: feature flag examples' do
@@ -14,9 +16,8 @@ RSpec.describe 'Frequently visited items', :js do
let_it_be(:project) { create(:project, :public) }
it 'increments localStorage counter when visiting the project' do
- pending_on_combined_menu_flag
-
visit project_path(project)
+ open_top_nav_projects
frequent_projects = nil
@@ -34,9 +35,8 @@ RSpec.describe 'Frequently visited items', :js do
let_it_be(:group) { create(:group, :public) }
it 'increments localStorage counter when visiting the group' do
- pending_on_combined_menu_flag
-
visit group_path(group)
+ open_top_nav_groups
frequent_groups = nil
@@ -51,7 +51,7 @@ RSpec.describe 'Frequently visited items', :js do
end
end
- context 'with combined_menu: feature flag on' do
+ context 'with combined_menu feature flag on' do
let(:needs_rewrite_for_combined_menu_flag_on) { true }
before do
@@ -70,8 +70,4 @@ RSpec.describe 'Frequently visited items', :js do
it_behaves_like 'combined_menu: feature flag examples'
end
-
- def pending_on_combined_menu_flag
- pending 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587' if needs_rewrite_for_combined_menu_flag_on
- end
end
diff --git a/spec/features/groups/clusters/applications_spec.rb b/spec/features/groups/clusters/applications_spec.rb
deleted file mode 100644
index 324ef24efc4..00000000000
--- a/spec/features/groups/clusters/applications_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_relative '../../../../spec/features/clusters/installing_applications_shared_examples'
-
-RSpec.describe 'Group-level Cluster Applications', :js do
- include GoogleApi::CloudPlatformHelpers
-
- let(:group) { create(:group) }
- let(:user) { create(:user) }
-
- before do
- group.add_maintainer(user)
- sign_in(user)
- end
-
- describe 'Installing applications' do
- include_examples "installing applications on a cluster" do
- let(:cluster_path) { group_cluster_path(group, cluster) }
- let(:cluster_factory_args) { [:group, groups: [group]] }
- end
- end
-end
diff --git a/spec/features/groups/group_settings_spec.rb b/spec/features/groups/group_settings_spec.rb
index 00ad1006037..161a8a7a203 100644
--- a/spec/features/groups/group_settings_spec.rb
+++ b/spec/features/groups/group_settings_spec.rb
@@ -153,6 +153,26 @@ RSpec.describe 'Edit group settings' do
end
end
+ describe 'prevent sharing outside group hierarchy setting' do
+ it 'updates the setting' do
+ visit edit_group_path(group)
+
+ check 'group_prevent_sharing_groups_outside_hierarchy'
+
+ expect { save_permissions_group }.to change {
+ group.reload.namespace_settings.prevent_sharing_groups_outside_hierarchy
+ }.to(true)
+ end
+
+ it 'is not present for a subgroup' do
+ subgroup = create(:group, parent: group)
+ visit edit_group_path(subgroup)
+
+ expect(page).to have_text "Permissions"
+ expect(page).not_to have_selector('#group_prevent_sharing_groups_outside_hierarchy')
+ end
+ end
+
def update_path(new_group_path)
visit edit_group_path(group)
diff --git a/spec/features/groups/import_export/connect_instance_spec.rb b/spec/features/groups/import_export/connect_instance_spec.rb
index 73de49101ea..563c8f429f8 100644
--- a/spec/features/groups/import_export/connect_instance_spec.rb
+++ b/spec/features/groups/import_export/connect_instance_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do
visit new_group_path
- find('#import-group-tab').click
+ click_link 'Import group'
end
context 'when the user provides valid credentials' do
@@ -24,7 +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=40&search=" % { url: source_url }).to_return(
+ 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,
web_url: 'https://gitlab.com/groups/auto-breakfast',
diff --git a/spec/features/groups/import_export/import_file_spec.rb b/spec/features/groups/import_export/import_file_spec.rb
index 7018f3b1086..08295a3392a 100644
--- a/spec/features/groups/import_export/import_file_spec.rb
+++ b/spec/features/groups/import_export/import_file_spec.rb
@@ -28,9 +28,9 @@ RSpec.describe 'Import/Export - Group Import', :js do
group_name = 'Test Group Import'
visit new_group_path
+ click_link 'Import group'
- fill_in :group_name, with: group_name
- find('#import-group-tab').click
+ fill_in :import_group_name, with: group_name
expect(page).to have_content 'Import group from file'
attach_file(file) do
@@ -51,9 +51,9 @@ RSpec.describe 'Import/Export - Group Import', :js do
context 'when modifying the pre-filled path' do
it 'successfully imports the group' do
visit new_group_path
+ click_link 'Import group'
- fill_in :group_name, with: 'Test Group Import'
- find('#import-group-tab').click
+ fill_in :import_group_name, with: 'Test Group Import'
fill_in :import_group_path, with: 'custom-path'
attach_file(file) do
@@ -74,7 +74,7 @@ RSpec.describe 'Import/Export - Group Import', :js do
it 'suggests a unique path' do
visit new_group_path
- find('#import-group-tab').click
+ 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'
@@ -87,9 +87,9 @@ RSpec.describe 'Import/Export - Group Import', :js do
it 'displays an error' do
visit new_group_path
+ click_link 'Import group'
- fill_in :group_name, with: 'Test Group Import'
- find('#import-group-tab').click
+ fill_in :import_group_name, with: 'Test Group Import'
attach_file(file) do
find('.js-filepicker-button').click
end
diff --git a/spec/features/groups/integrations/user_activates_mattermost_slash_command_spec.rb b/spec/features/groups/integrations/user_activates_mattermost_slash_command_spec.rb
new file mode 100644
index 00000000000..7703268af39
--- /dev/null
+++ b/spec/features/groups/integrations/user_activates_mattermost_slash_command_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User activates the group-level Mattermost Slash Command integration', :js do
+ include_context 'group integration activation'
+
+ before do
+ stub_mattermost_setting(enabled: true)
+ visit_group_integration('Mattermost slash commands')
+ end
+
+ let(:edit_path) { edit_group_settings_integration_path(group, :mattermost_slash_commands) }
+
+ include_examples 'user activates the Mattermost Slash Command integration'
+end
diff --git a/spec/features/groups/members/manage_groups_spec.rb b/spec/features/groups/members/manage_groups_spec.rb
index 40cd54c1e33..2dfcd941b4f 100644
--- a/spec/features/groups/members/manage_groups_spec.rb
+++ b/spec/features/groups/members/manage_groups_spec.rb
@@ -143,6 +143,82 @@ RSpec.describe 'Groups > Members > Manage groups', :js do
end
end
+ describe 'group search results' do
+ let_it_be(:group, refind: true) { create(:group) }
+ let_it_be(:group_within_hierarchy) { create(:group, parent: group) }
+ let_it_be(:group_outside_hierarchy) { create(:group) }
+
+ before_all do
+ group.add_owner(user)
+ group_within_hierarchy.add_owner(user)
+ group_outside_hierarchy.add_owner(user)
+ end
+
+ context 'when sharing with groups outside the hierarchy is enabled' do
+ context 'when the invite members group modal is disabled' do
+ before do
+ stub_feature_flags(invite_members_group_modal: false)
+ end
+
+ it 'shows groups within and outside the hierarchy in search results' do
+ visit group_group_members_path(group)
+
+ click_on 'Invite group'
+ click_on 'Search for a group'
+
+ expect(page).to have_text group_within_hierarchy.name
+ expect(page).to have_text group_outside_hierarchy.name
+ end
+ end
+
+ context 'when the invite members group modal is enabled' do
+ it 'shows groups within and outside the hierarchy in search results' do
+ visit group_group_members_path(group)
+
+ click_on 'Invite a group'
+ click_on 'Select a group'
+
+ expect(page).to have_text group_within_hierarchy.name
+ expect(page).to have_text group_outside_hierarchy.name
+ end
+ end
+ end
+
+ context 'when sharing with groups outside the hierarchy is disabled' do
+ before do
+ group.namespace_settings.update!(prevent_sharing_groups_outside_hierarchy: true)
+ end
+
+ context 'when the invite members group modal is disabled' do
+ before do
+ stub_feature_flags(invite_members_group_modal: false)
+ end
+
+ it 'shows only groups within the hierarchy in search results' do
+ visit group_group_members_path(group)
+
+ click_on 'Invite group'
+ click_on 'Search for a group'
+
+ expect(page).to have_text group_within_hierarchy.name
+ expect(page).not_to have_text group_outside_hierarchy.name
+ end
+ end
+
+ context 'when the invite members group modal is enabled' do
+ it 'shows only groups within the hierarchy in search results' do
+ visit group_group_members_path(group)
+
+ click_on 'Invite a group'
+ click_on 'Select a group'
+
+ expect(page).to have_text group_within_hierarchy.name
+ expect(page).not_to have_text group_outside_hierarchy.name
+ end
+ end
+ end
+ end
+
def add_group(id, role)
page.click_link 'Invite group'
page.within ".invite-group-form" do
diff --git a/spec/features/groups/members/manage_members_spec.rb b/spec/features/groups/members/manage_members_spec.rb
index c5e6479ec51..ee18298e894 100644
--- a/spec/features/groups/members/manage_members_spec.rb
+++ b/spec/features/groups/members/manage_members_spec.rb
@@ -3,20 +3,19 @@
require 'spec_helper'
RSpec.describe 'Groups > Members > Manage members' do
- include Select2Helper
include Spec::Support::Helpers::Features::MembersHelpers
include Spec::Support::Helpers::Features::InviteMembersModalHelper
- let(:user1) { create(:user, name: 'John Doe') }
- let(:user2) { create(:user, name: 'Mary Jane') }
- let(:group) { create(:group) }
+ let_it_be(:user1) { create(:user, name: 'John Doe') }
+ let_it_be(:user2) { create(:user, name: 'Mary Jane') }
+ let_it_be(:group) { create(:group) }
before do
sign_in(user1)
end
shared_examples 'includes the correct Invite link' do |should_include, should_not_include|
- it 'includes either the form or the modal trigger' do
+ it 'includes either the form or the modal trigger', :aggregate_failures do
group.add_owner(user1)
visit group_group_members_path(group)
@@ -27,12 +26,12 @@ RSpec.describe 'Groups > Members > Manage members' do
end
shared_examples 'does not include either invite modal or either invite form' do
- it 'does not include either of the invite members or invite group modal buttons' do
+ it 'does not include either of the invite members or invite group modal buttons', :aggregate_failures do
expect(page).not_to have_selector '.js-invite-members-modal'
expect(page).not_to have_selector '.js-invite-group-modal'
end
- it 'does not include either of the invite users or invite group forms' do
+ it 'does not include either of the invite users or invite group forms', :aggregate_failures do
expect(page).not_to have_selector '.invite-users-form'
expect(page).not_to have_selector '.invite-group-form'
end
@@ -66,7 +65,7 @@ RSpec.describe 'Groups > Members > Manage members' do
end
end
- it 'add user to group', :js do
+ it 'add user to group', :js, :snowplow, :aggregate_failures do
group.add_owner(user1)
visit group_group_members_path(group)
@@ -77,6 +76,14 @@ RSpec.describe 'Groups > Members > Manage members' do
expect(page).to have_content(user2.name)
expect(page).to have_button('Reporter')
end
+
+ expect_snowplow_event(
+ category: 'Members::CreateService',
+ action: 'create_member',
+ label: 'group-members-page',
+ property: 'existing_user',
+ user: user1
+ )
end
it 'do not disclose email addresses', :js do
@@ -143,11 +150,13 @@ RSpec.describe 'Groups > Members > Manage members' do
wait_for_requests
- expect(page).not_to have_content(user2.name)
- expect(group.users).not_to include(user2)
+ aggregate_failures do
+ expect(page).not_to have_content(user2.name)
+ expect(group.users).not_to include(user2)
+ end
end
- it 'add yourself to group when already an owner', :js do
+ it 'add yourself to group when already an owner', :js, :aggregate_failures do
group.add_owner(user1)
visit group_group_members_path(group)
@@ -160,7 +169,7 @@ RSpec.describe 'Groups > Members > Manage members' do
end
end
- it 'invite user to group', :js do
+ it 'invite user to group', :js, :snowplow do
group.add_owner(user1)
visit group_group_members_path(group)
@@ -170,14 +179,24 @@ RSpec.describe 'Groups > Members > Manage members' do
expect(page).to have_link 'Invited'
click_link 'Invited'
- page.within(members_table) do
- expect(page).to have_content('test@example.com')
- expect(page).to have_content('Invited')
- expect(page).to have_button('Reporter')
+ aggregate_failures do
+ page.within(members_table) do
+ expect(page).to have_content('test@example.com')
+ expect(page).to have_content('Invited')
+ expect(page).to have_button('Reporter')
+ end
+
+ expect_snowplow_event(
+ category: 'Members::InviteService',
+ action: 'create_member',
+ label: 'group-members-page',
+ property: 'net_new_user',
+ user: user1
+ )
end
end
- context 'as a guest', :js do
+ context 'when user is a guest' do
before do
group.add_guest(user1)
group.add_developer(user2)
@@ -187,7 +206,7 @@ RSpec.describe 'Groups > Members > Manage members' do
it_behaves_like 'does not include either invite modal or either invite form'
- it 'does not include a button on the members page list to manage or remove the existing member', :js do
+ it 'does not include a button on the members page list to manage or remove the existing member', :js, :aggregate_failures do
page.within(second_row) do
# Can not modify user2 role
expect(page).not_to have_button 'Developer'
@@ -198,7 +217,7 @@ RSpec.describe 'Groups > Members > Manage members' do
end
end
- context 'As a guest when the :invite_members_group_modal feature flag is disabled', :js do
+ context 'when user is a guest and the :invite_members_group_modal feature flag is disabled' do
before do
stub_feature_flags(invite_members_group_modal: false)
group.add_guest(user1)
@@ -209,7 +228,7 @@ RSpec.describe 'Groups > Members > Manage members' do
it_behaves_like 'does not include either invite modal or either invite form'
- it 'does not include a button on the members page list to manage or remove the existing member', :js do
+ it 'does not include a button on the members page list to manage or remove the existing member', :js, :aggregate_failures do
page.within(second_row) do
# Can not modify user2 role
expect(page).not_to have_button 'Developer'
diff --git a/spec/features/groups/members/tabs_spec.rb b/spec/features/groups/members/tabs_spec.rb
index 2f95e9fa6d3..2e9f332c0d6 100644
--- a/spec/features/groups/members/tabs_spec.rb
+++ b/spec/features/groups/members/tabs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Groups > Members > Tabs' do
+RSpec.describe 'Groups > Members > Tabs', :js do
using RSpec::Parameterized::TableSyntax
shared_examples 'active "Members" tab' do
@@ -56,7 +56,7 @@ RSpec.describe 'Groups > Members > Tabs' do
it_behaves_like 'active "Members" tab'
end
- context 'when searching "Invited"', :js do
+ context 'when searching "Invited"' do
before do
visit group_group_members_path(group)
@@ -86,7 +86,7 @@ RSpec.describe 'Groups > Members > Tabs' do
end
end
- context 'when using "Invited" pagination', :js do
+ context 'when using "Invited" pagination' do
before do
visit group_group_members_path(group)
diff --git a/spec/features/groups/milestones/gfm_autocomplete_spec.rb b/spec/features/groups/milestones/gfm_autocomplete_spec.rb
index 85a14123294..1fec6091f1e 100644
--- a/spec/features/groups/milestones/gfm_autocomplete_spec.rb
+++ b/spec/features/groups/milestones/gfm_autocomplete_spec.rb
@@ -16,6 +16,7 @@ RSpec.describe 'GFM autocomplete', :js do
fill_in 'Description', with: User.reference_prefix
wait_for_requests
expect(find_autocomplete_menu).to be_visible
+ expect_autocomplete_entry(user.name)
expect_autocomplete_entry(group.name)
fill_in 'Description', with: Label.reference_prefix
diff --git a/spec/features/groups/navbar_spec.rb b/spec/features/groups/navbar_spec.rb
index b46d4dae87a..70a19445c89 100644
--- a/spec/features/groups/navbar_spec.rb
+++ b/spec/features/groups/navbar_spec.rb
@@ -13,6 +13,7 @@ RSpec.describe 'Group navbar' do
let(:structure) do
[
+ group_context_nav_item,
group_information_nav_item,
{
nav_item: _('Issues'),
@@ -37,6 +38,13 @@ RSpec.describe 'Group navbar' 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'))
@@ -79,6 +87,10 @@ RSpec.describe 'Group navbar' do
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'),
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 6d7a3871bb1..a01514714dd 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', 'set default configuration'
+ it_behaves_like 'can highlight results', 'Project integration management'
end
context 'in Repository page' do
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index bcccadf7710..5f8079f0436 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -15,9 +15,10 @@ RSpec.describe 'Group' do
end
end
- describe 'create a group' do
+ describe 'create a group', :js do
before do
visit new_group_path
+ click_link 'Create group'
end
describe 'as a non-admin' do
@@ -50,13 +51,14 @@ RSpec.describe 'Group' do
fill_in 'Group URL', with: 'space group'
click_button 'Create group'
- expect(current_path).to eq(groups_path)
- expect(page).to have_namespace_error_message
+ expect(current_path).to eq(new_group_path)
+ expect(page).to have_text('Please choose a group URL with no special characters.')
end
end
describe 'with .atom at end of group path' do
it 'renders new group form with validation errors' do
+ fill_in 'Group name', with: 'test-group'
fill_in 'Group URL', with: 'atom_group.atom'
click_button 'Create group'
@@ -67,6 +69,7 @@ RSpec.describe 'Group' do
describe 'with .git at end of group path' do
it 'renders new group form with validation errors' do
+ fill_in 'Group name', with: 'test-group'
fill_in 'Group URL', with: 'git_group.git'
click_button 'Create group'
@@ -109,6 +112,7 @@ RSpec.describe 'Group' do
stub_mattermost_setting(enabled: mattermost_enabled)
visit new_group_path
+ click_link 'Create group'
end
context 'Mattermost enabled' do
@@ -119,7 +123,7 @@ RSpec.describe 'Group' do
end
it 'unchecks the checkbox by default' do
- expect(find('#group_create_chat_team')['checked']).to eq(false)
+ expect(find('#group_create_chat_team')).not_to be_checked
end
it 'updates the team URL on graph path update', :js do
@@ -147,6 +151,7 @@ RSpec.describe 'Group' do
stub_application_setting(recaptcha_enabled: true)
allow(Gitlab::Recaptcha).to receive(:load_configurations!)
visit new_group_path
+ click_link 'Create group'
end
it 'renders recaptcha' do
@@ -159,6 +164,7 @@ RSpec.describe 'Group' do
stub_feature_flags(recaptcha_on_top_level_group_creation: false)
stub_application_setting(recaptcha_enabled: true)
visit new_group_path
+ click_link 'Create group'
end
it 'does not render recaptcha' do
@@ -167,30 +173,30 @@ RSpec.describe 'Group' do
end
end
- describe 'create a nested group' do
+ describe 'create a nested group', :js do
let_it_be(:group) { create(:group, path: 'foo') }
context 'as admin' do
let(:user) { create(:admin) }
before do
- visit new_group_path(group, parent_id: group.id)
+ visit new_group_path(parent_id: group.id)
end
context 'when admin mode is enabled', :enable_admin_mode do
it 'creates a nested group' do
+ click_link 'Create group'
fill_in 'Group name', with: 'bar'
- fill_in 'Group URL', with: 'bar'
click_button 'Create group'
expect(current_path).to eq(group_path('foo/bar'))
- expect(page).to have_content("Group 'bar' was successfully created.")
+ expect(page).to have_selector 'h1', text: 'bar'
end
end
context 'when admin mode is disabled' do
it 'is not allowed' do
- expect(page).to have_gitlab_http_status(:not_found)
+ expect(page).not_to have_button('Create group')
end
end
end
@@ -203,14 +209,14 @@ RSpec.describe 'Group' do
sign_out(:user)
sign_in(user)
- visit new_group_path(group, parent_id: group.id)
+ visit new_group_path(parent_id: group.id)
+ click_link 'Create group'
fill_in 'Group name', with: 'bar'
- fill_in 'Group URL', with: 'bar'
click_button 'Create group'
expect(current_path).to eq(group_path('foo/bar'))
- expect(page).to have_content("Group 'bar' was successfully created.")
+ expect(page).to have_selector 'h1', text: 'bar'
end
end
@@ -221,7 +227,7 @@ RSpec.describe 'Group' do
end
context 'when creating subgroup' do
- let(:path) { new_group_path(group, parent_id: group.id) }
+ let(:path) { new_group_path(parent_id: group.id) }
it 'does not render recaptcha' do
visit path
@@ -237,6 +243,7 @@ RSpec.describe 'Group' do
before do
group.add_owner(user)
visit new_group_path(parent_id: group.id)
+ click_link 'Create group'
end
it 'shows a message if group url is available' do
@@ -255,14 +262,15 @@ RSpec.describe 'Group' do
end
end
- it 'checks permissions to avoid exposing groups by parent_id' do
+ it 'checks permissions to avoid exposing groups by parent_id', :js do
group = create(:group, :private, path: 'secret-group')
sign_out(:user)
sign_in(create(:user))
visit new_group_path(parent_id: group.id)
- expect(page).not_to have_content('secret-group')
+ expect(page).to have_title('Not Found')
+ expect(page).to have_content('Page Not Found')
end
describe 'group edit', :js do
diff --git a/spec/features/incidents/incident_details_spec.rb b/spec/features/incidents/incident_details_spec.rb
index 96f8cf0062c..b704a0515c8 100644
--- a/spec/features/incidents/incident_details_spec.rb
+++ b/spec/features/incidents/incident_details_spec.rb
@@ -49,4 +49,42 @@ RSpec.describe 'Incident details', :js do
end
end
end
+
+ context 'when an incident `issue_type` is edited by a signed in user' do
+ it 'routes the user to the incident details page when the `issue_type` is set to incident' do
+ wait_for_requests
+ project_path = "/#{project.full_path}"
+ click_button 'Edit title and description'
+ wait_for_requests
+
+ page.within('[data-testid="issuable-form"]') do
+ click_button 'Incident'
+ click_button 'Issue'
+ click_button 'Save changes'
+
+ wait_for_requests
+
+ expect(page).to have_current_path("#{project_path}/-/issues/#{incident.iid}")
+ end
+ end
+ end
+
+ context 'when incident details are edited by a signed in user' do
+ it 'routes the user to the incident details page when the `issue_type` is set to incident' do
+ wait_for_requests
+ project_path = "/#{project.full_path}"
+ click_button 'Edit title and description'
+ wait_for_requests
+
+ page.within('[data-testid="issuable-form"]') do
+ click_button 'Incident'
+ click_button 'Issue'
+ click_button 'Save changes'
+
+ wait_for_requests
+
+ expect(page).to have_current_path("#{project_path}/-/issues/#{incident.iid}")
+ end
+ end
+ end
end
diff --git a/spec/features/issues/csv_spec.rb b/spec/features/issues/csv_spec.rb
index d41a41c4383..51e0d54ca5e 100644
--- a/spec/features/issues/csv_spec.rb
+++ b/spec/features/issues/csv_spec.rb
@@ -16,9 +16,7 @@ RSpec.describe 'Issues csv', :js do
def request_csv(params = {})
visit project_issues_path(project, params)
- page.within('.nav-controls') do
- find('[data-testid="export-csv-button"]').click
- end
+ click_button 'Export as CSV'
click_on 'Export issues'
end
diff --git a/spec/features/issues/issue_detail_spec.rb b/spec/features/issues/issue_detail_spec.rb
index 1c8da227412..a942a1a44f6 100644
--- a/spec/features/issues/issue_detail_spec.rb
+++ b/spec/features/issues/issue_detail_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe 'Issue Detail', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project, author: user) }
+ let(:incident) { create(:incident, project: project, author: user) }
context 'when user displays the issue' do
before do
@@ -21,10 +22,8 @@ RSpec.describe 'Issue Detail', :js do
end
context 'when user displays the issue as an incident' do
- let(:issue) { create(:incident, project: project, author: user) }
-
before do
- visit project_issue_path(project, issue)
+ visit project_issue_path(project, incident)
wait_for_requests
end
@@ -58,9 +57,9 @@ RSpec.describe 'Issue Detail', :js do
visit project_issue_path(project, issue)
wait_for_requests
- page.find('.js-issuable-edit').click
+ click_button 'Edit title and description'
fill_in 'issuable-title', with: 'issue title'
- click_button 'Save'
+ click_button 'Save changes'
wait_for_requests
Users::DestroyService.new(user).execute(user)
@@ -74,4 +73,58 @@ RSpec.describe 'Issue Detail', :js do
end
end
end
+
+ describe 'user updates `issue_type` via the issue type dropdown' do
+ context 'when an issue `issue_type` is edited by a signed in user' do
+ before do
+ sign_in(user)
+
+ visit project_issue_path(project, issue)
+ wait_for_requests
+ end
+
+ it 'routes the user to the incident details page when the `issue_type` is set to incident' do
+ open_issue_edit_form
+
+ page.within('[data-testid="issuable-form"]') do
+ update_type_select('Issue', 'Incident')
+
+ expect(page).to have_current_path(project_issues_incident_path(project, issue))
+ end
+ end
+ end
+
+ context 'when an incident `issue_type` is edited by a signed in user' do
+ before do
+ sign_in(user)
+
+ visit project_issue_path(project, incident)
+ wait_for_requests
+ end
+
+ it 'routes the user to the issue details page when the `issue_type` is set to issue' do
+ open_issue_edit_form
+
+ page.within('[data-testid="issuable-form"]') do
+ update_type_select('Incident', 'Issue')
+
+ expect(page).to have_current_path(project_issue_path(project, incident))
+ end
+ end
+ end
+ end
+
+ def update_type_select(from, to)
+ click_button from
+ click_button to
+ click_button 'Save changes'
+
+ wait_for_requests
+ end
+
+ def open_issue_edit_form
+ wait_for_requests
+ click_button 'Edit title and description'
+ wait_for_requests
+ end
end
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index d147476f1ab..d828b1c1f0c 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe 'Issue Sidebar' do
stub_feature_flags(issue_assignees_widget: false)
end
- include_examples 'issuable invite members experiments' do
+ include_examples 'issuable invite members' do
let(:issuable_path) { project_issue_path(project, issue2) }
end
@@ -266,7 +266,7 @@ RSpec.describe 'Issue Sidebar' do
let_it_be(:milestone3) { create(:milestone, project: project, title: 'Milestone-3', due_date: 10.days.from_now) }
before do
- page.within('.block.milestone > .title') do
+ page.within('[data-testid="milestone_title"]') do
click_on 'Edit'
end
end
diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb
index e2e204f03db..4a77e850d51 100644
--- a/spec/features/issues/user_creates_issue_spec.rb
+++ b/spec/features/issues/user_creates_issue_spec.rb
@@ -30,7 +30,7 @@ RSpec.describe "User creates issue" do
end
end
- context "when signed in as guest" do
+ context "when signed in as guest", :js do
before do
project.add_guest(user)
sign_in(user)
@@ -38,41 +38,19 @@ RSpec.describe "User creates issue" do
visit(new_project_issue_path(project))
end
- it "creates issue", :js do
- page.within(".issue-form") do
- expect(page).to have_no_content("Assign to")
- .and have_no_content("Labels")
- .and have_no_content("Milestone")
-
- expect(page.find('#issue_title')['placeholder']).to eq 'Title'
- expect(page.find('#issue_description')['placeholder']).to eq 'Write a description or drag your files here…'
+ context 'available metadata' do
+ it 'allows guest to set issue metadata' do
+ page.within(".issue-form") do
+ expect(page).to have_content("Title")
+ .and have_content("Description")
+ .and have_content("Type")
+ .and have_content("Assignee")
+ .and have_content("Milestone")
+ .and have_content("Labels")
+ .and have_content("Due date")
+ .and have_content("This issue is confidential and should only be visible to team members with at least Reporter access.")
+ end
end
-
- issue_title = "500 error on profile"
-
- fill_in("Title", with: issue_title)
- first('.js-md').click
- first('.rspec-issuable-form-description').native.send_keys('Description')
-
- click_button("Create issue")
-
- expect(page).to have_content(issue_title)
- .and have_content(user.name)
- .and have_content(project.name)
- expect(page).to have_selector('strong', text: 'Description')
- end
-
- it 'does not render the issue type dropdown' do
- expect(page).not_to have_selector('.s-issuable-type-filter-dropdown-wrap')
- end
- end
-
- context "when signed in as developer", :js do
- before do
- project.add_developer(user)
- sign_in(user)
-
- visit(new_project_issue_path(project))
end
context "when previewing" do
diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb
index cb4a5a32762..c59cc99467c 100644
--- a/spec/features/issues/user_edits_issue_spec.rb
+++ b/spec/features/issues/user_edits_issue_spec.rb
@@ -187,7 +187,8 @@ RSpec.describe "Issues > User edits issue", :js do
click_link 'Edit'
click_link 'Unassigned'
- first('.title').click
+
+ close_dropdown_menu_if_visible
expect(page).to have_content 'None - assign yourself'
end
@@ -227,7 +228,7 @@ RSpec.describe "Issues > User edits issue", :js do
close_dropdown_menu_if_visible
- page.within '.value .assign-yourself' do
+ page.within '[data-testid="no-value"]' do
expect(page).to have_content "None"
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 bbb7e8a028d..2921eea7641 100644
--- a/spec/features/issues/user_interacts_with_awards_spec.rb
+++ b/spec/features/issues/user_interacts_with_awards_spec.rb
@@ -62,11 +62,11 @@ 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"].is-active .js-counter')).to have_content('1')
- expect(page).to have_css('[data-testid="award-button"].is-active[title="You"]')
+ 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 do
- page.find('[data-testid="award-button"].is-active').click
+ page.find('[data-testid="award-button"].selected').click
wait_for_requests
end.to change { page.all('[data-testid="award-button"]').size }.from(3).to(2)
end
@@ -205,7 +205,7 @@ RSpec.describe 'User interacts with awards' do
it 'adds award to issue' do
first('[data-testid="award-button"]').click
- expect(page).to have_selector('[data-testid="award-button"].is-active')
+ expect(page).to have_selector('[data-testid="award-button"].selected')
expect(first('[data-testid="award-button"]')).to have_content '1'
visit project_issue_path(project, issue)
@@ -215,7 +215,7 @@ RSpec.describe 'User interacts with awards' do
it 'removes award from issue' do
first('[data-testid="award-button"]').click
- find('[data-testid="award-button"].is-active').click
+ find('[data-testid="award-button"].selected').click
expect(first('[data-testid="award-button"]')).to have_content '0'
diff --git a/spec/features/issues/user_resets_their_incoming_email_token_spec.rb b/spec/features/issues/user_resets_their_incoming_email_token_spec.rb
index 2b1c25174c2..4580378dc8a 100644
--- a/spec/features/issues/user_resets_their_incoming_email_token_spec.rb
+++ b/spec/features/issues/user_resets_their_incoming_email_token_spec.rb
@@ -16,11 +16,11 @@ RSpec.describe 'Issues > User resets their incoming email token' do
end
it 'changes incoming email address token', :js do
- page.find('[data-testid="issuable-email-modal-btn"]').click
+ click_button 'Email a new issue to this project'
page.within '#issuable-email-modal' do
previous_token = page.find('input[type="text"]').value
- page.find('[data-testid="incoming-email-token-reset"]').click
+ find('[data-testid="reset_email_token_link"]').click
wait_for_requests
diff --git a/spec/features/issues/user_toggles_subscription_spec.rb b/spec/features/issues/user_toggles_subscription_spec.rb
index 35f4b415463..9809bb34d26 100644
--- a/spec/features/issues/user_toggles_subscription_spec.rb
+++ b/spec/features/issues/user_toggles_subscription_spec.rb
@@ -5,35 +5,70 @@ require "spec_helper"
RSpec.describe "User toggles subscription", :js do
let(:project) { create(:project_empty_repo, :public) }
let(:user) { create(:user) }
+ let(:user2) { create(:user) }
let(:issue) { create(:issue, project: project, author: user) }
- before do
- project.add_developer(user)
- sign_in(user)
+ context 'user is not logged in' do
+ before do
+ visit(project_issue_path(project, issue))
+ end
- visit(project_issue_path(project, issue))
+ it 'does not display the Notification toggle' do
+ expect(page).not_to have_button('Notifications')
+ end
end
- it "unsubscribes from issue" do
- subscription_button = find('[data-testid="subscription-toggle"]')
+ context 'user is logged in' do
+ before do
+ project.add_developer(user)
+ sign_in(user)
+
+ visit(project_issue_path(project, issue))
+ end
+
+ it 'unsubscribes from issue' do
+ subscription_button = find('[data-testid="subscription-toggle"]')
+
+ # Check we're subscribed.
+ expect(subscription_button).to have_css("button.is-checked")
+
+ # Toggle subscription.
+ find('[data-testid="subscription-toggle"]').click
+ wait_for_requests
- # Check we're subscribed.
- expect(subscription_button).to have_css("button.is-checked")
+ # Check we're unsubscribed.
+ expect(subscription_button).to have_css("button:not(.is-checked)")
+ end
- # Toggle subscription.
- find('[data-testid="subscription-toggle"]').click
- wait_for_requests
+ context 'when project emails are disabled' do
+ let(:project) { create(:project_empty_repo, :public, emails_disabled: true) }
- # Check we're unsubscribed.
- expect(subscription_button).to have_css("button:not(.is-checked)")
+ it 'is disabled' do
+ expect(page).to have_content('Disabled by project owner')
+ expect(page).to have_button('Notifications', class: 'is-disabled')
+ end
+ end
end
- context 'when project emails are disabled' do
- let(:project) { create(:project_empty_repo, :public, emails_disabled: true) }
+ context 'user is logged in without edit permission' do
+ before do
+ sign_in(user2)
+
+ visit(project_issue_path(project, issue))
+ end
+
+ it 'subscribes to issue' do
+ subscription_button = find('[data-testid="subscription-toggle"]')
+
+ # Check we're not subscribed.
+ expect(subscription_button).to have_css("button:not(.is-checked)")
+
+ # Toggle subscription.
+ find('[data-testid="subscription-toggle"]').click
+ wait_for_requests
- it 'is disabled' do
- expect(page).to have_content('Disabled by project owner')
- expect(page).to have_button('Notifications', class: 'is-disabled')
+ # Check we're subscribed.
+ expect(subscription_button).to have_css("button.is-checked")
end
end
end
diff --git a/spec/features/markdown/mermaid_spec.rb b/spec/features/markdown/mermaid_spec.rb
index 207678e07c3..c4994838d26 100644
--- a/spec/features/markdown/mermaid_spec.rb
+++ b/spec/features/markdown/mermaid_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Mermaid rendering', :js do
+ let_it_be(:project) { create(:project, :public) }
+
it 'renders Mermaid diagrams correctly' do
description = <<~MERMAID
```mermaid
@@ -14,7 +16,6 @@ RSpec.describe 'Mermaid rendering', :js do
```
MERMAID
- project = create(:project, :public)
issue = create(:issue, project: project, description: description)
visit project_issue_path(project, issue)
@@ -36,7 +37,6 @@ RSpec.describe 'Mermaid rendering', :js do
```
MERMAID
- project = create(:project, :public)
issue = create(:issue, project: project, description: description)
visit project_issue_path(project, issue)
@@ -44,10 +44,33 @@ RSpec.describe 'Mermaid rendering', :js do
wait_for_requests
wait_for_mermaid
- expected = '<text style=""><tspan xml:space="preserve" dy="1em" x="1">Line 1</tspan><tspan xml:space="preserve" dy="1em" x="1">Line 2</tspan></text>'
+ # From https://github.com/mermaid-js/mermaid/blob/d3f8f03a7d03a052e1fe0251d5a6d8d1f48d67ee/src/dagre-wrapper/createLabel.js#L79-L82
+ expected = %(<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">Line 1<br>Line 2</div>)
expect(page.html.scan(expected).count).to be(4)
end
+ it 'does not allow XSS in HTML labels' do
+ description = <<~MERMAID
+ ```mermaid
+ graph LR;
+ A-->CLICK_HERE_AND_GET_BONUS;
+ click A alert "aaa"
+ click CLICK_HERE_AND_GET_BONUS "javascript:alert%28%64%6f%63%75%6d%65%6e%74%2e%64%6f%6d%61%69%6e%29" "Here is the XSS"
+ ```
+ MERMAID
+
+ issue = create(:issue, project: project, description: description)
+
+ visit project_issue_path(project, issue)
+
+ wait_for_requests
+ wait_for_mermaid
+
+ # From https://github.com/mermaid-js/mermaid/blob/d3f8f03a7d03a052e1fe0251d5a6d8d1f48d67ee/src/dagre-wrapper/createLabel.js#L79-L82
+ expected = %(<div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; white-space: nowrap;">CLICK_HERE_AND_GET_BONUS</div>)
+ expect(page.html).to include(expected)
+ end
+
it 'renders only 2 Mermaid blocks and', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/234081' do
description = <<~MERMAID
```mermaid
@@ -64,7 +87,6 @@ RSpec.describe 'Mermaid rendering', :js do
```
MERMAID
- project = create(:project, :public)
issue = create(:issue, project: project, description: description)
visit project_issue_path(project, issue)
@@ -94,7 +116,6 @@ RSpec.describe 'Mermaid rendering', :js do
</details>
MERMAID
- project = create(:project, :public)
issue = create(:issue, project: project, description: description)
visit project_issue_path(project, issue)
@@ -108,7 +129,37 @@ RSpec.describe 'Mermaid rendering', :js do
expect(svg[:style]).to match(/max-width/)
expect(svg[:width].to_i).to eq(100)
- expect(svg[:height].to_i).to be_within(5).of(220)
+ expect(svg[:height].to_i).to be_within(5).of(236)
+ end
+ end
+
+ it 'renders V2 state diagrams' do
+ description = <<~MERMAID
+ ```mermaid
+ stateDiagram-v2
+ [*] --> Idle
+ Idle --> Active : CONTINUE
+ state Active {
+ [*] --> Run
+ Run--> Stop: CONTINUE
+ Stop--> Run: CONTINUE
+
+ Run: Run
+ Run: entry/start
+ Run: check
+ }
+ ```
+ MERMAID
+
+ issue = create(:issue, project: project, description: description)
+
+ visit project_issue_path(project, issue)
+
+ wait_for_requests
+ wait_for_mermaid
+
+ page.within('.description') do
+ expect(page).to have_selector('svg')
end
end
@@ -123,7 +174,6 @@ RSpec.describe 'Mermaid rendering', :js do
```
MERMAID
- project = create(:project, :public)
issue = create(:issue, project: project, description: description)
visit project_issue_path(project, issue)
@@ -144,7 +194,6 @@ RSpec.describe 'Mermaid rendering', :js do
```
MERMAID
- project = create(:project, :public)
issue = create(:issue, project: project, description: description)
visit project_issue_path(project, issue)
@@ -183,8 +232,6 @@ RSpec.describe 'Mermaid rendering', :js do
description *= 51
- project = create(:project, :public)
-
issue = create(:issue, project: project, description: description)
visit project_issue_path(project, issue)
@@ -200,6 +247,36 @@ RSpec.describe 'Mermaid rendering', :js do
expect(page).to have_selector('.js-lazy-render-mermaid-container')
end
end
+
+ it 'renders without any limits on wiki page', :js do
+ graph_edges = "A-->B;B-->A;"
+
+ description = <<~MERMAID
+ ```mermaid
+ graph LR
+ #{graph_edges}
+ ```
+ MERMAID
+
+ description *= 51
+
+ project = create(:project, :public)
+
+ wiki_page = build(:wiki_page, { container: project, content: description })
+ wiki_page.create message: 'mermaid test commit' # rubocop:disable Rails/SaveBang
+ wiki_page = project.wiki.find_page(wiki_page.slug)
+
+ visit project_wiki_path(project, wiki_page)
+
+ wait_for_requests
+ wait_for_mermaid
+
+ page.within('.js-wiki-page-content') do
+ expect(page).not_to have_selector('.lazy-alert-shown')
+
+ expect(page).not_to have_selector('.js-lazy-render-mermaid-container')
+ end
+ end
end
def wait_for_mermaid
diff --git a/spec/features/markdown/metrics_spec.rb b/spec/features/markdown/metrics_spec.rb
index 9716c660fa9..f9781f6c702 100644
--- a/spec/features/markdown/metrics_spec.rb
+++ b/spec/features/markdown/metrics_spec.rb
@@ -173,7 +173,7 @@ RSpec.describe 'Metrics rendering', :js, :kubeclient, :use_clean_rails_memory_st
allow(Prometheus::ProxyService).to receive(:new).and_call_original
- create(:clusters_applications_prometheus, :installed, cluster: cluster)
+ 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)
diff --git a/spec/features/merge_request/user_allows_commits_from_memebers_who_can_merge_spec.rb b/spec/features/merge_request/user_allows_commits_from_memebers_who_can_merge_spec.rb
index d36abf86518..75912238501 100644
--- a/spec/features/merge_request/user_allows_commits_from_memebers_who_can_merge_spec.rb
+++ b/spec/features/merge_request/user_allows_commits_from_memebers_who_can_merge_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe 'create a merge request, allowing commits from members who can me
wait_for_requests
- expect(page).to have_content('Allows commits from members who can merge to the target branch')
+ expect(page).to have_content('Members who can merge are allowed to add commits.')
end
it 'shows a message when one of the projects is private', :sidekiq_might_not_need_inline do
@@ -59,7 +59,7 @@ RSpec.describe 'create a merge request, allowing commits from members who can me
visit_new_merge_request
- expect(page).not_to have_content('Allows commits from members who can merge to the target branch')
+ expect(page).not_to have_content('The fork project allows commits from members who can write to the target branch.')
end
end
@@ -81,7 +81,7 @@ RSpec.describe 'create a merge request, allowing commits from members who can me
it 'hides the option from members' do
visit edit_project_merge_request_path(target_project, merge_request)
- expect(page).not_to have_content('Allows commits from members who can merge to the target branch')
+ expect(page).not_to have_content('The fork project allows commits from members who can write to the target branch.')
end
end
end
diff --git a/spec/features/merge_request/user_awards_emoji_spec.rb b/spec/features/merge_request/user_awards_emoji_spec.rb
index 6f46cc20cba..240b8f996c8 100644
--- a/spec/features/merge_request/user_awards_emoji_spec.rb
+++ b/spec/features/merge_request/user_awards_emoji_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe 'Merge request > User awards emoji', :js do
it 'adds award to merge request' do
first('[data-testid="award-button"]').click
- expect(page).to have_selector('[data-testid="award-button"].is-active')
+ expect(page).to have_selector('[data-testid="award-button"].selected')
expect(first('[data-testid="award-button"]')).to have_content '1'
visit project_merge_request_path(project, merge_request)
@@ -27,7 +27,7 @@ RSpec.describe 'Merge request > User awards emoji', :js do
it 'removes award from merge request' do
first('[data-testid="award-button"]').click
- find('[data-testid="award-button"].is-active').click
+ find('[data-testid="award-button"].selected').click
expect(first('[data-testid="award-button"]')).to have_content '0'
visit project_merge_request_path(project, merge_request)
diff --git a/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb b/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb
index 7d55a72c2b1..1087be3d8c6 100644
--- a/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb
+++ b/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb
@@ -68,14 +68,14 @@ RSpec.describe 'Merge request > User edits assignees sidebar', :js do
end
end
- context 'with invite members experiment considerations' do
+ context 'with invite members considerations' do
let_it_be(:user) { create(:user) }
before do
sign_in(user)
end
- include_examples 'issuable invite members experiments' do
+ include_examples 'issuable invite members' do
let(:issuable_path) { project_merge_request_path(project, merge_request) }
end
end
diff --git a/spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb b/spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb
new file mode 100644
index 00000000000..45ee914de9d
--- /dev/null
+++ b/spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Merge request > User edits reviewers sidebar', :js do
+ context 'with invite members considerations' do
+ let_it_be(:merge_request) { create(:merge_request) }
+ let_it_be(:project) { merge_request.project }
+ let_it_be(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+ end
+
+ context 'when a privileged user can invite in reviewer dropdown' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ it 'shows a link for inviting members and launches invite modal' do
+ visit project_merge_request_path(project, merge_request)
+
+ reviewer_edit_link.click
+
+ wait_for_requests
+
+ page.within '.dropdown-menu-user' do
+ expect(page).to have_link('Invite Members')
+ expect(page).to have_selector('[data-track-event="click_invite_members"]')
+ expect(page).to have_selector('[data-track-label="edit_reviewer"]')
+ end
+
+ click_link 'Invite Members'
+
+ expect(page).to have_content("You're inviting members to the")
+ end
+ end
+
+ context 'when user cannot invite members in reviewer dropdown' do
+ before do
+ project.add_developer(user)
+ end
+
+ it 'shows author in assignee dropdown and no invite link' do
+ visit project_merge_request_path(project, merge_request)
+
+ reviewer_edit_link.click
+
+ wait_for_requests
+
+ page.within '.dropdown-menu-user' do
+ expect(page).not_to have_link('Invite Members')
+ end
+ end
+ end
+
+ def reviewer_edit_link
+ find('.block.reviewer .edit-link')
+ end
+ end
+end
diff --git a/spec/features/merge_request/user_merges_immediately_spec.rb b/spec/features/merge_request/user_merges_immediately_spec.rb
index 64a357de1f7..bca6e6ceba5 100644
--- a/spec/features/merge_request/user_merges_immediately_spec.rb
+++ b/spec/features/merge_request/user_merges_immediately_spec.rb
@@ -36,7 +36,7 @@ RSpec.describe 'Merge requests > User merges immediately', :js do
Sidekiq::Testing.fake! do
click_button 'Merge immediately'
- expect(find('.accept-merge-request.btn-info')).to have_content('Merge in progress')
+ expect(find('.accept-merge-request.btn-confirm')).to have_content('Merge in progress')
wait_for_requests
end
diff --git a/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb b/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
index 85eb956033b..d555519eb43 100644
--- a/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
+++ b/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
@@ -25,6 +25,8 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
}
end
+ let_it_be(:runner) { create(:ci_runner, :online) }
+
before do
stub_application_setting(auto_devops_enabled: false)
stub_ci_pipeline_yaml_file(YAML.dump(config))
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 d9b5ec17a4a..a85700fc721 100644
--- a/spec/features/merge_request/user_sees_merge_widget_spec.rb
+++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb
@@ -104,7 +104,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
before do
create(:service, project: project,
active: true,
- type: 'CiService',
+ type: 'DroneCiService',
category: 'ci')
visit project_merge_request_path(project, merge_request)
@@ -154,9 +154,9 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
end
it 'shows information about blocked pipeline' do
- expect(page).to have_content("Pipeline blocked")
+ expect(page).to have_content("Merge blocked")
expect(page).to have_content(
- "The pipeline for this merge request requires a manual action")
+ "pipeline must succeed. It's waiting for a manual action to continue.")
expect(page).to have_css('.ci-status-icon-manual')
end
end
@@ -274,10 +274,10 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
visit project_merge_request_path(project, merge_request)
end
- it 'has info button when MWBS button' do
+ it 'has confirm button when MWBS button' do
# Wait for the `ci_status` and `merge_check` requests
wait_for_requests
- expect(page).to have_selector('.accept-merge-request.btn-info')
+ expect(page).to have_selector('.accept-merge-request.btn-confirm')
end
end
@@ -432,7 +432,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
it 'user cannot remove source branch', :sidekiq_might_not_need_inline do
expect(page).not_to have_field('remove-source-branch-input')
- expect(page).to have_content('Deletes source branch')
+ expect(page).to have_content('The source branch will be deleted')
end
end
diff --git a/spec/features/merge_request/user_sees_versions_spec.rb b/spec/features/merge_request/user_sees_versions_spec.rb
index 8999c4d6656..34ae082750b 100644
--- a/spec/features/merge_request/user_sees_versions_spec.rb
+++ b/spec/features/merge_request/user_sees_versions_spec.rb
@@ -129,8 +129,8 @@ RSpec.describe 'Merge request > User sees versions', :js do
)
expect(page).to have_content '4 files'
- additions_content = page.find('.diff-stats.is-compare-versions-header .diff-stats-group .js-file-addition-line').text
- deletions_content = page.find('.diff-stats.is-compare-versions-header .diff-stats-group .js-file-deletion-line').text
+ additions_content = page.find('.diff-stats.is-compare-versions-header .diff-stats-group [data-testid="js-file-addition-line"]').text
+ deletions_content = page.find('.diff-stats.is-compare-versions-header .diff-stats-group [data-testid="js-file-deletion-line"]').text
expect(additions_content).to eq '15'
expect(deletions_content).to eq '6'
@@ -152,8 +152,8 @@ RSpec.describe 'Merge request > User sees versions', :js do
end
it 'show diff between new and old version' do
- additions_content = page.find('.diff-stats.is-compare-versions-header .diff-stats-group .js-file-addition-line').text
- deletions_content = page.find('.diff-stats.is-compare-versions-header .diff-stats-group .js-file-deletion-line').text
+ additions_content = page.find('.diff-stats.is-compare-versions-header .diff-stats-group [data-testid="js-file-addition-line"]').text
+ deletions_content = page.find('.diff-stats.is-compare-versions-header .diff-stats-group [data-testid="js-file-deletion-line"]').text
expect(page).to have_content '4 files'
expect(additions_content).to eq '15'
diff --git a/spec/features/merge_request/user_views_diffs_spec.rb b/spec/features/merge_request/user_views_diffs_spec.rb
index a0b3067994c..d5061657c59 100644
--- a/spec/features/merge_request/user_views_diffs_spec.rb
+++ b/spec/features/merge_request/user_views_diffs_spec.rb
@@ -66,6 +66,7 @@ RSpec.describe 'User views diffs', :js do
expect(page).to have_button('Expand all')
click_button 'Expand all'
+ wait_for_requests
expect(page).not_to have_button('Expand all')
end
diff --git a/spec/features/merge_requests/user_exports_as_csv_spec.rb b/spec/features/merge_requests/user_exports_as_csv_spec.rb
index 725b8366d04..351e714b612 100644
--- a/spec/features/merge_requests/user_exports_as_csv_spec.rb
+++ b/spec/features/merge_requests/user_exports_as_csv_spec.rb
@@ -12,15 +12,9 @@ RSpec.describe 'Merge Requests > Exports as CSV', :js do
visit(project_merge_requests_path(project))
end
- subject { page.find('.nav-controls') }
-
- it { is_expected.to have_selector '[data-testid="export-csv-button"]' }
-
context 'button is clicked' do
before do
- page.within('.nav-controls') do
- find('[data-testid="export-csv-button"]').click
- end
+ click_button 'Export as CSV'
end
it 'shows a success message' do
diff --git a/spec/features/nav/top_nav_responsive_spec.rb b/spec/features/nav/top_nav_responsive_spec.rb
new file mode 100644
index 00000000000..dfe3e76f172
--- /dev/null
+++ b/spec/features/nav/top_nav_responsive_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'top nav responsive', :js do
+ include MobileHelpers
+
+ let_it_be(:user) { create(:user) }
+
+ before do
+ stub_feature_flags(combined_menu: true)
+
+ sign_in(user)
+ visit explore_projects_path
+
+ resize_screen_xs
+ end
+
+ context 'before opened' do
+ it 'has page content and hides responsive menu', :aggregate_failures do
+ expect(page).to have_css('.page-title', text: 'Projects')
+ expect(page).to have_link('Dashboard', id: 'logo')
+
+ expect(page).to have_no_css('.top-nav-responsive')
+ end
+ end
+
+ context 'when opened' do
+ before do
+ click_button('Menu')
+ end
+
+ it 'hides everything and shows responsive menu', :aggregate_failures do
+ expect(page).to have_no_css('.page-title', text: 'Projects')
+ expect(page).to have_no_link('Dashboard', id: 'logo')
+
+ within '.top-nav-responsive' do
+ expect(page).to have_link(nil, href: search_path)
+ expect(page).to have_button('Projects')
+ expect(page).to have_button('Groups')
+ expect(page).to have_link('Snippets', href: dashboard_snippets_path)
+ end
+ end
+
+ it 'has new dropdown', :aggregate_failures do
+ click_button('New...')
+
+ expect(page).to have_link('New project', href: new_project_path)
+ expect(page).to have_link('New group', href: new_group_path)
+ expect(page).to have_link('New snippet', href: new_snippet_path)
+ end
+ end
+end
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index 84ea9495f08..0f453f1c1e5 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -70,7 +70,7 @@ RSpec.describe 'Profile account page', :js do
within('.feed-token-reset') do
previous_token = find("#feed_token").value
- accept_confirm { click_link('reset it') }
+ accept_confirm { find('[data-testid="reset_feed_token_link"]').click }
expect(find('#feed_token').value).not_to eq(previous_token)
end
@@ -89,7 +89,7 @@ RSpec.describe 'Profile account page', :js do
within('.incoming-email-token-reset') do
previous_token = find('#incoming_email_token').value
- accept_confirm { click_link('reset it') }
+ accept_confirm { find('[data-testid="reset_email_token_link"]').click }
expect(find('#incoming_email_token').value).not_to eq(previous_token)
end
diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb
index c85657c89d5..379c25d6002 100644
--- a/spec/features/profiles/personal_access_tokens_spec.rb
+++ b/spec/features/profiles/personal_access_tokens_spec.rb
@@ -22,6 +22,10 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
find("#feed_token").value
end
+ def feed_token_description
+ "Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs."
+ end
+
def disallow_personal_access_token_saves!
allow(PersonalAccessTokens::CreateService).to receive(:new).and_return(pat_create_service)
@@ -123,8 +127,9 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
allow(Gitlab::CurrentSettings).to receive(:disable_feed_token).and_return(false)
visit profile_personal_access_tokens_path
- expect(page).to have_content("Your feed token is used to authenticate you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar, and is included in those feed URLs.")
expect(feed_token).to eq(user.feed_token)
+
+ expect(page).to have_content(feed_token_description)
end
end
@@ -133,8 +138,8 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
allow(Gitlab::CurrentSettings).to receive(:disable_feed_token).and_return(true)
visit profile_personal_access_tokens_path
- expect(page).not_to have_content("Your feed token is used to authenticate you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar, and is included in those feed URLs.")
- expect(page).not_to have_css("#feed_token")
+ expect(page).to have_no_content(feed_token_description)
+ expect(page).to have_no_css("#feed_token")
end
end
end
diff --git a/spec/features/profiles/user_edit_profile_spec.rb b/spec/features/profiles/user_edit_profile_spec.rb
index dddca15ae24..d941988d12f 100644
--- a/spec/features/profiles/user_edit_profile_spec.rb
+++ b/spec/features/profiles/user_edit_profile_spec.rb
@@ -8,6 +8,8 @@ RSpec.describe 'User edit profile' do
let(:user) { create(:user) }
before do
+ stub_feature_flags(improved_emoji_picker: false)
+
sign_in(user)
visit(profile_path)
end
diff --git a/spec/features/profiles/user_search_settings_spec.rb b/spec/features/profiles/user_search_settings_spec.rb
index 64a8556e349..0b05e6c9489 100644
--- a/spec/features/profiles/user_search_settings_spec.rb
+++ b/spec/features/profiles/user_search_settings_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe 'User searches their settings', :js do
visit profile_path
end
- it_behaves_like 'can search settings', 'Public Avatar', 'Main settings'
+ it_behaves_like 'can search settings', 'Public avatar', 'Main settings'
end
context 'in preferences page' do
diff --git a/spec/features/projects/active_tabs_spec.rb b/spec/features/projects/active_tabs_spec.rb
index 96a321037a9..b333f64aa87 100644
--- a/spec/features/projects/active_tabs_spec.rb
+++ b/spec/features/projects/active_tabs_spec.rb
@@ -18,12 +18,11 @@ RSpec.describe 'Project active tab' do
end
context 'on project Home' do
- context 'when feature flag :sidebar_refactor is enabled' do
- before do
- visit project_path(project)
- end
+ it 'activates Project scope menu' do
+ visit project_path(project)
- it_behaves_like 'page has active tab', 'Project'
+ 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
@@ -36,11 +35,23 @@ RSpec.describe 'Project active tab' do
it_behaves_like 'page has active tab', 'Project'
it_behaves_like 'page has active sub tab', 'Details'
end
+ end
- context 'on project Home/Activity' do
+ context 'on Project information' do
+ context 'default link' do
before do
visit project_path(project)
- click_tab('Activity')
+
+ click_link('Project information', match: :first)
+ end
+
+ it_behaves_like 'page has active tab', 'Project'
+ it_behaves_like 'page has active sub tab', 'Activity'
+ end
+
+ context 'on Project information/Activity' do
+ before do
+ visit activity_project_path(project)
end
it_behaves_like 'page has active tab', 'Project'
diff --git a/spec/features/projects/badges/pipeline_badge_spec.rb b/spec/features/projects/badges/pipeline_badge_spec.rb
index bfc924b5d9b..9d8f9872a1a 100644
--- a/spec/features/projects/badges/pipeline_badge_spec.rb
+++ b/spec/features/projects/badges/pipeline_badge_spec.rb
@@ -68,7 +68,7 @@ RSpec.describe 'Pipeline Badge' do
visit pipeline_project_badges_path(project, ref: ref, format: :svg)
expect(page.status_code).to eq(200)
- expect(page.response_headers['Cache-Control']).to include 'no-cache'
+ expect(page.response_headers['Cache-Control']).to eq('no-store')
end
end
diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb
index 3598aa2f423..595304789a6 100644
--- a/spec/features/projects/blobs/blob_show_spec.rb
+++ b/spec/features/projects/blobs/blob_show_spec.rb
@@ -172,7 +172,7 @@ RSpec.describe 'File blob', :js do
end
end
- context 'sucessfully change ref of similar name' do
+ context 'successfully change ref of similar name' do
before do
project.repository.create_branch('dev')
project.repository.create_branch('development')
@@ -182,14 +182,32 @@ RSpec.describe 'File blob', :js do
visit_blob('files/js/application.js', ref: 'development')
switch_ref_to('dev')
- expect(page.find('.file-title-name').text).to eq('application.js')
+ aggregate_failures do
+ expect(page.find('.file-title-name').text).to eq('application.js')
+ expect(page).not_to have_css('flash-container')
+ end
end
it 'switch ref from shorter to longer ref name' do
visit_blob('files/js/application.js', ref: 'dev')
switch_ref_to('development')
+ aggregate_failures do
+ expect(page.find('.file-title-name').text).to eq('application.js')
+ expect(page).not_to have_css('flash-container')
+ end
+ end
+ end
+
+ it 'successfully changes ref when the ref name matches the project name' do
+ project.repository.create_branch(project.name)
+
+ visit_blob('files/js/application.js', ref: project.name)
+ switch_ref_to('master')
+
+ aggregate_failures do
expect(page.find('.file-title-name').text).to eq('application.js')
+ expect(page).not_to have_css('flash-container')
end
end
end
diff --git a/spec/features/projects/branches/user_deletes_branch_spec.rb b/spec/features/projects/branches/user_deletes_branch_spec.rb
index 53994ec018e..3b8f49accc5 100644
--- a/spec/features/projects/branches/user_deletes_branch_spec.rb
+++ b/spec/features/projects/branches/user_deletes_branch_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe "User deletes branch", :js do
sign_in(user)
end
- it "deletes branch" do
+ it "deletes branch", :js do
visit(project_branches_path(project))
branch_search = find('input[data-testid="branch-search"]')
@@ -21,11 +21,38 @@ RSpec.describe "User deletes branch", :js do
branch_search.native.send_keys(:enter)
page.within(".js-branch-improve\\/awesome") do
- accept_alert { find(".btn-danger").click }
+ find('.js-delete-branch-button').click
+ end
+
+ page.within '.modal-footer' do
+ click_button 'Yes, delete branch'
end
wait_for_requests
- expect(page).to have_css(".js-branch-improve\\/awesome", visible: :hidden)
+ expect(page).to have_content('Branch was deleted')
+ end
+
+ context 'when the feature flag :delete_branch_confirmation_modals is disabled' do
+ before do
+ stub_feature_flags(delete_branch_confirmation_modals: false)
+ end
+
+ it "deletes branch" do
+ visit(project_branches_path(project))
+
+ branch_search = find('input[data-testid="branch-search"]')
+
+ branch_search.set('improve/awesome')
+ branch_search.native.send_keys(:enter)
+
+ page.within(".js-branch-improve\\/awesome") do
+ accept_alert { click_link(title: 'Delete branch') }
+ end
+
+ wait_for_requests
+
+ expect(page).to have_css(".js-branch-improve\\/awesome", visible: :hidden)
+ end
end
end
diff --git a/spec/features/projects/branches/user_views_branches_spec.rb b/spec/features/projects/branches/user_views_branches_spec.rb
index 19d96579785..d0c0a0860d9 100644
--- a/spec/features/projects/branches/user_views_branches_spec.rb
+++ b/spec/features/projects/branches/user_views_branches_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-RSpec.describe "User views branches" do
+RSpec.describe "User views branches", :js do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { project.owner }
@@ -10,9 +10,12 @@ RSpec.describe "User views branches" do
sign_in(user)
end
- context "all branches" do
+ context "all branches", :js do
before do
visit(project_branches_path(project))
+ branch_search = find('input[data-testid="branch-search"]')
+ branch_search.set('master')
+ branch_search.native.send_keys(:enter)
end
it "shows branches" do
@@ -20,6 +23,10 @@ RSpec.describe "User views branches" do
expect(page.all(".graph-side")).to all( have_content(/\d+/) )
end
+
+ it "displays a disabled button with a tooltip for the default branch that cannot be deleted", :js do
+ expect(page).to have_button('The default branch cannot be deleted', disabled: true)
+ end
end
context "protected branches" do
diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb
index f805416b03d..0a79719f14a 100644
--- a/spec/features/projects/branches_spec.rb
+++ b/spec/features/projects/branches_spec.rb
@@ -88,10 +88,7 @@ RSpec.describe 'Branches' do
it 'shows filtered branches', :js do
visit project_branches_path(project)
- branch_search = find('input[data-testid="branch-search"]')
-
- branch_search.set('fix')
- branch_search.native.send_keys(:enter)
+ search_for_branch('fix')
expect(page).to have_content('fix')
expect(find('.all-branches')).to have_selector('li', count: 1)
@@ -99,13 +96,14 @@ RSpec.describe 'Branches' do
end
describe 'Delete unprotected branch on Overview' do
- it 'removes branch after confirmation', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/239019' do
+ it 'removes branch after confirmation', :js do
visit project_branches_filtered_path(project, state: 'all')
expect(all('.all-branches').last).to have_selector('li', count: 20)
- accept_confirm { first('.js-branch-item .btn-danger').click }
- expect(all('.all-branches').last).to have_selector('li', count: 19)
+ delete_branch_and_confirm
+
+ expect(page).to have_content('Branch was deleted')
end
end
@@ -151,10 +149,7 @@ RSpec.describe 'Branches' do
it 'shows filtered branches', :js do
visit project_branches_filtered_path(project, state: 'all')
- branch_search = find('input[data-testid="branch-search"]')
-
- branch_search.set('fix')
- branch_search.native.send_keys(:enter)
+ search_for_branch('fix')
expect(page).to have_content('fix')
expect(find('.all-branches')).to have_selector('li', count: 1)
@@ -165,17 +160,39 @@ RSpec.describe 'Branches' do
it 'removes branch after confirmation', :js do
visit project_branches_filtered_path(project, state: 'all')
- branch_search = find('input[data-testid="branch-search"]')
+ search_for_branch('fix')
- branch_search.set('fix')
- branch_search.native.send_keys(:enter)
+ expect(all('.all-branches').last).to have_selector('li', count: 1)
- expect(page).to have_content('fix')
- expect(find('.all-branches')).to have_selector('li', count: 1)
- accept_confirm { find('.js-branch-fix .btn-danger').click }
+ delete_branch_and_confirm
+
+ expect(page).to have_content('Branch was deleted')
+
+ page.refresh
+
+ search_for_branch('fix')
expect(page).not_to have_content('fix')
- expect(find('.all-branches')).to have_selector('li', count: 0)
+ expect(all('.all-branches').last).to have_selector('li', count: 0)
+ end
+
+ context 'when the delete_branch_confirmation_modals feature flag is disabled' do
+ it 'removes branch after confirmation', :js do
+ stub_feature_flags(delete_branch_confirmation_modals: false)
+
+ visit project_branches_filtered_path(project, state: 'all')
+
+ search_for_branch('fix')
+
+ expect(page).to have_content('fix')
+ expect(find('.all-branches')).to have_selector('li', count: 1)
+ accept_confirm do
+ within('.js-branch-item', match: :first) { click_link(title: 'Delete branch') }
+ end
+
+ expect(page).not_to have_content('fix')
+ expect(find('.all-branches')).to have_selector('li', count: 0)
+ end
end
end
@@ -323,4 +340,18 @@ RSpec.describe 'Branches' do
def create_file(message: 'message', branch_name:)
repository.create_file(user, generate(:branch), 'content', message: message, branch_name: branch_name)
end
+
+ def search_for_branch(name)
+ branch_search = find('input[data-testid="branch-search"]')
+ branch_search.set(name)
+ branch_search.native.send_keys(:enter)
+ end
+
+ def delete_branch_and_confirm
+ find('.js-delete-branch-button', match: :first).click
+
+ within '.modal-footer' do
+ click_button 'Yes, delete branch'
+ end
+ end
end
diff --git a/spec/features/projects/clusters/applications_spec.rb b/spec/features/projects/clusters/applications_spec.rb
deleted file mode 100644
index 74b477dd85d..00000000000
--- a/spec/features/projects/clusters/applications_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require_relative '../../../../spec/features/clusters/installing_applications_shared_examples'
-
-RSpec.describe 'Project-level Cluster Applications', :js do
- include GoogleApi::CloudPlatformHelpers
-
- let(:project) { create(:project) }
- let(:user) { create(:user) }
-
- before do
- project.add_maintainer(user)
- sign_in(user)
- end
-
- describe 'Installing applications' do
- include_examples "installing applications on a cluster" do
- let(:cluster_path) { project_cluster_path(project, cluster) }
- let(:cluster_factory_args) { [projects: [project]] }
- end
- end
-end
diff --git a/spec/features/projects/confluence/user_views_confluence_page_spec.rb b/spec/features/projects/confluence/user_views_confluence_page_spec.rb
index 7ec724ed55d..ece2f82f5c6 100644
--- a/spec/features/projects/confluence/user_views_confluence_page_spec.rb
+++ b/spec/features/projects/confluence/user_views_confluence_page_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe 'User views the Confluence page' do
end
it 'shows the page when the Confluence integration is enabled' do
- service = create(:confluence_service, project: project)
+ service = create(:confluence_integration, project: project)
visit project_wikis_confluence_path(project)
diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb
index 1d7be7fa7a3..fea054de64e 100644
--- a/spec/features/projects/environments/environment_spec.rb
+++ b/spec/features/projects/environments/environment_spec.rb
@@ -329,11 +329,11 @@ RSpec.describe 'Environment' do
expect(page).to have_button('Stop')
end
- it 'user deletes the branch with running environment' do
+ it 'user deletes the branch with running environment', :js do
visit project_branches_filtered_path(project, state: 'all', search: 'feature')
remove_branch_with_hooks(project, user, 'feature') do
- page.within('.js-branch-feature') { find('a.btn-danger').click }
+ page.within('.js-branch-feature') { find('.js-delete-branch-button').click }
end
visit_environment(environment)
@@ -341,6 +341,24 @@ RSpec.describe 'Environment' do
expect(page).not_to have_button('Stop')
end
+ context 'when the feature flag :delete_branch_confirmation_modals is disabled' do
+ before do
+ stub_feature_flags(delete_branch_confirmation_modals: false)
+ end
+
+ it 'user deletes the branch with running environment' do
+ visit project_branches_filtered_path(project, state: 'all', search: 'feature')
+
+ remove_branch_with_hooks(project, user, 'feature') do
+ within('.js-branch-feature') { click_link(title: 'Delete branch') }
+ end
+
+ visit_environment(environment)
+
+ expect(page).not_to have_button('Stop')
+ end
+ end
+
##
# This is a workaround for problem described in #24543
#
diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb
index de7ff1c473d..0dd4bd55d46 100644
--- a/spec/features/projects/environments/environments_spec.rb
+++ b/spec/features/projects/environments/environments_spec.rb
@@ -81,7 +81,7 @@ RSpec.describe 'Environments page', :js do
context 'when cluster is not reachable' do
let!(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
- let!(:application_prometheus) { create(:clusters_applications_prometheus, :installed, cluster: cluster) }
+ let!(:integration_prometheus) { create(:clusters_integrations_prometheus, cluster: cluster) }
before do
allow_next_instance_of(Kubeclient::Client) do |instance|
diff --git a/spec/features/projects/environments_pod_logs_spec.rb b/spec/features/projects/environments_pod_logs_spec.rb
index eaef3e6ca28..5019e45593c 100644
--- a/spec/features/projects/environments_pod_logs_spec.rb
+++ b/spec/features/projects/environments_pod_logs_spec.rb
@@ -40,7 +40,7 @@ RSpec.describe 'Environment > Pod Logs', :js, :kubeclient do
dropdown_items = find(".dropdown-menu").all(".dropdown-item")
expect(dropdown_items.first).to have_content(environment.name)
- expect(dropdown_items.size).to eq(3)
+ expect(dropdown_items.size).to eq(2)
end
end
diff --git a/spec/features/projects/feature_flag_user_lists/user_deletes_feature_flag_user_list_spec.rb b/spec/features/projects/feature_flag_user_lists/user_deletes_feature_flag_user_list_spec.rb
index 2a81c706525..37d6f299883 100644
--- a/spec/features/projects/feature_flag_user_lists/user_deletes_feature_flag_user_list_spec.rb
+++ b/spec/features/projects/feature_flag_user_lists/user_deletes_feature_flag_user_list_spec.rb
@@ -17,12 +17,13 @@ RSpec.describe 'User deletes feature flag user list', :js do
end
it 'deletes the list' do
- visit(project_feature_flags_path(project, scope: 'userLists'))
+ visit(project_feature_flags_user_lists_path(project, scope: 'userLists'))
delete_user_list_button.click
delete_user_list_modal_confirmation_button.click
- expect(page).to have_text('Lists 0')
+ expect(page).to have_text('Lists')
+ expect(page).not_to have_selector('[data-testid="ffUserListName"]')
end
end
@@ -34,7 +35,7 @@ RSpec.describe 'User deletes feature flag user list', :js do
end
it 'does not delete the list' do
- visit(project_feature_flags_path(project, scope: 'userLists'))
+ visit(project_feature_flags_user_lists_path(project, scope: 'userLists'))
delete_user_list_button.click
delete_user_list_modal_confirmation_button.click
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 50fc7bb0753..d922bc1f4a0 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
@@ -18,65 +18,21 @@ RSpec.describe 'User sees feature flag list', :js do
context 'with legacy feature flags' do
before do
- create_flag(project, 'ci_live_trace', false).tap do |feature_flag|
+ create_flag(project, 'ci_live_trace', false, version: :legacy_flag).tap do |feature_flag|
create_scope(feature_flag, 'review/*', true)
end
- create_flag(project, 'drop_legacy_artifacts', false)
- create_flag(project, 'mr_train', true).tap do |feature_flag|
+ 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)
end
end
- it 'user sees the first flag' do
- visit(project_feature_flags_path(project))
-
- 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-qa-selector="feature-flag-scope-muted-badge"]:nth-child(1)')).to have_content('*')
- expect(page.find('[data-qa-selector="feature-flag-scope-info-badge"]:nth-child(2)')).to have_content('review/*')
- end
- end
- end
-
- it 'user sees 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
-
- within_feature_flag_scopes do
- expect(page.find('[data-qa-selector="feature-flag-scope-muted-badge"]:nth-child(1)')).to have_content('*')
- end
- end
- end
-
- it 'user sees 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-qa-selector="feature-flag-scope-info-badge"]:nth-child(1)')).to have_content('*')
- expect(page.find('[data-qa-selector="feature-flag-scope-muted-badge"]:nth-child(2)')).to have_content('production')
- end
- end
- end
-
- it 'user sees the status toggle disabled' do
+ it 'shows empty page' do
visit(project_feature_flags_path(project))
- within_feature_flag_row(1) do
- expect_status_toggle_button_to_be_disabled
- end
+ 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')
end
end
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 a435e565ff1..9c03a26abc8 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
@@ -73,16 +73,16 @@ RSpec.describe 'User updates feature flag', :js do
context 'with a legacy feature flag' do
let!(:feature_flag) do
create_flag(project, 'ci_live_trace', true,
- description: 'For live trace feature')
+ description: 'For live trace feature',
+ version: :legacy_flag)
end
let!(:scope) { create_scope(feature_flag, 'review/*', true) }
- it 'the user cannot edit the flag' do
+ it 'shows not found error' do
visit(edit_project_feature_flag_path(project, feature_flag))
- expect(page).to have_text 'This feature flag is read-only, and it will be removed in 14.0.'
- expect(page).to have_css('button.js-ff-submit.disabled')
+ expect(page).to have_text 'Page Not Found'
end
end
end
diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb
index 363fe8c35fe..2e5a5cef0fd 100644
--- a/spec/features/projects/features_visibility_spec.rb
+++ b/spec/features/projects/features_visibility_spec.rb
@@ -43,7 +43,7 @@ RSpec.describe 'Edit Project Settings' do
context 'When external issue tracker is enabled and issues enabled on project settings' do
it 'does not hide issues tab and hides labels tab' do
allow_next_instance_of(Project) do |instance|
- allow(instance).to receive(:external_issue_tracker).and_return(JiraService.new)
+ allow(instance).to receive(:external_issue_tracker).and_return(Integrations::Jira.new)
end
visit project_path(project)
@@ -58,7 +58,7 @@ RSpec.describe 'Edit Project Settings' do
project.issues_enabled = false
project.save!
allow_next_instance_of(Project) do |instance|
- allow(instance).to receive(:external_issue_tracker).and_return(JiraService.new)
+ allow(instance).to receive(:external_issue_tracker).and_return(Integrations::Jira.new)
end
end
diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb
index af228764c17..25836514981 100644
--- a/spec/features/projects/import_export/import_file_spec.rb
+++ b/spec/features/projects/import_export/import_file_spec.rb
@@ -30,14 +30,14 @@ RSpec.describe 'Import/Export - project import integration test', :js do
it 'user imports an exported project successfully', :sidekiq_might_not_need_inline do
visit new_project_path
- click_import_project_tab
+ click_import_project
click_link 'GitLab export'
fill_in :name, with: 'Test Project Name', visible: true
fill_in :path, with: 'test-project-path', visible: true
attach_file('file', file)
- expect { click_on 'Import project' }.to change { Project.count }.by(1)
+ expect { click_button 'Import project' }.to change { Project.count }.by(1)
project = Project.last
expect(project).not_to be_nil
@@ -49,11 +49,11 @@ RSpec.describe 'Import/Export - project import integration test', :js do
visit new_project_path
- click_import_project_tab
+ click_import_project
click_link 'GitLab export'
fill_in :name, with: project.name, visible: true
attach_file('file', file)
- click_on 'Import project'
+ click_button 'Import project'
page.within('.flash-container') do
expect(page).to have_content('Project could not be imported')
@@ -61,7 +61,7 @@ RSpec.describe 'Import/Export - project import integration test', :js do
end
end
- def click_import_project_tab
+ def click_import_project
find('[data-qa-selector="import_project_link"]').click
end
end
diff --git a/spec/features/projects/infrastructure_registry_spec.rb b/spec/features/projects/infrastructure_registry_spec.rb
new file mode 100644
index 00000000000..9cab4ebeb3a
--- /dev/null
+++ b/spec/features/projects/infrastructure_registry_spec.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Infrastructure Registry' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+
+ before do
+ sign_in(user)
+ project.add_maintainer(user)
+ end
+
+ context 'when feature is not available' do
+ before do
+ stub_feature_flags(infrastructure_registry_page: false)
+ end
+
+ it 'gives 404' do
+ visit_project_infrastructure_registry
+
+ expect(status_code).to eq(404)
+ end
+ end
+
+ context 'when feature is available', :js do
+ before do
+ visit_project_infrastructure_registry
+ end
+
+ context 'when there are packages' 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 'deleting a package' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:terraform_module) { create(:terraform_module_package, project: project) }
+
+ it 'allows you to delete a module', :aggregate_failures do
+ # this is still using the package copy in the UI too
+ click_button('Remove package')
+ click_button('Delete package')
+
+ expect(page).to have_content 'Package deleted successfully'
+ expect(page).not_to have_content(terraform_module.name)
+ end
+ end
+ end
+
+ it 'displays the empty message' do
+ expect(page).to have_content('You have no Terraform modules in your project')
+ end
+ end
+
+ def visit_project_infrastructure_registry
+ visit project_infrastructure_registry_index_path(project)
+ end
+end
diff --git a/spec/features/projects/services/user_activates_flowdock_spec.rb b/spec/features/projects/integrations/user_activates_flowdock_spec.rb
index 4a4d7bbecfd..4a4d7bbecfd 100644
--- a/spec/features/projects/services/user_activates_flowdock_spec.rb
+++ b/spec/features/projects/integrations/user_activates_flowdock_spec.rb
diff --git a/spec/features/projects/services/user_activates_jira_spec.rb b/spec/features/projects/integrations/user_activates_jira_spec.rb
index 10f84aae93f..10f84aae93f 100644
--- a/spec/features/projects/services/user_activates_jira_spec.rb
+++ b/spec/features/projects/integrations/user_activates_jira_spec.rb
diff --git a/spec/features/projects/services/user_activates_pivotaltracker_spec.rb b/spec/features/projects/integrations/user_activates_pivotaltracker_spec.rb
index 83f66d4fa7b..83f66d4fa7b 100644
--- a/spec/features/projects/services/user_activates_pivotaltracker_spec.rb
+++ b/spec/features/projects/integrations/user_activates_pivotaltracker_spec.rb
diff --git a/spec/features/projects/members/invite_group_spec.rb b/spec/features/projects/members/invite_group_spec.rb
index 4caf3e947c7..6ce6834b5d5 100644
--- a/spec/features/projects/members/invite_group_spec.rb
+++ b/spec/features/projects/members/invite_group_spec.rb
@@ -32,6 +32,14 @@ RSpec.describe 'Project > Members > Invite group', :js do
expect(page).to have_selector(expected_invite_group_selector)
end
+
+ it 'does not display either the form or the button when visiting the page not signed in' do
+ project = create(:project, namespace: create(:group))
+
+ visit project_project_members_path(project)
+
+ expect(page).not_to have_selector(expected_invite_group_selector)
+ end
end
describe 'Share with group lock' do
diff --git a/spec/features/projects/members/list_spec.rb b/spec/features/projects/members/list_spec.rb
index f1fc579bb8a..25598146604 100644
--- a/spec/features/projects/members/list_spec.rb
+++ b/spec/features/projects/members/list_spec.rb
@@ -6,17 +6,17 @@ RSpec.describe 'Project members list', :js do
include Spec::Support::Helpers::Features::MembersHelpers
include Spec::Support::Helpers::Features::InviteMembersModalHelper
- let(:user1) { create(:user, name: 'John Doe') }
- let(:user2) { create(:user, name: 'Mary Jane') }
- let(:group) { create(:group) }
- let(:project) { create(:project, :internal, namespace: group) }
+ let_it_be(:user1) { create(:user, name: 'John Doe') }
+ let_it_be(:user2) { create(:user, name: 'Mary Jane') }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, :internal, namespace: group) }
before do
sign_in(user1)
group.add_owner(user1)
end
- it 'show members from project and group' do
+ it 'show members from project and group', :aggregate_failures do
project.add_developer(user2)
visit_members_page
@@ -25,7 +25,7 @@ RSpec.describe 'Project members list', :js do
expect(second_row).to have_content(user2.name)
end
- it 'show user once if member of both group and project' do
+ it 'show user once if member of both group and project', :aggregate_failures do
project.add_developer(user1)
visit_members_page
@@ -47,7 +47,7 @@ RSpec.describe 'Project members list', :js do
end
end
- it 'add user to project' do
+ it 'add user to project', :snowplow, :aggregate_failures do
visit_members_page
invite_member(user2.name, role: 'Reporter')
@@ -55,9 +55,17 @@ RSpec.describe 'Project members list', :js do
page.within find_member_row(user2) do
expect(page).to have_button('Reporter')
end
+
+ expect_snowplow_event(
+ category: 'Members::CreateService',
+ action: 'create_member',
+ label: 'project-members-page',
+ property: 'existing_user',
+ user: user1
+ )
end
- it 'uses ProjectMember access_level_roles for the invite members modal access option' do
+ it 'uses ProjectMember access_level_roles for the invite members modal access option', :aggregate_failures do
visit_members_page
click_on 'Invite members'
@@ -95,7 +103,7 @@ RSpec.describe 'Project members list', :js do
expect(members_table).not_to have_content(other_user.name)
end
- it 'invite user to project' do
+ it 'invite user to project', :snowplow, :aggregate_failures do
visit_members_page
invite_member('test@example.com', role: 'Reporter')
@@ -105,6 +113,28 @@ RSpec.describe 'Project members list', :js do
page.within find_invited_member_row('test@example.com') do
expect(page).to have_button('Reporter')
end
+
+ expect_snowplow_event(
+ category: 'Members::InviteService',
+ action: 'create_member',
+ label: 'project-members-page',
+ property: 'net_new_user',
+ user: user1
+ )
+ end
+
+ context 'as a signed out visitor viewing a public project' do
+ let_it_be(:project) { create(:project, :public) }
+
+ before do
+ sign_out(user1)
+ end
+
+ it 'does not show the Invite members button when not signed in' do
+ visit_members_page
+
+ expect(page).not_to have_button('Invite members')
+ end
end
context 'project bots' do
@@ -114,7 +144,7 @@ RSpec.describe 'Project members list', :js do
project.add_maintainer(project_bot)
end
- it 'does not show form used to change roles and "Expiration date" or the remove user button' do
+ it 'does not show form used to change roles and "Expiration date" or the remove user button', :aggregate_failures do
visit_members_page
page.within find_member_row(project_bot) do
diff --git a/spec/features/projects/members/tabs_spec.rb b/spec/features/projects/members/tabs_spec.rb
index 471be26e126..5611e7ee810 100644
--- a/spec/features/projects/members/tabs_spec.rb
+++ b/spec/features/projects/members/tabs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Projects > Members > Tabs' do
+RSpec.describe 'Projects > Members > Tabs', :js do
include Spec::Support::Helpers::Features::MembersHelpers
using RSpec::Parameterized::TableSyntax
@@ -44,7 +44,7 @@ RSpec.describe 'Projects > Members > Tabs' do
end
end
- context 'when searching "Groups"', :js do
+ context 'when searching "Groups"' do
before do
click_link 'Groups'
diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb
index 7073741a92d..94543290050 100644
--- a/spec/features/projects/members/user_requests_access_spec.rb
+++ b/spec/features/projects/members/user_requests_access_spec.rb
@@ -3,8 +3,9 @@
require 'spec_helper'
RSpec.describe 'Projects > Members > User requests access', :js do
- let(:user) { create(:user) }
- let(:project) { create(:project, :public, :repository) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :public, :repository) }
+
let(:maintainer) { project.owner }
before do
@@ -47,6 +48,8 @@ RSpec.describe 'Projects > Members > User requests access', :js do
expect(project.requesters.exists?(user_id: user)).to be_truthy
+ click_link 'Project information'
+
page.within('.nav-sidebar') do
click_link('Members')
end
diff --git a/spec/features/projects/navbar_spec.rb b/spec/features/projects/navbar_spec.rb
index ee5bf99fd75..bce11e6bc8a 100644
--- a/spec/features/projects/navbar_spec.rb
+++ b/spec/features/projects/navbar_spec.rb
@@ -17,6 +17,10 @@ RSpec.describe 'Project navbar' do
end
context 'when sidebar refactor feature flag is disabled' do
+ let(:project_context_nav_item) do
+ nil
+ end
+
before do
stub_feature_flags(sidebar_refactor: false)
insert_package_nav(_('Operations'))
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index a1523f9eb08..c57432ae94e 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe 'New project', :js do
include Select2Helper
+ include Spec::Support::Helpers::Features::TopNavSpecHelpers
shared_examples 'combined_menu: feature flag examples' do
context 'as a user' do
@@ -45,34 +46,39 @@ RSpec.describe 'New project', :js do
end
it 'when in control it renders "project" in the new projects dropdown' do
- pending_on_combined_menu_flag
-
stub_experiments(new_repo: :control)
visit new_project_path
- find('#nav-projects-dropdown').click
-
- page.within('#nav-projects-dropdown') do
- 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')
+ 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
- pending_on_combined_menu_flag
-
stub_experiments(new_repo: :candidate)
visit new_project_path
- find('#nav-projects-dropdown').click
+ open_top_nav_projects
- page.within('#nav-projects-dropdown') do
- expect(page).to have_selector('a', text: 'Create blank project/repository')
- expect(page).to have_selector('a', text: 'Import project/repository')
+ 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
@@ -356,16 +362,6 @@ 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'
- fill_in 'project_name', with: 'import-project-without-git-suffix'
- fill_in 'project_path', with: 'import-project-without-git-suffix'
-
- click_button 'Create project'
-
- expect(page).to have_text('Please provide a valid URL ending with .git')
- end
-
it 'keeps "Import project" tab open after form validation error' do
collision_project = create(:project, name: 'test-name-collision', namespace: user.namespace)
@@ -422,7 +418,7 @@ RSpec.describe 'New project', :js do
end
end
- context 'with combined_menu: feature flag on' do
+ context 'with combined_menu feature flag on' do
let(:needs_rewrite_for_combined_menu_flag_on) { true }
before do
@@ -441,8 +437,4 @@ RSpec.describe 'New project', :js do
it_behaves_like 'combined_menu: feature flag examples'
end
-
- def pending_on_combined_menu_flag
- pending 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56587' if needs_rewrite_for_combined_menu_flag_on
- end
end
diff --git a/spec/features/projects/pages/user_edits_settings_spec.rb b/spec/features/projects/pages/user_edits_settings_spec.rb
index 412ba17cf20..71d4cce2784 100644
--- a/spec/features/projects/pages/user_edits_settings_spec.rb
+++ b/spec/features/projects/pages/user_edits_settings_spec.rb
@@ -39,12 +39,6 @@ RSpec.describe 'Pages edits pages settings', :js do
end
end
- it 'renders first deployment warning' do
- visit project_pages_path(project)
-
- expect(page).to have_content('It may take up to 30 minutes before the site is available after the first deployment.')
- end
-
shared_examples 'does not render access control warning' do
it 'does not render access control warning' do
visit project_pages_path(project)
diff --git a/spec/features/projects/releases/user_views_releases_spec.rb b/spec/features/projects/releases/user_views_releases_spec.rb
index d8a55fc7f3b..fcb1b6a0015 100644
--- a/spec/features/projects/releases/user_views_releases_spec.rb
+++ b/spec/features/projects/releases/user_views_releases_spec.rb
@@ -19,129 +19,147 @@ RSpec.describe 'User views releases', :js do
project.add_guest(guest)
end
- context('when the user is a maintainer') do
- before do
- sign_in(maintainer)
-
- visit project_releases_path(project)
- end
+ shared_examples 'releases index page' do
+ context('when the user is a maintainer') do
+ before do
+ sign_in(maintainer)
- it 'sees the release' do
- page.within("##{release_v1.tag}") do
- expect(page).to have_content(release_v1.name)
- expect(page).to have_content(release_v1.tag)
- expect(page).not_to have_content('Upcoming Release')
+ visit project_releases_path(project)
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 '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"]')
+ it 'sees the release' do
+ page.within("##{release_v1.tag}") do
+ expect(page).to have_content(release_v1.name)
+ expect(page).to have_content(release_v1.tag)
+ expect(page).not_to have_content('Upcoming Release')
end
end
- 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) }
+ 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 'sees the link', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/329301' do
+ 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
- end
- context 'when url points to external resource' do
- let(:url) { 'http://google.com/download' }
+ 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" }
- 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"]')
+ 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
end
end
- end
- context 'with an upcoming release' do
- it 'sees the upcoming tag' do
- page.within("##{release_v3.tag}") do
- expect(page).to have_content('Upcoming Release')
+ context 'with an upcoming release' do
+ it 'sees the upcoming tag' do
+ page.within("##{release_v3.tag}") do
+ expect(page).to have_content('Upcoming Release')
+ end
end
end
- end
- context 'with a tag containing a slash' do
- it 'sees the release' do
- page.within("##{release_v2.tag.parameterize}") do
- expect(page).to have_content(release_v2.name)
- expect(page).to have_content(release_v2.tag)
+ context 'with a tag containing a slash' do
+ it 'sees the release' do
+ page.within("##{release_v2.tag.parameterize}") do
+ expect(page).to have_content(release_v2.name)
+ expect(page).to have_content(release_v2.tag)
+ end
end
end
- end
- context 'sorting' do
- def sort_page(by:, direction:)
- within '[data-testid="releases-sort"]' do
- find('.dropdown-toggle').click
+ context 'sorting' do
+ def sort_page(by:, direction:)
+ within '[data-testid="releases-sort"]' do
+ find('.dropdown-toggle').click
- click_button(by, class: 'dropdown-item')
+ click_button(by, class: 'dropdown-item')
- find('.sorting-direction-button').click if direction == :ascending
+ find('.sorting-direction-button').click if direction == :ascending
+ end
end
- end
- shared_examples 'releases sort order' do
- it "sorts the releases #{description}" do
- card_titles = page.all('.release-block .card-title', minimum: expected_releases.count)
+ shared_examples 'releases sort order' do
+ it "sorts the releases #{description}" do
+ card_titles = page.all('.release-block .card-title', minimum: expected_releases.count)
- card_titles.each_with_index do |title, index|
- expect(title).to have_content(expected_releases[index].name)
+ card_titles.each_with_index do |title, index|
+ expect(title).to have_content(expected_releases[index].name)
+ end
end
end
- end
- context "when the page is sorted by the default sort order" do
- let(:expected_releases) { [release_v3, release_v2, release_v1] }
+ context "when the page is sorted by the default sort order" do
+ let(:expected_releases) { [release_v3, release_v2, release_v1] }
- it_behaves_like 'releases sort order'
- end
+ it_behaves_like 'releases sort order'
+ end
- context "when the page is sorted by created_at ascending " do
- let(:expected_releases) { [release_v2, release_v1, release_v3] }
+ context "when the page is sorted by created_at ascending " do
+ let(:expected_releases) { [release_v2, release_v1, release_v3] }
- before do
- sort_page by: 'Created date', direction: :ascending
+ before do
+ sort_page by: 'Created date', direction: :ascending
+ end
+
+ it_behaves_like 'releases sort order'
end
+ end
+ end
+
+ context('when the user is a guest') do
+ before do
+ sign_in(guest)
+ end
+
+ it 'renders release info except for Git-related data' do
+ visit project_releases_path(project)
+
+ within('.release-block', match: :first) do
+ expect(page).to have_content(release_v3.description)
- it_behaves_like 'releases sort order'
+ # The following properties (sometimes) include Git info,
+ # so they are not rendered for Guest users
+ expect(page).not_to have_content(release_v3.name)
+ expect(page).not_to have_content(release_v3.tag)
+ expect(page).not_to have_content(release_v3.commit.short_id)
+ end
end
end
end
- context('when the user is a guest') do
+ context 'when the releases_index_apollo_client feature flag is enabled' do
before do
- sign_in(guest)
+ stub_feature_flags(releases_index_apollo_client: true)
end
- it 'renders release info except for Git-related data' do
- visit project_releases_path(project)
-
- within('.release-block', match: :first) do
- expect(page).to have_content(release_v3.description)
+ it_behaves_like 'releases index page'
+ end
- # The following properties (sometimes) include Git info,
- # so they are not rendered for Guest users
- expect(page).not_to have_content(release_v3.name)
- expect(page).not_to have_content(release_v3.tag)
- expect(page).not_to have_content(release_v3.commit.short_id)
- end
+ context 'when the releases_index_apollo_client feature flag is disabled' do
+ before do
+ stub_feature_flags(releases_index_apollo_client: false)
end
+
+ it_behaves_like 'releases index page'
end
end
diff --git a/spec/features/projects/serverless/functions_spec.rb b/spec/features/projects/serverless/functions_spec.rb
index a0b06d7e2a1..db8c2a24f2f 100644
--- a/spec/features/projects/serverless/functions_spec.rb
+++ b/spec/features/projects/serverless/functions_spec.rb
@@ -25,7 +25,6 @@ RSpec.describe 'Functions', :js do
end
it 'sees an empty state require Knative installation' do
- expect(page).to have_link('Install Knative')
expect(page).to have_selector('.empty-state')
end
end
diff --git a/spec/features/projects/services/disable_triggers_spec.rb b/spec/features/projects/services/disable_triggers_spec.rb
index d9e200cf563..c6413685f38 100644
--- a/spec/features/projects/services/disable_triggers_spec.rb
+++ b/spec/features/projects/services/disable_triggers_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe 'Disable individual triggers', :js do
let(:service_name) { 'Jenkins' }
it 'shows trigger checkboxes' do
- event_count = JenkinsService.supported_events.count
+ event_count = Integrations::Jenkins.supported_events.count
expect(page).to have_content "Trigger"
expect(page).to have_css(checkbox_selector, visible: :all, count: event_count)
diff --git a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb
index 54a501e89a2..b2ca0424b6d 100644
--- a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb
+++ b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb
@@ -14,35 +14,10 @@ RSpec.describe 'Set up Mattermost slash commands', :js do
context 'mattermost service is enabled' do
let(:mattermost_enabled) { true }
- it 'shows a help message' do
- expect(page).to have_content("Use this service to perform common")
- end
-
- it 'shows a token placeholder' do
- token_placeholder = find_field('service_token')['placeholder']
-
- expect(token_placeholder).to eq('XXxxXXxxXXxxXXxxXXxxXXxx')
- end
-
- it 'redirects to the integrations page after saving but not activating' do
- token = ('a'..'z').to_a.join
-
- fill_in 'service_token', with: token
- click_active_checkbox
- click_save_integration
-
- expect(current_path).to eq(edit_project_service_path(project, :mattermost_slash_commands))
- expect(page).to have_content('Mattermost slash commands settings saved, but not active.')
- end
-
- it 'redirects to the integrations page after activating' do
- token = ('a'..'z').to_a.join
-
- fill_in 'service_token', with: token
- click_save_integration
+ describe 'activation' do
+ let(:edit_path) { edit_project_service_path(project, :mattermost_slash_commands) }
- expect(current_path).to eq(edit_project_service_path(project, :mattermost_slash_commands))
- expect(page).to have_content('Mattermost slash commands settings saved and active.')
+ include_examples 'user activates the Mattermost Slash Command integration'
end
it 'shows the add to mattermost button' do
@@ -109,7 +84,7 @@ RSpec.describe 'Set up Mattermost slash commands', :js do
end
it 'shows an error alert with the error message if there is an error requesting teams' do
- allow_any_instance_of(MattermostSlashCommandsService).to receive(:list_teams) { [[], 'test mattermost error message'] }
+ allow_any_instance_of(Integrations::MattermostSlashCommands).to receive(:list_teams) { [[], 'test mattermost error message'] }
click_link 'Add to Mattermost'
@@ -138,7 +113,7 @@ RSpec.describe 'Set up Mattermost slash commands', :js do
def stub_teams(count: 0)
teams = create_teams(count)
- allow_any_instance_of(MattermostSlashCommandsService).to receive(:list_teams) { [teams, nil] }
+ allow_any_instance_of(Integrations::MattermostSlashCommands).to receive(:list_teams) { [teams, nil] }
teams
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 0cba1ee1c4c..dec83ff1489 100644
--- a/spec/features/projects/services/user_activates_slack_notifications_spec.rb
+++ b/spec/features/projects/services/user_activates_slack_notifications_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe 'User activates Slack notifications', :js do
end
context 'when service is already configured' do
- let(:service) { SlackService.new }
+ let(:service) { Integrations::Slack.new }
let(:project) { create(:project, slack_service: service) }
before do
diff --git a/spec/features/projects/settings/monitor_settings_spec.rb b/spec/features/projects/settings/monitor_settings_spec.rb
index 64138e0aeca..971a747e64f 100644
--- a/spec/features/projects/settings/monitor_settings_spec.rb
+++ b/spec/features/projects/settings/monitor_settings_spec.rb
@@ -41,7 +41,7 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do
visit project_settings_operations_path(project)
wait_for_requests
- click_expand_incident_management_button
+ click_settings_tab
end
it 'renders form for incident management' do
@@ -60,22 +60,24 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do
click_on('bug')
save_form
- click_expand_incident_management_button
+ click_settings_tab
expect(find_field(create_issue)).to be_checked
expect(page).to have_selector(:id, 'alert-integration-settings-issue-template', text: 'bug')
+
+ click_settings_tab
expect(find_field(send_email)).not_to be_checked
end
- def click_expand_incident_management_button
- within '.qa-incident-management-settings' do
- click_button('Expand')
+ def click_settings_tab
+ within '[data-testid="alert-integration-settings"]' do
+ click_link 'Alert settings'
end
end
def save_form
- page.within ".qa-incident-management-settings" do
- click_on 'Save changes'
+ page.within '[data-testid="alert-integration-settings"]' do
+ click_button 'Save changes'
end
end
end
diff --git a/spec/features/projects/settings/registry_settings_spec.rb b/spec/features/projects/settings/registry_settings_spec.rb
index 6a2769d11fd..1cc54b71d4a 100644
--- a/spec/features/projects/settings/registry_settings_spec.rb
+++ b/spec/features/projects/settings/registry_settings_spec.rb
@@ -24,14 +24,14 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
it 'shows available section' do
subject
- settings_block = find('#js-registry-policies')
+ settings_block = find('[data-testid="registry-settings-app"]')
expect(settings_block).to have_text 'Clean up image tags'
end
it 'saves cleanup policy submit the form' do
subject
- within '#js-registry-policies' do
+ 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')
@@ -49,7 +49,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
it 'does not save cleanup policy submit form with invalid regex' do
subject
- within '#js-registry-policies' do
+ within '[data-testid="registry-settings-app"]' do
fill_in('Remove tags matching:', with: '*-production')
submit_button = find('[data-testid="save-button"')
@@ -80,7 +80,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
it 'displays the expected result' do
subject
- within '#js-registry-policies' do
+ 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.')
@@ -98,7 +98,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
it 'does not exists' do
subject
- expect(page).not_to have_selector('#js-registry-policies')
+ expect(page).not_to have_selector('[data-testid="registry-settings-app"]')
end
end
@@ -108,7 +108,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
it 'does not exists' do
subject
- expect(page).not_to have_selector('#js-registry-policies')
+ expect(page).not_to have_selector('[data-testid="registry-settings-app"]')
end
end
end
diff --git a/spec/features/projects/settings/service_desk_setting_spec.rb b/spec/features/projects/settings/service_desk_setting_spec.rb
index 50451075db5..91355d8f625 100644
--- a/spec/features/projects/settings/service_desk_setting_spec.rb
+++ b/spec/features/projects/settings/service_desk_setting_spec.rb
@@ -89,25 +89,10 @@ RSpec.describe 'Service Desk Setting', :js, :clean_gitlab_redis_cache do
before do
stub_licensed_features(custom_file_templates_for_namespace: false, custom_file_templates: false)
group.update_columns(file_template_project_id: group_template_repo.id)
+ visit edit_project_path(project)
end
- context 'when inherited_issuable_templates enabled' do
- before do
- stub_feature_flags(inherited_issuable_templates: true)
- visit edit_project_path(project)
- end
-
- it_behaves_like 'issue description templates from current project only'
- end
-
- context 'when inherited_issuable_templates disabled' do
- before do
- stub_feature_flags(inherited_issuable_templates: false)
- visit edit_project_path(project)
- end
-
- it_behaves_like 'issue description templates from current project only'
- end
+ it_behaves_like 'issue description templates from current project only'
end
end
end
diff --git a/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
index bf90e86c263..862bae45fc6 100644
--- a/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
+++ b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
@@ -116,7 +116,8 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do
click_on('Save changes')
end
- find('.flash-notice')
+ wait_for_all_requests
+
checkbox = find_field('project_printing_merge_request_link_enabled')
expect(checkbox).not_to be_checked
@@ -139,7 +140,8 @@ RSpec.describe 'Projects > Settings > User manages merge request settings' do
click_on('Save changes')
end
- find('.flash-notice')
+ wait_for_all_requests
+
checkbox = find_field('project_remove_source_branch_after_merge')
expect(checkbox).not_to be_checked
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 9b09958bae5..a60743f0e47 100644
--- a/spec/features/projects/settings/user_searches_in_settings_spec.rb
+++ b/spec/features/projects/settings/user_searches_in_settings_spec.rb
@@ -63,7 +63,7 @@ RSpec.describe 'User searches project settings', :js do
visit project_settings_operations_path(project)
end
- it_behaves_like 'can search settings', 'Alert integrations', 'Error tracking'
+ it_behaves_like 'can search settings', 'Alerts', 'Error tracking'
end
context 'in Pages page' do
diff --git a/spec/features/projects/show/schema_markup_spec.rb b/spec/features/projects/show/schema_markup_spec.rb
index 1777b72cbf5..28803db924a 100644
--- a/spec/features/projects/show/schema_markup_spec.rb
+++ b/spec/features/projects/show/schema_markup_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe 'Projects > Show > Schema Markup' do
- let_it_be(:project) { create(:project, :repository, :public, :with_avatar, description: 'foobar', tag_list: 'tag1, tag2') }
+ let_it_be(:project) { create(:project, :repository, :public, :with_avatar, description: 'foobar', topic_list: 'topic1, topic2') }
it 'shows SoftwareSourceCode structured markup', :js do
visit project_path(project)
@@ -16,7 +16,7 @@ RSpec.describe 'Projects > Show > Schema Markup' do
expect(page).to have_selector('[itemprop="identifier"]', text: "Project ID: #{project.id}")
expect(page).to have_selector('[itemprop="description"]', text: project.description)
expect(page).to have_selector('[itemprop="license"]', text: project.repository.license.name)
- expect(find_all('[itemprop="keywords"]').map(&:text)).to match_array(project.tag_list.map(&:capitalize))
+ expect(find_all('[itemprop="keywords"]').map(&:text)).to match_array(project.topic_list.map(&:capitalize))
expect(page).to have_selector('[itemprop="about"]')
end
end
diff --git a/spec/features/projects/show/user_sees_collaboration_links_spec.rb b/spec/features/projects/show/user_sees_collaboration_links_spec.rb
index ffdfbb9fe81..613033373e8 100644
--- a/spec/features/projects/show/user_sees_collaboration_links_spec.rb
+++ b/spec/features/projects/show/user_sees_collaboration_links_spec.rb
@@ -12,6 +12,10 @@ RSpec.describe 'Projects > Show > Collaboration links', :js do
sign_in(user)
end
+ def find_new_menu_toggle
+ find('#js-onboarding-new-project-link')
+ end
+
context 'with developer user' do
before do
project.add_developer(user)
@@ -22,7 +26,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js do
# The navigation bar
page.within('.header-new') do
- find('.qa-new-menu-toggle').click
+ find_new_menu_toggle.click
aggregate_failures 'dropdown links in the navigation bar' do
expect(page).to have_link('New issue')
@@ -30,7 +34,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js do
expect(page).to have_link('New snippet', href: new_project_snippet_path(project))
end
- find('.qa-new-menu-toggle').click
+ find_new_menu_toggle.click
end
# The dropdown above the tree
@@ -56,7 +60,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js do
visit project_path(project)
page.within('.header-new') do
- find('.qa-new-menu-toggle').click
+ find_new_menu_toggle.click
aggregate_failures 'dropdown links' do
expect(page).not_to have_link('New issue')
@@ -64,7 +68,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js do
expect(page).not_to have_link('New snippet', href: new_project_snippet_path(project))
end
- find('.qa-new-menu-toggle').click
+ find_new_menu_toggle.click
end
expect(page).not_to have_selector('.qa-add-to-tree')
diff --git a/spec/features/projects/user_uses_shortcuts_spec.rb b/spec/features/projects/user_uses_shortcuts_spec.rb
index 1350ecf6e75..2f7844ff615 100644
--- a/spec/features/projects/user_uses_shortcuts_spec.rb
+++ b/spec/features/projects/user_uses_shortcuts_spec.rb
@@ -3,11 +3,11 @@
require 'spec_helper'
RSpec.describe 'User uses shortcuts', :js do
- let(:project) { create(:project, :repository) }
- let(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :repository) }
+
+ let(:user) { project.owner }
before do
- project.add_maintainer(user)
sign_in(user)
visit(project_path(project))
@@ -74,7 +74,7 @@ RSpec.describe 'User uses shortcuts', :js do
find('body').native.send_key('g')
find('body').native.send_key('p')
- expect(page).to have_active_navigation('Project')
+ expect(page).to have_active_navigation(project.name)
end
context 'when feature flag :sidebar_refactor is disabled' do
diff --git a/spec/features/projects/user_views_empty_project_spec.rb b/spec/features/projects/user_views_empty_project_spec.rb
index 3d4d9a7ea96..cce38456df9 100644
--- a/spec/features/projects/user_views_empty_project_spec.rb
+++ b/spec/features/projects/user_views_empty_project_spec.rb
@@ -3,8 +3,8 @@
require 'spec_helper'
RSpec.describe 'User views an empty project' do
- let(:project) { create(:project, :empty_repo) }
- let(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :empty_repo) }
+ let_it_be(:user) { create(:user) }
shared_examples 'allowing push to default branch' do
it 'shows push-to-master instructions' do
@@ -14,17 +14,25 @@ RSpec.describe 'User views an empty project' do
end
end
- describe 'as a maintainer' do
+ context 'when user is a maintainer' do
before do
project.add_maintainer(user)
sign_in(user)
end
it_behaves_like 'allowing push to default branch'
+
+ it 'shows a link for inviting members and launches invite modal', :js do
+ visit project_path(project)
+
+ click_button 'Invite members'
+
+ expect(page).to have_content("You're inviting members to the")
+ end
end
- describe 'as an admin' do
- let(:user) { create(:user, :admin) }
+ context 'when user is an admin' do
+ let_it_be(:user) { create(:user, :admin) }
context 'when admin mode is enabled' do
before do
@@ -44,16 +52,17 @@ RSpec.describe 'User views an empty project' do
end
end
- describe 'as a developer' do
+ context 'when user is a developer' do
before do
project.add_developer(user)
sign_in(user)
end
- it 'does not show push-to-master instructions' 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_button(text: 'Invite members')
end
end
end
diff --git a/spec/features/projects/wiki/user_views_wiki_empty_spec.rb b/spec/features/projects/wiki/user_views_wiki_empty_spec.rb
index 1f460f39267..ea045ddb6a1 100644
--- a/spec/features/projects/wiki/user_views_wiki_empty_spec.rb
+++ b/spec/features/projects/wiki/user_views_wiki_empty_spec.rb
@@ -75,7 +75,7 @@ RSpec.describe 'Project > User views empty wiki' do
context 'and Confluence is already enabled' do
before do
- create(:confluence_service, project: project)
+ create(:confluence_integration, project: project)
end
it_behaves_like 'empty wiki message', writable: true, issuable: true, confluence: false
diff --git a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb
index 30b94495e3d..63ee89bd11f 100644
--- a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb
+++ b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb
@@ -3,15 +3,12 @@
require 'spec_helper'
RSpec.describe 'Projects > Wiki > User views wiki in project page' do
- let(:user) { create(:user) }
-
before do
- project.add_maintainer(user)
- sign_in(user)
+ sign_in(project.owner)
end
context 'when repository is disabled for project' do
- let(:project) do
+ let_it_be(:project) do
create(:project,
:wiki_repo,
:repository_disabled,
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
index c18b0f2688b..2ac829d406c 100644
--- a/spec/features/projects_spec.rb
+++ b/spec/features/projects_spec.rb
@@ -128,23 +128,23 @@ RSpec.describe 'Project' do
end
it 'shows project topics' do
- project.update_attribute(:tag_list, 'topic1')
+ project.update_attribute(:topic_list, 'topic1')
visit path
expect(page).to have_css('.home-panel-topic-list')
- expect(page).to have_link('Topic1', href: explore_projects_path(tag: 'topic1'))
+ expect(page).to have_link('Topic1', href: explore_projects_path(topic: 'topic1'))
end
- it 'shows up to 3 project tags' do
- project.update_attribute(:tag_list, 'topic1, topic2, topic3, topic4')
+ it 'shows up to 3 project topics' do
+ project.update_attribute(:topic_list, 'topic1, topic2, topic3, topic4')
visit path
expect(page).to have_css('.home-panel-topic-list')
- expect(page).to have_link('Topic1', href: explore_projects_path(tag: 'topic1'))
- expect(page).to have_link('Topic2', href: explore_projects_path(tag: 'topic2'))
- expect(page).to have_link('Topic3', href: explore_projects_path(tag: 'topic3'))
+ expect(page).to have_link('Topic1', href: explore_projects_path(topic: 'topic1'))
+ expect(page).to have_link('Topic2', href: explore_projects_path(topic: 'topic2'))
+ expect(page).to have_link('Topic3', href: explore_projects_path(topic: 'topic3'))
expect(page).to have_content('+ 1 more')
end
end
diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb
index 207b74c990a..6fbed21acdb 100644
--- a/spec/features/protected_branches_spec.rb
+++ b/spec/features/protected_branches_spec.rb
@@ -21,13 +21,28 @@ RSpec.describe 'Protected Branches', :js do
expect(ProtectedBranch.count).to eq(1)
end
- it 'does not allow developer to removes protected branch' do
+ it 'does not allow developer to remove protected branch' do
visit project_branches_path(project)
find('input[data-testid="branch-search"]').set('fix')
find('input[data-testid="branch-search"]').native.send_keys(:enter)
- expect(page).to have_css('.btn-danger.disabled')
+ expect(page).to have_button('Only a project maintainer or owner can delete a protected branch', disabled: true)
+ end
+
+ context 'when feature flag :delete_branch_confirmation_modals is disabled' do
+ before do
+ stub_feature_flags(delete_branch_confirmation_modals: false)
+ end
+
+ it 'does not allow developer to remove protected branch' do
+ visit project_branches_path(project)
+
+ find('input[data-testid="branch-search"]').set('fix')
+ find('input[data-testid="branch-search"]').native.send_keys(:enter)
+
+ expect(page).to have_selector('button[data-testid="remove-protected-branch"][disabled]')
+ end
end
end
end
@@ -52,17 +67,44 @@ RSpec.describe 'Protected Branches', :js do
expect(page).to have_content('fix')
expect(find('.all-branches')).to have_selector('li', count: 1)
- page.find('[data-target="#modal-delete-branch"]').click
- expect(page).to have_css('.js-delete-branch[disabled]')
+ expect(page).to have_button('Delete protected branch', disabled: false)
+
+ page.find('.js-delete-branch-button').click
fill_in 'delete_branch_input', with: 'fix'
- click_link 'Delete protected branch'
+ click_button 'Yes, delete protected branch'
find('input[data-testid="branch-search"]').set('fix')
find('input[data-testid="branch-search"]').native.send_keys(:enter)
expect(page).to have_content('No branches to show')
end
+
+ context 'when the feature flag :delete_branch_confirmation_modals is disabled' do
+ before do
+ stub_feature_flags(delete_branch_confirmation_modals: false)
+ end
+
+ it 'removes branch after modal confirmation' do
+ visit project_branches_path(project)
+
+ find('input[data-testid="branch-search"]').set('fix')
+ find('input[data-testid="branch-search"]').native.send_keys(:enter)
+
+ expect(page).to have_content('fix')
+ expect(find('.all-branches')).to have_selector('li', count: 1)
+ page.find('[data-target="#modal-delete-branch"]').click
+
+ expect(page).to have_css('.js-delete-branch[disabled]')
+ fill_in 'delete_branch_input', with: 'fix'
+ click_link 'Delete protected branch'
+
+ find('input[data-testid="branch-search"]').set('fix')
+ find('input[data-testid="branch-search"]').native.send_keys(:enter)
+
+ expect(page).to have_content('No branches to show')
+ end
+ end
end
end
diff --git a/spec/features/search/user_searches_for_code_spec.rb b/spec/features/search/user_searches_for_code_spec.rb
index ee3717b3e42..094b31ba784 100644
--- a/spec/features/search/user_searches_for_code_spec.rb
+++ b/spec/features/search/user_searches_for_code_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe 'User searches for code' do
wait_for_requests
page.within('[data-testid="project-filter"]') do
- click_on(project.full_name)
+ click_on(project.name)
end
end
diff --git a/spec/features/search/user_searches_for_issues_spec.rb b/spec/features/search/user_searches_for_issues_spec.rb
index 828e478d701..184f8ba0d36 100644
--- a/spec/features/search/user_searches_for_issues_spec.rb
+++ b/spec/features/search/user_searches_for_issues_spec.rb
@@ -90,7 +90,7 @@ RSpec.describe 'User searches for issues', :js do
wait_for_requests
page.within('[data-testid="project-filter"]') do
- click_on(project.full_name)
+ click_on(project.name)
end
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 7271716644b..32952a127d3 100644
--- a/spec/features/search/user_searches_for_merge_requests_spec.rb
+++ b/spec/features/search/user_searches_for_merge_requests_spec.rb
@@ -29,6 +29,11 @@ RSpec.describe 'User searches for merge requests', :js do
page.within('.results') do
expect(page).to have_link(merge_request1.title)
expect(page).not_to have_link(merge_request2.title)
+
+ # Each result should have MR refs like `gitlab-org/gitlab!1`
+ page.all('.search-result-row').each do |e|
+ expect(e.text).to match(/!\d+/)
+ end
end
end
@@ -55,7 +60,7 @@ RSpec.describe 'User searches for merge requests', :js do
wait_for_requests
page.within('[data-testid="project-filter"]') do
- click_on(project.full_name)
+ click_on(project.name)
end
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 f4df91dbc08..e81abb44ba5 100644
--- a/spec/features/search/user_searches_for_milestones_spec.rb
+++ b/spec/features/search/user_searches_for_milestones_spec.rb
@@ -35,7 +35,7 @@ RSpec.describe 'User searches for milestones', :js do
wait_for_requests
page.within('[data-testid="project-filter"]') do
- click_on(project.full_name)
+ click_on(project.name)
end
fill_in('dashboard_search', with: milestone1.title)
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 72bd1193fc9..8913f1fe9ee 100644
--- a/spec/features/search/user_searches_for_wiki_pages_spec.rb
+++ b/spec/features/search/user_searches_for_wiki_pages_spec.rb
@@ -23,7 +23,7 @@ RSpec.describe 'User searches for wiki pages', :js do
wait_for_requests
page.within('[data-testid="project-filter"]') do
- click_on(project.full_name)
+ click_on(project.name)
end
fill_in('dashboard_search', with: search_term)
diff --git a/spec/features/search/user_uses_header_search_field_spec.rb b/spec/features/search/user_uses_header_search_field_spec.rb
index 4c42800cf05..c002d199b01 100644
--- a/spec/features/search/user_uses_header_search_field_spec.rb
+++ b/spec/features/search/user_uses_header_search_field_spec.rb
@@ -55,7 +55,7 @@ RSpec.describe 'User uses header search field', :js do
expect(page).to have_selector('.dropdown-header', text: /#{scope_name}/i)
end
- context 'when clicking issues' do
+ context 'when clicking issues', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/332317' do
let!(:issue) { create(:issue, project: project, author: user, assignees: [user]) }
it 'shows assigned issues' do
@@ -75,7 +75,7 @@ RSpec.describe 'User uses header search field', :js do
end
end
- context 'when clicking merge requests' do
+ context 'when clicking merge requests', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/332317' do
let!(:merge_request) { create(:merge_request, source_project: project, author: user, assignees: [user]) }
it 'shows assigned merge requests' do
diff --git a/spec/features/search/user_uses_search_filters_spec.rb b/spec/features/search/user_uses_search_filters_spec.rb
index 86017ca64c5..24f6c70e64c 100644
--- a/spec/features/search/user_uses_search_filters_spec.rb
+++ b/spec/features/search/user_uses_search_filters_spec.rb
@@ -33,10 +33,10 @@ RSpec.describe 'User uses search filters', :js do
wait_for_requests
page.within('[data-testid="project-filter"]') do
- click_on(group_project.full_name)
+ click_on(group_project.name)
end
- expect(find('[data-testid="project-filter"]')).to have_content(group_project.full_name)
+ expect(find('[data-testid="project-filter"]')).to have_content(group_project.name)
end
context 'when the group filter is set' do
@@ -65,10 +65,10 @@ RSpec.describe 'User uses search filters', :js do
wait_for_requests
page.within('[data-testid="project-filter"]') do
- click_on(project.full_name)
+ click_on(project.name)
end
- expect(find('[data-testid="project-filter"]')).to have_content(project.full_name)
+ expect(find('[data-testid="project-filter"]')).to have_content(project.name)
end
context 'when the project filter is set' do
diff --git a/spec/features/security/project/snippet/private_access_spec.rb b/spec/features/security/project/snippet/private_access_spec.rb
index 0f7ae06a6c5..0c06841399d 100644
--- a/spec/features/security/project/snippet/private_access_spec.rb
+++ b/spec/features/security/project/snippet/private_access_spec.rb
@@ -5,23 +5,25 @@ require 'spec_helper'
RSpec.describe "Private Project Snippets Access" do
include AccessMatchers
- let(:project) { create(:project, :private) }
-
- let(:private_snippet) { create(:project_snippet, :private, project: project, author: project.owner) }
+ let_it_be(:project) { create(:project, :private) }
+ let_it_be(:private_snippet) { create(:project_snippet, :private, project: project, author: project.owner) }
describe "GET /:project_path/snippets" do
subject { project_snippets_path(project) }
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
- it { is_expected.to be_allowed_for(:owner).of(project) }
- it { is_expected.to be_allowed_for(:maintainer).of(project) }
- it { is_expected.to be_allowed_for(:developer).of(project) }
- it { is_expected.to be_allowed_for(:reporter).of(project) }
- it { is_expected.to be_allowed_for(:guest).of(project) }
- it { is_expected.to be_denied_for(:user) }
- it { is_expected.to be_denied_for(:external) }
- it { is_expected.to be_denied_for(:visitor) }
+
+ specify :aggregate_failures do
+ is_expected.to be_allowed_for(:owner).of(project)
+ is_expected.to be_allowed_for(:maintainer).of(project)
+ is_expected.to be_allowed_for(:developer).of(project)
+ is_expected.to be_allowed_for(:reporter).of(project)
+ is_expected.to be_allowed_for(:guest).of(project)
+ is_expected.to be_denied_for(:user)
+ is_expected.to be_denied_for(:external)
+ is_expected.to be_denied_for(:visitor)
+ end
end
describe "GET /:project_path/snippets/new" do
@@ -29,14 +31,17 @@ RSpec.describe "Private Project Snippets Access" do
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
- it { is_expected.to be_allowed_for(:owner).of(project) }
- it { is_expected.to be_allowed_for(:maintainer).of(project) }
- it { is_expected.to be_allowed_for(:developer).of(project) }
- it { is_expected.to be_allowed_for(:reporter).of(project) }
- it { is_expected.to be_denied_for(:guest).of(project) }
- it { is_expected.to be_denied_for(:user) }
- it { is_expected.to be_denied_for(:external) }
- it { is_expected.to be_denied_for(:visitor) }
+
+ specify :aggregate_failures do
+ is_expected.to be_allowed_for(:maintainer).of(project)
+ is_expected.to be_allowed_for(:owner).of(project)
+ is_expected.to be_allowed_for(:developer).of(project)
+ is_expected.to be_allowed_for(:reporter).of(project)
+ is_expected.to be_denied_for(:guest).of(project)
+ is_expected.to be_denied_for(:user)
+ is_expected.to be_denied_for(:external)
+ is_expected.to be_denied_for(:visitor)
+ end
end
describe "GET /:project_path/snippets/:id for a private snippet" do
@@ -44,14 +49,17 @@ RSpec.describe "Private Project Snippets Access" do
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
- it { is_expected.to be_allowed_for(:owner).of(project) }
- it { is_expected.to be_allowed_for(:maintainer).of(project) }
- it { is_expected.to be_allowed_for(:developer).of(project) }
- it { is_expected.to be_allowed_for(:reporter).of(project) }
- it { is_expected.to be_allowed_for(:guest).of(project) }
- it { is_expected.to be_denied_for(:user) }
- it { is_expected.to be_denied_for(:external) }
- it { is_expected.to be_denied_for(:visitor) }
+
+ specify :aggregate_failures do
+ is_expected.to be_allowed_for(:owner).of(project)
+ is_expected.to be_allowed_for(:maintainer).of(project)
+ is_expected.to be_allowed_for(:developer).of(project)
+ is_expected.to be_allowed_for(:reporter).of(project)
+ is_expected.to be_allowed_for(:guest).of(project)
+ is_expected.to be_denied_for(:user)
+ is_expected.to be_denied_for(:external)
+ is_expected.to be_denied_for(:visitor)
+ end
end
describe "GET /:project_path/snippets/:id/raw for a private snippet" do
@@ -59,13 +67,16 @@ RSpec.describe "Private Project Snippets Access" do
it('is allowed for admin when admin mode is enabled', :enable_admin_mode) { is_expected.to be_allowed_for(:admin) }
it('is denied for admin when admin mode is disabled') { is_expected.to be_denied_for(:admin) }
- it { is_expected.to be_allowed_for(:owner).of(project) }
- it { is_expected.to be_allowed_for(:maintainer).of(project) }
- it { is_expected.to be_allowed_for(:developer).of(project) }
- it { is_expected.to be_allowed_for(:reporter).of(project) }
- it { is_expected.to be_allowed_for(:guest).of(project) }
- it { is_expected.to be_denied_for(:user) }
- it { is_expected.to be_denied_for(:external) }
- it { is_expected.to be_denied_for(:visitor) }
+
+ specify :aggregate_failures do
+ is_expected.to be_allowed_for(:owner).of(project)
+ is_expected.to be_allowed_for(:maintainer).of(project)
+ is_expected.to be_allowed_for(:developer).of(project)
+ is_expected.to be_allowed_for(:reporter).of(project)
+ is_expected.to be_allowed_for(:guest).of(project)
+ is_expected.to be_denied_for(:user)
+ is_expected.to be_denied_for(:external)
+ is_expected.to be_denied_for(:visitor)
+ end
end
end
diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb
index 56d2aaea203..0309df8f32a 100644
--- a/spec/features/users/show_spec.rb
+++ b/spec/features/users/show_spec.rb
@@ -220,6 +220,14 @@ RSpec.describe 'User page' do
expect(page).to have_content("Working hard!")
end
+ it 'shows the pronouns of the user if there was one' do
+ user.user_detail.update_column(:pronouns, 'they/them')
+
+ subject
+
+ expect(page).to have_content("(they/them)")
+ end
+
context 'signup disabled' do
it 'shows the sign in link' do
stub_application_setting(signup_enabled: false)
diff --git a/spec/features/users/signup_spec.rb b/spec/features/users/signup_spec.rb
index 17a6abb99e0..a651a6c09c6 100644
--- a/spec/features/users/signup_spec.rb
+++ b/spec/features/users/signup_spec.rb
@@ -204,7 +204,7 @@ RSpec.describe 'Signup' do
expect { click_button 'Register' }.to change { User.count }.by(1)
expect(current_path).to eq users_almost_there_path
- expect(page).to have_content('Please check your email to confirm your account')
+ expect(page).to have_content("Please check your email (#{new_user.email}) to confirm your account")
confirm_email