summaryrefslogtreecommitdiff
path: root/spec/features
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-08-19 09:08:42 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-08-19 09:08:42 +0000
commitb76ae638462ab0f673e5915986070518dd3f9ad3 (patch)
treebdab0533383b52873be0ec0eb4d3c66598ff8b91 /spec/features
parent434373eabe7b4be9593d18a585fb763f1e5f1a6f (diff)
downloadgitlab-ce-b76ae638462ab0f673e5915986070518dd3f9ad3.tar.gz
Add latest changes from gitlab-org/gitlab@14-2-stable-eev14.2.0-rc42
Diffstat (limited to 'spec/features')
-rw-r--r--spec/features/admin/admin_appearance_spec.rb2
-rw-r--r--spec/features/admin/admin_dev_ops_report_spec.rb4
-rw-r--r--spec/features/admin/admin_groups_spec.rb4
-rw-r--r--spec/features/admin/admin_manage_applications_spec.rb56
-rw-r--r--spec/features/admin/admin_mode/logout_spec.rb76
-rw-r--r--spec/features/admin/admin_mode_spec.rb217
-rw-r--r--spec/features/admin/admin_settings_spec.rb22
-rw-r--r--spec/features/admin/dashboard_spec.rb4
-rw-r--r--spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb6
-rw-r--r--spec/features/admin/services/admin_visits_service_templates_spec.rb53
-rw-r--r--spec/features/admin/users/user_spec.rb37
-rw-r--r--spec/features/boards/boards_spec.rb791
-rw-r--r--spec/features/callouts/service_templates_deprecation_spec.rb59
-rw-r--r--spec/features/clusters/cluster_health_dashboard_spec.rb16
-rw-r--r--spec/features/cycle_analytics_spec.rb87
-rw-r--r--spec/features/dashboard/active_tab_spec.rb43
-rw-r--r--spec/features/dashboard/group_dashboard_with_external_authorization_service_spec.rb72
-rw-r--r--spec/features/dashboard/projects_spec.rb23
-rw-r--r--spec/features/dashboard/shortcuts_spec.rb98
-rw-r--r--spec/features/frequently_visited_projects_and_groups_spec.rb72
-rw-r--r--spec/features/groups/board_sidebar_spec.rb28
-rw-r--r--spec/features/groups/board_spec.rb73
-rw-r--r--spec/features/groups/integrations/user_activates_mattermost_slash_command_spec.rb5
-rw-r--r--spec/features/groups/members/manage_members_spec.rb54
-rw-r--r--spec/features/groups/packages_spec.rb2
-rw-r--r--spec/features/groups/settings/manage_applications_spec.rb16
-rw-r--r--spec/features/groups/settings/packages_and_registries_spec.rb2
-rw-r--r--spec/features/groups/settings/user_searches_in_settings_spec.rb2
-rw-r--r--spec/features/groups_spec.rb2
-rw-r--r--spec/features/invites_spec.rb28
-rw-r--r--spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb2
-rw-r--r--spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb2
-rw-r--r--spec/features/issues/form_spec.rb36
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb4
-rw-r--r--spec/features/issues/user_creates_issue_spec.rb6
-rw-r--r--spec/features/jira_connect/branches_spec.rb86
-rw-r--r--spec/features/labels_hierarchy_spec.rb76
-rw-r--r--spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb8
-rw-r--r--spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb20
-rw-r--r--spec/features/merge_request/user_sees_closing_issues_message_spec.rb16
-rw-r--r--spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb32
-rw-r--r--spec/features/merge_request/user_sees_pipelines_spec.rb2
-rw-r--r--spec/features/merge_request/user_views_diffs_spec.rb2
-rw-r--r--spec/features/merge_requests/user_lists_merge_requests_spec.rb32
-rw-r--r--spec/features/nav/top_nav_responsive_spec.rb2
-rw-r--r--spec/features/profile_spec.rb2
-rw-r--r--spec/features/profiles/user_manages_applications_spec.rb49
-rw-r--r--spec/features/project_variables_spec.rb2
-rw-r--r--spec/features/projects/activity/user_sees_design_activity_spec.rb18
-rw-r--r--spec/features/projects/blobs/blob_show_spec.rb969
-rw-r--r--spec/features/projects/ci/editor_spec.rb40
-rw-r--r--spec/features/projects/commit/mini_pipeline_graph_spec.rb3
-rw-r--r--spec/features/projects/environments/environment_metrics_spec.rb12
-rw-r--r--spec/features/projects/environments/environment_spec.rb47
-rw-r--r--spec/features/projects/environments/environments_spec.rb4
-rw-r--r--spec/features/projects/environments_pod_logs_spec.rb2
-rw-r--r--spec/features/projects/feature_flags/user_sees_feature_flag_list_spec.rb2
-rw-r--r--spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb2
-rw-r--r--spec/features/projects/fork_spec.rb4
-rw-r--r--spec/features/projects/import_export/export_file_spec.rb3
-rw-r--r--spec/features/projects/import_export/import_file_spec.rb2
-rw-r--r--spec/features/projects/infrastructure_registry_spec.rb6
-rw-r--r--spec/features/projects/integrations/user_uses_inherited_settings_spec.rb91
-rw-r--r--spec/features/projects/members/invite_group_spec.rb4
-rw-r--r--spec/features/projects/new_project_spec.rb514
-rw-r--r--spec/features/projects/packages_spec.rb2
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb201
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb22
-rw-r--r--spec/features/projects/services/user_activates_irker_spec.rb6
-rw-r--r--spec/features/projects/services/user_activates_pushover_spec.rb2
-rw-r--r--spec/features/projects/services/user_views_services_spec.rb2
-rw-r--r--spec/features/projects/settings/registry_settings_spec.rb6
-rw-r--r--spec/features/projects/show/schema_markup_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_collaboration_links_spec.rb4
-rw-r--r--spec/features/projects/tags/user_edits_tags_spec.rb2
-rw-r--r--spec/features/projects/terraform_spec.rb23
-rw-r--r--spec/features/projects/tree/create_directory_spec.rb4
-rw-r--r--spec/features/projects/tree/create_file_spec.rb4
-rw-r--r--spec/features/projects/tree/tree_show_spec.rb6
-rw-r--r--spec/features/projects/user_creates_project_spec.rb9
-rw-r--r--spec/features/projects_spec.rb16
-rw-r--r--spec/features/registrations/welcome_spec.rb21
-rw-r--r--spec/features/runners_spec.rb10
-rw-r--r--spec/features/search/user_uses_header_search_field_spec.rb1
-rw-r--r--spec/features/users/show_spec.rb58
85 files changed, 2590 insertions, 1867 deletions
diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb
index b96762ec6ad..cd148642b90 100644
--- a/spec/features/admin/admin_appearance_spec.rb
+++ b/spec/features/admin/admin_appearance_spec.rb
@@ -90,7 +90,7 @@ RSpec.describe 'Admin Appearance' do
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
visit new_project_path
- find('[data-qa-panel-name="blank_project"]').click
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
expect_custom_new_project_appearance(appearance)
end
diff --git a/spec/features/admin/admin_dev_ops_report_spec.rb b/spec/features/admin/admin_dev_ops_report_spec.rb
index 8f1960b681c..cee79f8f440 100644
--- a/spec/features/admin/admin_dev_ops_report_spec.rb
+++ b/spec/features/admin/admin_dev_ops_report_spec.rb
@@ -19,7 +19,9 @@ RSpec.describe 'DevOps Report page', :js do
expect(page).to have_content 'Introducing Your DevOps Report'
- find('.js-close-callout').click
+ page.within(find('[data-testid="devops-score-container"]')) do
+ find('[data-testid="close-icon"]').click
+ end
expect(page).not_to have_content 'Introducing Your DevOps Report'
end
diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb
index 7d7b2baf941..8315b8f44b0 100644
--- a/spec/features/admin/admin_groups_spec.rb
+++ b/spec/features/admin/admin_groups_spec.rb
@@ -256,7 +256,7 @@ RSpec.describe 'Admin Groups' do
visit group_group_members_path(group)
- page.within '[data-qa-selector="members_list"]' do
+ page.within '[data-qa-selector="members_list"]' do # rubocop:disable QA/SelectorUsage
expect(page).to have_content(current_user.name)
expect(page).to have_content('Developer')
end
@@ -265,7 +265,7 @@ RSpec.describe 'Admin Groups' do
visit group_group_members_path(group)
- page.within '[data-qa-selector="members_list"]' do
+ page.within '[data-qa-selector="members_list"]' do # rubocop:disable QA/SelectorUsage
expect(page).not_to have_content(current_user.name)
expect(page).not_to have_content('Developer')
end
diff --git a/spec/features/admin/admin_manage_applications_spec.rb b/spec/features/admin/admin_manage_applications_spec.rb
index e54837ede11..b6437fce540 100644
--- a/spec/features/admin/admin_manage_applications_spec.rb
+++ b/spec/features/admin/admin_manage_applications_spec.rb
@@ -3,62 +3,14 @@
require 'spec_helper'
RSpec.describe 'admin manage applications' do
+ let_it_be(:new_application_path) { new_admin_application_path }
+ let_it_be(:applications_path) { admin_applications_path }
+
before do
admin = create(:admin)
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
end
- it 'creates new oauth application' do
- visit admin_applications_path
-
- click_on 'New application'
- expect(page).to have_content('New application')
-
- fill_in :doorkeeper_application_name, with: 'test'
- fill_in :doorkeeper_application_redirect_uri, with: 'https://test.com'
- check :doorkeeper_application_trusted
- check :doorkeeper_application_scopes_read_user
- click_on 'Submit'
- expect(page).to have_content('Application: test')
- expect(page).to have_content('Application ID')
- expect(page).to have_content('Secret')
- expect(page).to have_content('Trusted Y')
- expect(page).to have_content('Confidential Y')
-
- click_on 'Edit'
- expect(page).to have_content('Edit application')
-
- fill_in :doorkeeper_application_name, with: 'test_changed'
- uncheck :doorkeeper_application_trusted
- uncheck :doorkeeper_application_confidential
-
- click_on 'Submit'
- expect(page).to have_content('test_changed')
- expect(page).to have_content('Application ID')
- expect(page).to have_content('Secret')
- expect(page).to have_content('Trusted N')
- expect(page).to have_content('Confidential N')
-
- visit admin_applications_path
- page.within '.oauth-applications' do
- click_on 'Destroy'
- end
- expect(page.find('.oauth-applications')).not_to have_content('test_changed')
- end
-
- context 'when scopes are blank' do
- it 'returns an error' do
- visit admin_applications_path
-
- click_on 'New application'
- expect(page).to have_content('New application')
-
- fill_in :doorkeeper_application_name, with: 'test'
- fill_in :doorkeeper_application_redirect_uri, with: 'https://test.com'
- click_on 'Submit'
-
- expect(page).to have_content("Scopes can't be blank")
- end
- end
+ include_examples 'manage applications'
end
diff --git a/spec/features/admin/admin_mode/logout_spec.rb b/spec/features/admin/admin_mode/logout_spec.rb
index efb4baa8164..58bea5c4b5f 100644
--- a/spec/features/admin/admin_mode/logout_spec.rb
+++ b/spec/features/admin/admin_mode/logout_spec.rb
@@ -9,69 +9,47 @@ RSpec.describe 'Admin Mode Logout', :js do
let(:user) { create(:admin) }
- shared_examples 'combined_menu: feature flag examples' do
- before do
- # 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
+ before do
+ # 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
- gitlab_disable_admin_mode
+ it 'disable removes admin mode and redirects to root page' do
+ gitlab_disable_admin_mode
- expect(current_path).to eq root_path
+ expect(current_path).to eq root_path
- open_top_nav
+ 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
- gitlab_disable_admin_mode
-
- expect(page).to have_selector('.flash-notice')
+ within_top_nav do
+ expect(page).to have_link(href: new_admin_session_path)
end
+ end
- context 'on a read-only instance' do
- before do
- allow(Gitlab::Database).to receive(:read_only?).and_return(true)
- end
-
- it 'disable removes admin mode and redirects to root page' do
- gitlab_disable_admin_mode
-
- expect(current_path).to eq root_path
-
- open_top_nav
+ it 'disable shows flash notice' do
+ gitlab_disable_admin_mode
- within_top_nav do
- expect(page).to have_link(href: new_admin_session_path)
- end
- end
- end
+ expect(page).to have_selector('.flash-notice')
end
- context 'with combined_menu feature flag on' do
- let(:needs_rewrite_for_combined_menu_flag_on) { true }
-
+ context 'on a read-only instance' do
before do
- stub_feature_flags(combined_menu: true)
+ allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end
- it_behaves_like 'combined_menu: feature flag examples'
- end
+ it 'disable removes admin mode and redirects to root page' do
+ gitlab_disable_admin_mode
- context 'with combined_menu feature flag off' do
- let(:needs_rewrite_for_combined_menu_flag_on) { false }
+ expect(current_path).to eq root_path
- before do
- stub_feature_flags(combined_menu: false)
- end
+ open_top_nav
- it_behaves_like 'combined_menu: feature flag examples'
+ within_top_nav do
+ expect(page).to have_link(href: new_admin_session_path)
+ end
+ end
end
end
diff --git a/spec/features/admin/admin_mode_spec.rb b/spec/features/admin/admin_mode_spec.rb
index 9fd83f4af6d..24a10d3677d 100644
--- a/spec/features/admin/admin_mode_spec.rb
+++ b/spec/features/admin/admin_mode_spec.rb
@@ -2,48 +2,62 @@
require 'spec_helper'
-RSpec.describe 'Admin mode' do
+RSpec.describe 'Admin mode', :js do
include MobileHelpers
include Spec::Support::Helpers::Features::TopNavSpecHelpers
include StubENV
let(:admin) { create(:admin) }
- shared_examples 'combined_menu: feature flag examples' do
+ before do
+ stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
+ end
+
+ context 'application setting :admin_mode is enabled', :request_store do
before do
- stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
+ sign_in(admin)
end
- context 'application setting :admin_mode is enabled', :request_store do
- before do
- sign_in(admin)
+ 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)
+ end
end
- context 'when not in admin mode' do
- it 'has no leave admin mode button' do
- visit new_admin_session_path
- open_top_nav
+ it 'can open pages not in admin scope' do
+ visit new_admin_session_path
+ open_top_nav_projects
- page.within('.navbar-sub-nav') do
- expect(page).not_to have_link(href: destroy_admin_session_path)
- end
+ within_top_nav do
+ click_link('Your projects')
end
- it 'can open pages not in admin scope' do
- visit new_admin_session_path
- open_top_nav_projects
+ expect(page).to have_current_path(dashboard_projects_path)
+ end
- within_top_nav do
- click_link('Your projects')
- end
+ it 'is necessary to provide credentials again before opening pages in admin scope' do
+ visit general_admin_application_settings_path # admin logged out because not in admin_mode
- expect(page).to have_current_path(dashboard_projects_path)
- end
+ expect(page).to have_current_path(new_admin_session_path)
+ end
+
+ it 'can enter admin mode' do
+ visit new_admin_session_path
- it 'is necessary to provide credentials again before opening pages in admin scope' do
- visit general_admin_application_settings_path # admin logged out because not in admin_mode
+ fill_in 'user_password', with: admin.password
- expect(page).to have_current_path(new_admin_session_path)
+ click_button 'Enter Admin Mode'
+
+ expect(page).to have_current_path(admin_root_path)
+ end
+
+ context 'on a read-only instance' do
+ before do
+ allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end
it 'can enter admin mode' do
@@ -55,151 +69,82 @@ RSpec.describe 'Admin mode' do
expect(page).to have_current_path(admin_root_path)
end
+ end
+ end
- context 'on a read-only instance' do
- before do
- allow(Gitlab::Database).to receive(:read_only?).and_return(true)
- end
-
- it 'can enter admin mode' do
- visit new_admin_session_path
-
- fill_in 'user_password', with: admin.password
+ context 'when in admin_mode' do
+ before do
+ gitlab_enable_admin_mode_sign_in(admin)
+ end
- click_button 'Enter Admin Mode'
+ it 'contains link to leave admin mode' do
+ open_top_nav
- expect(page).to have_current_path(admin_root_path)
- end
+ within_top_nav do
+ expect(page).to have_link(href: destroy_admin_session_path)
end
end
- context 'when in admin_mode' do
- before do
- gitlab_enable_admin_mode_sign_in(admin)
- end
+ it 'can leave admin mode using main dashboard link' do
+ gitlab_disable_admin_mode
- it 'contains link to leave admin mode' do
- open_top_nav
+ open_top_nav
- within_top_nav do
- expect(page).to have_link(href: destroy_admin_session_path)
- end
+ within_top_nav do
+ expect(page).to have_link(href: new_admin_session_path)
end
+ end
- it 'can leave admin mode using main dashboard link', :js do
- gitlab_disable_admin_mode
-
- open_top_nav
+ it 'can open pages not in admin scope' do
+ open_top_nav_projects
- within_top_nav do
- expect(page).to have_link(href: new_admin_session_path)
- end
+ within_top_nav do
+ click_link('Your projects')
end
- it 'can leave admin mode using dropdown menu on smaller screens', :js do
- skip('pending responsive development under :combined_menu feature flag') if Feature.enabled?(:combined_menu, default_enabled: :yaml)
+ expect(page).to have_current_path(dashboard_projects_path)
+ end
- resize_screen_xs
+ context 'nav bar' do
+ it 'shows admin dashboard links on bigger screen' do
visit root_dashboard_path
-
- find('.header-more').click unless Feature.enabled?(:combined_menu, default_enabled: :yaml)
-
- gitlab_disable_admin_mode
-
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)
+ expect(page).to have_link(text: 'Admin', href: admin_root_path, visible: true)
+ expect(page).to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true)
end
+ end
- it 'can open pages not in admin scope' do
- open_top_nav_projects
-
- 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
- visit root_dashboard_path
- open_top_nav
-
- 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
- skip('pending responsive development under :combined_menu feature flag') if Feature.enabled?(:combined_menu, default_enabled: :yaml)
-
- resize_screen_xs
- visit root_dashboard_path
-
- expect(page).not_to have_link(text: 'Leave Admin Mode', href: destroy_admin_session_path, visible: true)
-
- find('.header-more').click
-
- 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
- end
+ context 'on a read-only instance' do
+ before do
+ allow(Gitlab::Database).to receive(:read_only?).and_return(true)
end
- context 'on a read-only instance' do
- before do
- allow(Gitlab::Database).to receive(:read_only?).and_return(true)
- end
-
- it 'can leave admin mode', :js do
- gitlab_disable_admin_mode
+ it 'can leave admin mode' do
+ gitlab_disable_admin_mode
- open_top_nav
+ open_top_nav
- within_top_nav do
- expect(page).to have_link(href: new_admin_session_path)
- end
+ within_top_nav do
+ expect(page).to have_link(href: new_admin_session_path)
end
end
end
end
-
- context 'application setting :admin_mode is disabled' do
- before do
- stub_application_setting(admin_mode: false)
- sign_in(admin)
- end
-
- it 'shows no admin mode buttons in navbar' do
- visit admin_root_path
- open_top_nav
-
- 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', :js do
- let(:needs_rewrite_for_combined_menu_flag_on) { true }
-
+ context 'application setting :admin_mode is disabled' do
before do
- stub_feature_flags(combined_menu: true)
+ stub_application_setting(admin_mode: false)
+ sign_in(admin)
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 }
+ it 'shows no admin mode buttons in navbar' do
+ visit admin_root_path
+ open_top_nav
- before do
- stub_feature_flags(combined_menu: false)
+ expect(page).not_to have_link(href: new_admin_session_path)
+ expect(page).not_to have_link(href: destroy_admin_session_path)
end
-
- it_behaves_like 'combined_menu: feature flag examples'
end
end
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 9efb31ef4c1..4a0f7ccbb0a 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -190,7 +190,7 @@ RSpec.describe 'Admin updates settings' do
accept_terms(admin)
page.within('.as-terms') do
- check 'Require all users to accept Terms of Service and Privacy Policy when they access GitLab.'
+ check 'All users must accept the Terms of Service and Privacy Policy to access GitLab'
fill_in 'Terms of Service Agreement', with: 'Be nice!'
click_button 'Save changes'
end
@@ -490,7 +490,7 @@ RSpec.describe 'Admin updates settings' do
it 'change Prometheus settings' do
page.within('.as-prometheus') do
- check 'Enable Prometheus Metrics'
+ check 'Enable health and performance metrics endpoint'
click_button 'Save changes'
end
@@ -502,23 +502,23 @@ RSpec.describe 'Admin updates settings' do
group = create(:group)
page.within('.as-performance-bar') do
- check 'Enable access to the Performance Bar'
- fill_in 'Allowed group', with: group.path
+ check 'Allow non-administrators to access to the performance bar'
+ fill_in 'Allow access to members of the following group', with: group.path
click_on 'Save changes'
end
expect(page).to have_content "Application settings saved successfully"
- expect(find_field('Enable access to the Performance Bar')).to be_checked
- expect(find_field('Allowed group').value).to eq group.path
+ expect(find_field('Allow non-administrators to access to the performance bar')).to be_checked
+ expect(find_field('Allow access to members of the following group').value).to eq group.path
page.within('.as-performance-bar') do
- uncheck 'Enable access to the Performance Bar'
+ uncheck 'Allow non-administrators to access to the performance bar'
click_on 'Save changes'
end
expect(page).to have_content 'Application settings saved successfully'
- expect(find_field('Enable access to the Performance Bar')).not_to be_checked
- expect(find_field('Allowed group').value).to be_nil
+ expect(find_field('Allow non-administrators to access to the performance bar')).not_to be_checked
+ expect(find_field('Allow access to members of the following group').value).to be_nil
end
it 'loads usage ping payload on click', :js do
@@ -585,7 +585,7 @@ RSpec.describe 'Admin updates settings' do
page.within('.as-help-page') do
fill_in 'Additional text to show on the Help page', with: 'Example text'
- check 'Hide marketing-related entries from the Help page.'
+ check 'Hide marketing-related entries from the Help page'
fill_in 'Support page URL', with: new_support_url
fill_in 'Documentation pages URL', with: new_documentation_url
click_button 'Save changes'
@@ -634,7 +634,7 @@ RSpec.describe 'Admin updates settings' do
it "change Pages Let's Encrypt settings" do
visit preferences_admin_application_settings_path
page.within('.as-pages') do
- fill_in 'Email', with: 'my@test.example.com'
+ fill_in "Let's Encrypt email", with: 'my@test.example.com'
check "I have read and agree to the Let's Encrypt Terms of Service"
click_button 'Save changes'
end
diff --git a/spec/features/admin/dashboard_spec.rb b/spec/features/admin/dashboard_spec.rb
index 618fae3e46b..112dc9e01d8 100644
--- a/spec/features/admin/dashboard_spec.rb
+++ b/spec/features/admin/dashboard_spec.rb
@@ -19,8 +19,8 @@ RSpec.describe 'admin visits dashboard' do
# Make sure the fork_networks & fork_networks reltuples have been updated
# to get a correct count on postgresql
- ActiveRecord::Base.connection.execute('ANALYZE fork_networks')
- ActiveRecord::Base.connection.execute('ANALYZE fork_network_members')
+ ForkNetwork.connection.execute('ANALYZE fork_networks')
+ ForkNetwork.connection.execute('ANALYZE fork_network_members')
visit admin_root_path
diff --git a/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb b/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb
index 6f091d37995..22a27b33671 100644
--- a/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb
+++ b/spec/features/admin/integrations/user_activates_mattermost_slash_command_spec.rb
@@ -11,6 +11,12 @@ RSpec.describe 'User activates the instance-level Mattermost Slash Command integ
end
let(:edit_path) { edit_admin_application_settings_integration_path(:mattermost_slash_commands) }
+ let(:overrides_path) { overrides_admin_application_settings_integration_path(:mattermost_slash_commands) }
include_examples 'user activates the Mattermost Slash Command integration'
+
+ it 'displays navigation tabs' do
+ expect(page).to have_link('Settings', href: edit_path)
+ expect(page).to have_link('Projects using custom settings', href: overrides_path)
+ end
end
diff --git a/spec/features/admin/services/admin_visits_service_templates_spec.rb b/spec/features/admin/services/admin_visits_service_templates_spec.rb
deleted file mode 100644
index d367867ebb5..00000000000
--- a/spec/features/admin/services/admin_visits_service_templates_spec.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'Admin visits service templates' do
- let(:admin) { create(:user, :admin) }
- let(:slack_integration) { Integration.for_template.find { |s| s.type == 'SlackService' } }
-
- before do
- sign_in(admin)
- gitlab_enable_admin_mode_sign_in(admin)
- end
-
- context 'without an active service template' do
- before do
- visit(admin_application_settings_services_path)
- end
-
- it 'does not show service template content' do
- expect(page).not_to have_content('Service template allows you to set default values for integrations')
- end
- end
-
- context 'with an active service template' do
- before do
- create(:integrations_slack, :template, active: true)
- visit(admin_application_settings_services_path)
- end
-
- it 'shows service template content' do
- expect(page).to have_content('Service template allows you to set default values for integrations')
- end
-
- context 'without instance-level integration' do
- it 'shows a link to service template' do
- expect(page).to have_link('Slack', href: edit_admin_application_settings_service_path(slack_integration.id))
- expect(page).not_to have_link('Slack', href: edit_admin_application_settings_integration_path(slack_integration))
- end
- end
-
- context 'with instance-level integration' do
- before do
- create(:integrations_slack, instance: true, project: nil)
- visit(admin_application_settings_services_path)
- end
-
- it 'shows a link to instance-level integration' do
- expect(page).not_to have_link('Slack', href: edit_admin_application_settings_service_path(slack_integration.id))
- expect(page).to have_link('Slack', href: edit_admin_application_settings_integration_path(slack_integration))
- end
- end
- end
-end
diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb
index e6eb76b13eb..624bfde7359 100644
--- a/spec/features/admin/users/user_spec.rb
+++ b/spec/features/admin/users/user_spec.rb
@@ -90,6 +90,39 @@ RSpec.describe 'Admin::Users::User' do
end
end
+ context 'when user is the sole owner of a group' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:user_sole_owner_of_group) { create(:user) }
+
+ before do
+ group.add_owner(user_sole_owner_of_group)
+ end
+
+ it 'shows `Delete user and contributions` action but not `Delete user` action', :js do
+ visit admin_user_path(user_sole_owner_of_group)
+
+ click_user_dropdown_toggle(user_sole_owner_of_group.id)
+
+ expect(page).to have_button('Delete user and contributions')
+ expect(page).not_to have_button('Delete user', exact: true)
+ end
+
+ it 'allows user to be deleted by using the `Delete user and contributions` action', :js do
+ visit admin_user_path(user_sole_owner_of_group)
+
+ click_action_in_user_dropdown(user_sole_owner_of_group.id, 'Delete user and contributions')
+
+ page.within('[role="dialog"]') do
+ fill_in('username', with: user_sole_owner_of_group.name)
+ click_button('Delete user and contributions')
+ end
+
+ wait_for_requests
+
+ expect(page).to have_content('The user is being deleted.')
+ end
+ end
+
describe 'Impersonation' do
let_it_be(:another_user) { create(:user) }
@@ -151,7 +184,7 @@ RSpec.describe 'Admin::Users::User' do
it 'logs in as the user when impersonate is clicked' do
subject
- find('[data-qa-selector="user_menu"]').click
+ find('[data-qa-selector="user_menu"]').click # rubocop:disable QA/SelectorUsage
expect(page.find(:css, '[data-testid="user-profile-link"]')['data-user']).to eql(another_user.username)
end
@@ -187,7 +220,7 @@ RSpec.describe 'Admin::Users::User' do
it 'logs out of impersonated user back to original user' do
subject
- find('[data-qa-selector="user_menu"]').click
+ find('[data-qa-selector="user_menu"]').click # rubocop:disable QA/SelectorUsage
expect(page.find(:css, '[data-testid="user-profile-link"]')['data-user']).to eq(current_user.username)
end
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index 4b52bb953ed..9a5b5bbfc34 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -5,6 +5,7 @@ require 'spec_helper'
RSpec.describe 'Project issue boards', :js do
include DragTo
include MobileHelpers
+ include BoardHelpers
let_it_be(:group) { create(:group, :nested) }
let_it_be(:project) { create(:project, :public, namespace: group) }
@@ -12,584 +13,508 @@ RSpec.describe 'Project issue boards', :js do
let_it_be(:user) { create(:user) }
let_it_be(:user2) { create(:user) }
- before do
- project.add_maintainer(user)
- project.add_maintainer(user2)
-
- sign_in(user)
-
- set_cookie('sidebar_collapsed', 'true')
- end
-
- context 'no lists' do
+ context 'signed in user' do
before do
- visit_project_board_path_without_query_limit(project, board)
- end
-
- it 'creates default lists' do
- lists = %w[Open Closed]
-
- wait_for_requests
+ project.add_maintainer(user)
+ project.add_maintainer(user2)
- expect(page).to have_selector('.board', count: 2)
+ sign_in(user)
- page.all('.board').each_with_index do |list, i|
- expect(list.find('.board-title')).to have_content(lists[i])
- end
+ set_cookie('sidebar_collapsed', 'true')
end
- end
- context 'with lists' do
- let_it_be(:milestone) { create(:milestone, project: project) }
-
- let_it_be(:planning) { create(:label, project: project, name: 'Planning', description: 'Test') }
- let_it_be(:development) { create(:label, project: project, name: 'Development') }
- let_it_be(:testing) { create(:label, project: project, name: 'Testing') }
- let_it_be(:bug) { create(:label, project: project, name: 'Bug') }
- let_it_be(:backlog) { create(:label, project: project, name: 'Backlog') }
- let_it_be(:closed) { create(:label, project: project, name: 'Closed') }
- let_it_be(:accepting) { create(:label, project: project, name: 'Accepting Merge Requests') }
- let_it_be(:a_plus) { create(:label, project: project, name: 'A+') }
- let_it_be(:list1) { create(:list, board: board, label: planning, position: 0) }
- let_it_be(:list2) { create(:list, board: board, label: development, position: 1) }
- let_it_be(:backlog_list) { create(:backlog_list, board: board) }
-
- let_it_be(:confidential_issue) { create(:labeled_issue, :confidential, project: project, author: user, labels: [planning], relative_position: 9) }
- let_it_be(:issue1) { create(:labeled_issue, project: project, title: 'aaa', description: '111', assignees: [user], labels: [planning], relative_position: 8) }
- let_it_be(:issue2) { create(:labeled_issue, project: project, title: 'bbb', description: '222', author: user2, labels: [planning], relative_position: 7) }
- let_it_be(:issue3) { create(:labeled_issue, project: project, title: 'ccc', description: '333', labels: [planning], relative_position: 6) }
- let_it_be(:issue4) { create(:labeled_issue, project: project, title: 'ddd', description: '444', labels: [planning], relative_position: 5) }
- let_it_be(:issue5) { create(:labeled_issue, project: project, title: 'eee', description: '555', labels: [planning], milestone: milestone, relative_position: 4) }
- let_it_be(:issue6) { create(:labeled_issue, project: project, title: 'fff', description: '666', labels: [planning, development], relative_position: 3) }
- let_it_be(:issue7) { create(:labeled_issue, project: project, title: 'ggg', description: '777', labels: [development], relative_position: 2) }
- let_it_be(:issue8) { create(:closed_issue, project: project, title: 'hhh', description: '888') }
- let_it_be(:issue9) { create(:labeled_issue, project: project, title: 'iii', description: '999', labels: [planning, testing, bug, accepting], relative_position: 1) }
- let_it_be(:issue10) { create(:labeled_issue, project: project, title: 'issue +', description: 'A+ great issue', labels: [a_plus]) }
-
- before do
- stub_feature_flags(board_new_list: false)
+ context 'no lists' do
+ before do
+ visit_project_board_path_without_query_limit(project, board)
+ end
- visit_project_board_path_without_query_limit(project, board)
+ it 'creates default lists' do
+ lists = %w[Open Closed]
- wait_for_requests
+ wait_for_requests
- expect(page).to have_selector('.board', count: 4)
- expect(find('.board:nth-child(2)')).to have_selector('.board-card')
- expect(find('.board:nth-child(3)')).to have_selector('.board-card')
- expect(find('.board:nth-child(4)')).to have_selector('.board-card')
- end
+ expect(page).to have_selector('.board', count: 2)
- it 'shows description tooltip on list title', :quarantine do
- page.within('.board:nth-child(2)') do
- expect(find('.board-title span.has-tooltip')[:title]).to eq('Test')
+ page.all('.board').each_with_index do |list, i|
+ expect(list.find('.board-title')).to have_content(lists[i])
+ end
end
end
- it 'shows issues in lists' do
- wait_for_board_cards(2, 8)
- wait_for_board_cards(3, 2)
- end
+ context 'with lists' do
+ let_it_be(:milestone) { create(:milestone, project: project) }
+
+ let_it_be(:planning) { create(:label, project: project, name: 'Planning', description: 'Test') }
+ let_it_be(:development) { create(:label, project: project, name: 'Development') }
+ let_it_be(:testing) { create(:label, project: project, name: 'Testing') }
+ let_it_be(:bug) { create(:label, project: project, name: 'Bug') }
+ let_it_be(:backlog) { create(:label, project: project, name: 'Backlog') }
+ let_it_be(:closed) { create(:label, project: project, name: 'Closed') }
+ let_it_be(:accepting) { create(:label, project: project, name: 'Accepting Merge Requests') }
+ let_it_be(:a_plus) { create(:label, project: project, name: 'A+') }
+ let_it_be(:list1) { create(:list, board: board, label: planning, position: 0) }
+ let_it_be(:list2) { create(:list, board: board, label: development, position: 1) }
+ let_it_be(:backlog_list) { create(:backlog_list, board: board) }
+
+ let_it_be(:confidential_issue) { create(:labeled_issue, :confidential, project: project, author: user, labels: [planning], relative_position: 9) }
+ let_it_be(:issue1) { create(:labeled_issue, project: project, title: 'aaa', description: '111', assignees: [user], labels: [planning], relative_position: 8) }
+ let_it_be(:issue2) { create(:labeled_issue, project: project, title: 'bbb', description: '222', author: user2, labels: [planning], relative_position: 7) }
+ let_it_be(:issue3) { create(:labeled_issue, project: project, title: 'ccc', description: '333', labels: [planning], relative_position: 6) }
+ let_it_be(:issue4) { create(:labeled_issue, project: project, title: 'ddd', description: '444', labels: [planning], relative_position: 5) }
+ let_it_be(:issue5) { create(:labeled_issue, project: project, title: 'eee', description: '555', labels: [planning], milestone: milestone, relative_position: 4) }
+ let_it_be(:issue6) { create(:labeled_issue, project: project, title: 'fff', description: '666', labels: [planning, development], relative_position: 3) }
+ let_it_be(:issue7) { create(:labeled_issue, project: project, title: 'ggg', description: '777', labels: [development], relative_position: 2) }
+ let_it_be(:issue8) { create(:closed_issue, project: project, title: 'hhh', description: '888') }
+ let_it_be(:issue9) { create(:labeled_issue, project: project, title: 'iii', description: '999', labels: [planning, testing, bug, accepting], relative_position: 1) }
+ let_it_be(:issue10) { create(:labeled_issue, project: project, title: 'issue +', description: 'A+ great issue', labels: [a_plus]) }
- it 'shows confidential issues with icon' do
- page.within(find('.board:nth-child(2)')) do
- expect(page).to have_selector('.confidential-icon', count: 1)
+ before do
+ visit_project_board_path_without_query_limit(project, board)
end
- end
-
- it 'search closed list' do
- find('.filtered-search').set(issue8.title)
- find('.filtered-search').native.send_keys(:enter)
- wait_for_requests
+ it 'shows description tooltip on list title', :quarantine do
+ page.within('.board:nth-child(2)') do
+ expect(find('.board-title span.has-tooltip')[:title]).to eq('Test')
+ end
+ end
- expect(find('.board:nth-child(2)')).to have_selector('.board-card', count: 0)
- expect(find('.board:nth-child(3)')).to have_selector('.board-card', count: 0)
- expect(find('.board:nth-child(4)')).to have_selector('.board-card', count: 1)
- end
+ it 'shows issues in lists' do
+ wait_for_board_cards(2, 8)
+ wait_for_board_cards(3, 2)
+ end
- it 'search list' do
- find('.filtered-search').set(issue5.title)
- find('.filtered-search').native.send_keys(:enter)
+ it 'shows confidential issues with icon' do
+ page.within(find('.board:nth-child(2)')) do
+ expect(page).to have_selector('.confidential-icon', count: 1)
+ end
+ end
- wait_for_requests
+ it 'search closed list' do
+ find('.filtered-search').set(issue8.title)
+ find('.filtered-search').native.send_keys(:enter)
- expect(find('.board:nth-child(2)')).to have_selector('.board-card', count: 1)
- expect(find('.board:nth-child(3)')).to have_selector('.board-card', count: 0)
- expect(find('.board:nth-child(4)')).to have_selector('.board-card', count: 0)
- end
+ wait_for_requests
- context 'search list negation queries' do
- before do
- visit_project_board_path_without_query_limit(project, board)
+ expect(find('.board:nth-child(2)')).to have_selector('.board-card', count: 0)
+ expect(find('.board:nth-child(3)')).to have_selector('.board-card', count: 0)
+ expect(find('.board:nth-child(4)')).to have_selector('.board-card', count: 1)
end
- it 'does not have the != option' do
- find('.filtered-search').set('label:')
+ it 'search list' do
+ find('.filtered-search').set(issue5.title)
+ find('.filtered-search').native.send_keys(:enter)
wait_for_requests
- within('#js-dropdown-operator') do
- tokens = all(:css, 'li.filter-dropdown-item')
- expect(tokens.count).to eq(2)
- button = tokens[0].find('button')
- expect(button).to have_content('=')
- button = tokens[1].find('button')
- expect(button).to have_content('!=')
- end
- end
- end
- it 'allows user to delete board' do
- remove_list
+ expect(find('.board:nth-child(2)')).to have_selector('.board-card', count: 1)
+ expect(find('.board:nth-child(3)')).to have_selector('.board-card', count: 0)
+ expect(find('.board:nth-child(4)')).to have_selector('.board-card', count: 0)
+ end
- wait_for_requests
+ context 'search list negation queries' do
+ before do
+ visit_project_board_path_without_query_limit(project, board)
+ end
- expect(page).to have_selector('.board', count: 3)
- end
+ it 'does not have the != option' do
+ find('.filtered-search').set('label:')
- it 'infinite scrolls list' do
- create_list(:labeled_issue, 30, project: project, labels: [planning])
+ wait_for_requests
+ within('#js-dropdown-operator') do
+ tokens = all(:css, 'li.filter-dropdown-item')
+ expect(tokens.count).to eq(2)
+ button = tokens[0].find('button')
+ expect(button).to have_content('=')
+ button = tokens[1].find('button')
+ expect(button).to have_content('!=')
+ end
+ end
+ end
- visit_project_board_path_without_query_limit(project, board)
+ it 'allows user to delete board' do
+ remove_list
- page.within(find('.board:nth-child(2)')) do
- 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')
+ wait_for_requests
- find('.board .board-list')
+ expect(page).to have_selector('.board', count: 3)
+ end
- 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
+ it 'infinite scrolls list' do
+ create_list(:labeled_issue, 30, project: project, labels: [planning])
- expect(page).to have_selector('.board-card', count: 20)
- expect(page).to have_content('Showing 20 of 38 issues')
+ visit_project_board_path_without_query_limit(project, board)
- find('.board .board-list')
+ page.within(find('.board:nth-child(2)')) do
+ 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')
- 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
+ find('.board .board-list')
- expect(page).to have_selector('.board-card', count: 30)
- expect(page).to have_content('Showing 30 of 38 issues')
+ 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
- find('.board .board-list')
+ expect(page).to have_selector('.board-card', count: 20)
+ expect(page).to have_content('Showing 20 of 38 issues')
- 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
+ find('.board .board-list')
- expect(page).to have_selector('.board-card', count: 38)
- expect(page).to have_content('Showing all issues')
- end
- end
+ 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
- context 'closed' do
- it 'shows list of closed issues' do
- wait_for_board_cards(4, 1)
- wait_for_requests
- end
+ expect(page).to have_selector('.board-card', count: 30)
+ expect(page).to have_content('Showing 30 of 38 issues')
- it 'moves issue to closed' do
- drag(list_from_index: 1, list_to_index: 3)
+ find('.board .board-list')
- wait_for_board_cards(2, 7)
- wait_for_board_cards(3, 2)
- wait_for_board_cards(4, 2)
+ 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(find('.board:nth-child(2)')).not_to have_content(issue9.title)
- expect(find('.board:nth-child(4)')).to have_selector('.board-card', count: 2)
- expect(find('.board:nth-child(4)')).to have_content(issue9.title)
- expect(find('.board:nth-child(4)')).not_to have_content(planning.title)
+ expect(page).to have_selector('.board-card', count: 38)
+ expect(page).to have_content('Showing all issues')
+ end
end
- it 'removes all of the same issue to closed' do
- drag(list_from_index: 1, list_to_index: 3)
-
- wait_for_board_cards(2, 7)
- wait_for_board_cards(3, 2)
- wait_for_board_cards(4, 2)
+ context 'closed' do
+ it 'shows list of closed issues' do
+ wait_for_board_cards(4, 1)
+ wait_for_requests
+ end
- expect(find('.board:nth-child(2)')).not_to have_content(issue9.title)
- expect(find('.board:nth-child(4)')).to have_content(issue9.title)
- expect(find('.board:nth-child(4)')).not_to have_content(planning.title)
- end
- end
+ it 'moves issue to closed' do
+ drag(list_from_index: 1, list_to_index: 3)
- context 'lists' do
- it 'changes position of list' do
- drag(list_from_index: 2, list_to_index: 1, selector: '.board-header')
+ wait_for_board_cards(2, 7)
+ wait_for_board_cards(3, 2)
+ wait_for_board_cards(4, 2)
- wait_for_board_cards(2, 2)
- wait_for_board_cards(3, 8)
- wait_for_board_cards(4, 1)
+ expect(find('.board:nth-child(2)')).not_to have_content(issue9.title)
+ expect(find('.board:nth-child(4)')).to have_selector('.board-card', count: 2)
+ expect(find('.board:nth-child(4)')).to have_content(issue9.title)
+ expect(find('.board:nth-child(4)')).not_to have_content(planning.title)
+ end
- expect(find('.board:nth-child(2)')).to have_content(development.title)
- expect(find('.board:nth-child(3)')).to have_content(planning.title)
+ it 'removes all of the same issue to closed' do
+ drag(list_from_index: 1, list_to_index: 3)
- # Make sure list positions are preserved after a reload
- visit_project_board_path_without_query_limit(project, board)
+ wait_for_board_cards(2, 7)
+ wait_for_board_cards(3, 2)
+ wait_for_board_cards(4, 2)
- expect(find('.board:nth-child(2)')).to have_content(development.title)
- expect(find('.board:nth-child(3)')).to have_content(planning.title)
+ expect(find('.board:nth-child(2)')).not_to have_content(issue9.title)
+ expect(find('.board:nth-child(4)')).to have_content(issue9.title)
+ expect(find('.board:nth-child(4)')).not_to have_content(planning.title)
+ end
end
- it 'dragging does not duplicate list' do
- selector = '.board:not(.is-ghost) .board-header'
- expect(page).to have_selector(selector, text: development.title, count: 1)
+ context 'lists' do
+ it 'changes position of list' do
+ drag(list_from_index: 2, list_to_index: 1, selector: '.board-header')
- drag(list_from_index: 2, list_to_index: 1, selector: '.board-header', perform_drop: false)
+ expect(find('.board:nth-child(2) [data-testid="board-list-header"]')).to have_content(development.title)
+ expect(find('.board:nth-child(3) [data-testid="board-list-header"]')).to have_content(planning.title)
- expect(page).to have_selector(selector, text: development.title, count: 1)
- end
+ # Make sure list positions are preserved after a reload
+ visit_project_board_path_without_query_limit(project, board)
- it 'issue moves between lists and does not show the "Development" label since the card is in the "Development" list label' do
- drag(list_from_index: 1, from_index: 1, list_to_index: 2)
+ expect(find('.board:nth-child(2) [data-testid="board-list-header"]')).to have_content(development.title)
+ expect(find('.board:nth-child(3) [data-testid="board-list-header"]')).to have_content(planning.title)
+ end
- wait_for_board_cards(2, 7)
- wait_for_board_cards(3, 2)
- wait_for_board_cards(4, 1)
+ context 'without backlog and closed lists' do
+ let_it_be(:board) { create(:board, project: project, hide_backlog_list: true, hide_closed_list: true) }
+ let_it_be(:list1) { create(:list, board: board, label: planning, position: 0) }
+ let_it_be(:list2) { create(:list, board: board, label: development, position: 1) }
- expect(find('.board:nth-child(3)')).to have_content(issue6.title)
- expect(find('.board:nth-child(3)').all('.board-card').last).not_to have_content(development.title)
- end
+ it 'changes position of list' do
+ visit_project_board_path_without_query_limit(project, board)
- it 'issue moves between lists and does not show the "Planning" label since the card is in the "Planning" list label' do
- drag(list_from_index: 2, list_to_index: 1)
+ drag(list_from_index: 0, list_to_index: 1, selector: '.board-header')
- wait_for_board_cards(2, 9)
- wait_for_board_cards(3, 1)
- wait_for_board_cards(4, 1)
+ expect(find('.board:nth-child(1) [data-testid="board-list-header"]')).to have_content(development.title)
+ expect(find('.board:nth-child(2) [data-testid="board-list-header"]')).to have_content(planning.title)
- expect(find('.board:nth-child(2)')).to have_content(issue7.title)
- expect(find('.board:nth-child(2)').all('.board-card').first).not_to have_content(planning.title)
- end
+ # Make sure list positions are preserved after a reload
+ visit_project_board_path_without_query_limit(project, board)
- it 'issue moves from closed' do
- drag(list_from_index: 2, list_to_index: 3)
+ expect(find('.board:nth-child(1) [data-testid="board-list-header"]')).to have_content(development.title)
+ expect(find('.board:nth-child(2) [data-testid="board-list-header"]')).to have_content(planning.title)
+ end
+ end
- wait_for_board_cards(2, 8)
- wait_for_board_cards(3, 1)
- wait_for_board_cards(4, 2)
+ it 'dragging does not duplicate list' do
+ selector = '.board:not(.is-ghost) .board-header'
+ expect(page).to have_selector(selector, text: development.title, count: 1)
- expect(find('.board:nth-child(4)')).to have_content(issue8.title)
- end
+ drag(list_from_index: 2, list_to_index: 1, selector: '.board-header', perform_drop: false)
- context 'issue card' do
- it 'shows assignee' do
- page.within(find('.board:nth-child(2)')) do
- expect(page).to have_selector('.avatar', count: 1)
- end
+ expect(page).to have_selector(selector, text: development.title, count: 1)
end
- context 'list header' do
- let(:total_planning_issues) { "8" }
+ it 'issue moves between lists and does not show the "Development" label since the card is in the "Development" list label' do
+ drag(list_from_index: 1, from_index: 1, list_to_index: 2)
- it 'shows issue count on the list' do
- page.within(find(".board:nth-child(2)")) do
- expect(page.find('[data-testid="board-items-count"]')).to have_text(total_planning_issues)
- expect(page).not_to have_selector('.js-max-issue-size')
- end
- end
+ wait_for_board_cards(2, 7)
+ wait_for_board_cards(3, 2)
+ wait_for_board_cards(4, 1)
+
+ expect(find('.board:nth-child(3)')).to have_content(issue6.title)
+ expect(find('.board:nth-child(3)').all('.board-card').last).not_to have_content(development.title)
end
- end
- context 'new list' do
- it 'shows all labels in new list dropdown' do
- click_button 'Add list'
+ it 'issue moves between lists and does not show the "Planning" label since the card is in the "Planning" list label' do
+ drag(list_from_index: 2, list_to_index: 1)
- wait_for_requests
+ wait_for_board_cards(2, 9)
+ wait_for_board_cards(3, 1)
+ wait_for_board_cards(4, 1)
- page.within('.dropdown-menu-issues-board-new') do
- expect(page).to have_content(planning.title)
- expect(page).to have_content(development.title)
- expect(page).to have_content(testing.title)
- end
+ expect(find('.board:nth-child(2)')).to have_content(issue7.title)
+ expect(find('.board:nth-child(2)').all('.board-card').first).not_to have_content(planning.title)
end
- it 'creates new list for label' do
- click_button 'Add list'
- wait_for_requests
-
- page.within('.dropdown-menu-issues-board-new') do
- click_link testing.title
- end
+ it 'issue moves from closed' do
+ drag(list_from_index: 2, list_to_index: 3)
- wait_for_requests
+ wait_for_board_cards(2, 8)
+ wait_for_board_cards(3, 1)
+ wait_for_board_cards(4, 2)
- expect(page).to have_selector('.board', count: 5)
+ expect(find('.board:nth-child(4)')).to have_content(issue8.title)
end
- it 'creates new list for Backlog label' do
- click_button 'Add list'
- wait_for_requests
-
- page.within('.dropdown-menu-issues-board-new') do
- click_link backlog.title
+ context 'issue card' do
+ it 'shows assignee' do
+ page.within(find('.board:nth-child(2)')) do
+ expect(page).to have_selector('.avatar', count: 1)
+ end
end
- wait_for_requests
+ context 'list header' do
+ let(:total_planning_issues) { "8" }
- expect(page).to have_selector('.board', count: 5)
+ it 'shows issue count on the list' do
+ page.within(find(".board:nth-child(2)")) do
+ expect(page.find('[data-testid="board-items-count"]')).to have_text(total_planning_issues)
+ expect(page).not_to have_selector('.js-max-issue-size')
+ end
+ end
+ end
end
+ end
+
+ context 'filtering' do
+ it 'filters by author' do
+ set_filter("author", user2.username)
+ click_filter_link(user2.username)
+ submit_filter
- it 'creates new list for Closed label' do
- click_button 'Add list'
wait_for_requests
+ wait_for_board_cards(2, 1)
+ wait_for_empty_boards((3..4))
+ end
- page.within('.dropdown-menu-issues-board-new') do
- click_link closed.title
- end
+ it 'filters by assignee' do
+ set_filter("assignee", user.username)
+ click_filter_link(user.username)
+ submit_filter
wait_for_requests
- expect(page).to have_selector('.board', count: 5)
+ wait_for_board_cards(2, 1)
+ wait_for_empty_boards((3..4))
end
- it 'keeps dropdown open after adding new list' do
- click_button 'Add list'
- wait_for_requests
-
- page.within('.dropdown-menu-issues-board-new') do
- click_link closed.title
- end
+ it 'filters by milestone' do
+ set_filter("milestone", "\"#{milestone.title}")
+ click_filter_link(milestone.title)
+ submit_filter
wait_for_requests
-
- expect(page).to have_css('#js-add-list.show')
+ wait_for_board_cards(2, 1)
+ wait_for_board_cards(3, 0)
+ wait_for_board_cards(4, 0)
end
- it 'creates new list from a new label' do
- click_button 'Add list'
+ it 'filters by label' do
+ set_filter("label", testing.title)
+ click_filter_link(testing.title)
+ submit_filter
wait_for_requests
+ wait_for_board_cards(2, 1)
+ wait_for_empty_boards((3..4))
+ end
- click_link 'Create project label'
+ it 'filters by label with encoded character' do
+ set_filter("label", a_plus.title)
+ click_filter_link(a_plus.title)
+ submit_filter
- fill_in('new_label_name', with: 'Testing New Label - with list')
+ wait_for_board_cards(1, 1)
+ wait_for_empty_boards((2..4))
+ end
- first('.suggest-colors a').click
+ it 'filters by label with space after reload', :quarantine do
+ set_filter("label", "\"#{accepting.title}")
+ click_filter_link(accepting.title)
+ submit_filter
- click_button 'Create'
+ # Test after reload
+ page.evaluate_script 'window.location.reload()'
+ wait_for_board_cards(2, 1)
+ wait_for_empty_boards((3..4))
wait_for_requests
- wait_for_requests
- expect(page).to have_selector('.board', count: 5)
+ page.within(find('.board:nth-child(2)')) do
+ expect(page.find('.board-header')).to have_content('1')
+ expect(page).to have_selector('.board-card', count: 1)
+ end
+
+ page.within(find('.board:nth-child(3)')) do
+ expect(page.find('.board-header')).to have_content('0')
+ expect(page).to have_selector('.board-card', count: 0)
+ end
end
- end
- end
- context 'filtering' do
- it 'filters by author' do
- set_filter("author", user2.username)
- click_filter_link(user2.username)
- submit_filter
+ it 'removes filtered labels' do
+ inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
+ set_filter("label", testing.title)
+ click_filter_link(testing.title)
+ submit_filter
- wait_for_requests
- wait_for_board_cards(2, 1)
- wait_for_empty_boards((3..4))
- end
+ wait_for_board_cards(2, 1)
- it 'filters by assignee' do
- set_filter("assignee", user.username)
- click_filter_link(user.username)
- submit_filter
+ find('.clear-search').click
+ submit_filter
+ end
- wait_for_requests
+ wait_for_board_cards(2, 8)
+ end
- wait_for_board_cards(2, 1)
- wait_for_empty_boards((3..4))
- end
+ it 'infinite scrolls list with label filter' do
+ create_list(:labeled_issue, 30, project: project, labels: [planning, testing])
- it 'filters by milestone' do
- set_filter("milestone", "\"#{milestone.title}")
- click_filter_link(milestone.title)
- submit_filter
+ set_filter("label", testing.title)
+ click_filter_link(testing.title)
+ inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
+ submit_filter
+ end
- wait_for_requests
- wait_for_board_cards(2, 1)
- wait_for_board_cards(3, 0)
- wait_for_board_cards(4, 0)
- end
+ wait_for_requests
- it 'filters by label' do
- set_filter("label", testing.title)
- click_filter_link(testing.title)
- submit_filter
+ page.within(find('.board:nth-child(2)')) do
+ 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')
- wait_for_requests
- wait_for_board_cards(2, 1)
- wait_for_empty_boards((3..4))
- end
+ find('.board .board-list')
- it 'filters by label with encoded character' do
- set_filter("label", a_plus.title)
- click_filter_link(a_plus.title)
- submit_filter
+ 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
- wait_for_board_cards(1, 1)
- wait_for_empty_boards((2..4))
- end
+ expect(page).to have_selector('.board-card', count: 20)
+ expect(page).to have_content('Showing 20 of 31 issues')
- it 'filters by label with space after reload', :quarantine do
- set_filter("label", "\"#{accepting.title}")
- click_filter_link(accepting.title)
- submit_filter
+ find('.board .board-list')
- # Test after reload
- page.evaluate_script 'window.location.reload()'
- wait_for_board_cards(2, 1)
- wait_for_empty_boards((3..4))
+ 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
- wait_for_requests
+ expect(page).to have_selector('.board-card', count: 30)
+ expect(page).to have_content('Showing 30 of 31 issues')
- page.within(find('.board:nth-child(2)')) do
- expect(page.find('.board-header')).to have_content('1')
- expect(page).to have_selector('.board-card', count: 1)
- end
+ 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
- page.within(find('.board:nth-child(3)')) do
- expect(page.find('.board-header')).to have_content('0')
- expect(page).to have_selector('.board-card', count: 0)
+ expect(page).to have_selector('.board-card', count: 31)
+ expect(page).to have_content('Showing all issues')
+ end
end
- end
- it 'removes filtered labels' do
- inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
+ it 'filters by multiple labels', :quarantine do
set_filter("label", testing.title)
click_filter_link(testing.title)
- submit_filter
- wait_for_board_cards(2, 1)
+ set_filter("label", bug.title)
+ click_filter_link(bug.title)
- find('.clear-search').click
submit_filter
- end
- wait_for_board_cards(2, 8)
- end
-
- it 'infinite scrolls list with label filter' do
- create_list(:labeled_issue, 30, project: project, labels: [planning, testing])
+ wait_for_requests
- set_filter("label", testing.title)
- click_filter_link(testing.title)
- inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
- submit_filter
+ wait_for_board_cards(2, 1)
+ wait_for_empty_boards((3..4))
end
- wait_for_requests
-
- page.within(find('.board:nth-child(2)')) do
- 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 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")
+ it 'filters by clicking label button on issue' do
+ page.within(find('.board:nth-child(2)')) do
+ expect(page).to have_selector('.board-card', count: 8)
+ expect(find('.board-card', match: :first)).to have_content(bug.title)
+ click_link(bug.title)
+ wait_for_requests
end
- 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")
+ page.within('.tokens-container') do
+ expect(page).to have_content(bug.title)
end
- expect(page).to have_selector('.board-card', count: 31)
- expect(page).to have_content('Showing all issues')
- end
- end
-
- it 'filters by multiple labels', :quarantine do
- set_filter("label", testing.title)
- click_filter_link(testing.title)
-
- set_filter("label", bug.title)
- click_filter_link(bug.title)
-
- submit_filter
-
- wait_for_requests
-
- wait_for_board_cards(2, 1)
- wait_for_empty_boards((3..4))
- end
-
- it 'filters by clicking label button on issue' do
- page.within(find('.board:nth-child(2)')) do
- expect(page).to have_selector('.board-card', count: 8)
- expect(find('.board-card', match: :first)).to have_content(bug.title)
- click_link(bug.title)
wait_for_requests
- end
- page.within('.tokens-container') do
- expect(page).to have_content(bug.title)
+ wait_for_board_cards(2, 1)
+ wait_for_empty_boards((3..4))
end
- wait_for_requests
+ it 'removes label filter by clicking label button on issue' do
+ page.within(find('.board:nth-child(2)')) do
+ page.within(find('.board-card', match: :first)) do
+ click_link(bug.title)
+ end
- wait_for_board_cards(2, 1)
- wait_for_empty_boards((3..4))
- end
+ wait_for_requests
- it 'removes label filter by clicking label button on issue' do
- page.within(find('.board:nth-child(2)')) do
- page.within(find('.board-card', match: :first)) do
- click_link(bug.title)
+ expect(page).to have_selector('.board-card', count: 1)
end
wait_for_requests
-
- expect(page).to have_selector('.board-card', count: 1)
end
-
- wait_for_requests
end
end
- end
- context 'issue board focus mode' do
- before do
- visit project_board_path(project, board)
- wait_for_requests
- end
+ context 'issue board focus mode' do
+ before do
+ visit project_board_path(project, board)
+ wait_for_requests
+ end
- it 'shows the button' do
- expect(page).to have_button('Toggle focus mode')
+ it 'shows the button' do
+ expect(page).to have_button('Toggle focus mode')
+ end
end
- end
- context 'keyboard shortcuts' do
- before do
- visit_project_board_path_without_query_limit(project, board)
- wait_for_requests
- end
+ context 'keyboard shortcuts' do
+ before do
+ visit_project_board_path_without_query_limit(project, board)
+ wait_for_requests
+ end
- it 'allows user to use keyboard shortcuts' do
- find('body').native.send_keys('i')
- expect(page).to have_content('New Issue')
+ it 'allows user to use keyboard shortcuts' do
+ find('body').native.send_keys('i')
+ expect(page).to have_content('New Issue')
+ end
end
end
context 'signed out user' do
before do
- sign_out(:user)
visit project_board_path(project, board)
wait_for_requests
end
@@ -599,7 +524,7 @@ RSpec.describe 'Project issue boards', :js do
end
it 'does not show create new list' do
- expect(page).not_to have_button('.js-new-board-list')
+ expect(page).not_to have_button('Create list')
end
it 'does not allow dragging' do
@@ -612,34 +537,16 @@ RSpec.describe 'Project issue boards', :js do
before do
project.add_guest(user_guest)
- sign_out(:user)
sign_in(user_guest)
visit project_board_path(project, board)
wait_for_requests
end
it 'does not show create new list' do
- expect(page).not_to have_selector('.js-new-board-list')
+ expect(page).not_to have_button('Create list')
end
end
- def drag(selector: '.board-list', list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0, perform_drop: true)
- # ensure there is enough horizontal space for four boards
- inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
- resize_window(2000, 800)
-
- drag_to(selector: selector,
- scrollable: '#board-app',
- list_from_index: list_from_index,
- from_index: from_index,
- to_index: to_index,
- list_to_index: list_to_index,
- perform_drop: perform_drop)
- end
-
- wait_for_requests
- end
-
def wait_for_board_cards(board_number, expected_cards)
page.within(find(".board:nth-child(#{board_number})")) do
expect(page.find('.board-header')).to have_content(expected_cards.to_s)
@@ -682,6 +589,8 @@ RSpec.describe 'Project issue boards', :js do
def visit_project_board_path_without_query_limit(project, board)
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
visit project_board_path(project, board)
+
+ wait_for_requests
end
end
end
diff --git a/spec/features/callouts/service_templates_deprecation_spec.rb b/spec/features/callouts/service_templates_deprecation_spec.rb
deleted file mode 100644
index b6403b54e29..00000000000
--- a/spec/features/callouts/service_templates_deprecation_spec.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'Service templates deprecation callout' do
- let_it_be(:admin) { create(:admin) }
- let_it_be(:non_admin) { create(:user) }
- let_it_be(:callout_content) { 'Service templates are deprecated and will be removed in GitLab 14.0.' }
-
- context 'when a non-admin is logged in' do
- before do
- sign_in(non_admin)
- visit root_dashboard_path
- end
-
- it 'does not display callout' do
- expect(page).not_to have_content callout_content
- end
- end
-
- context 'when an admin is logged in' do
- before do
- sign_in(admin)
- gitlab_enable_admin_mode_sign_in(admin)
-
- visit root_dashboard_path
- end
-
- context 'with no active service templates' do
- it 'does not display callout' do
- expect(page).not_to have_content callout_content
- end
- end
-
- context 'with active service template' do
- before do
- create(:service, :template, type: 'MattermostService', active: true)
- visit root_dashboard_path
- end
-
- it 'displays callout' do
- expect(page).to have_content callout_content
- expect(page).to have_link 'See affected service templates', href: admin_application_settings_services_path
- end
-
- context 'when callout is dismissed', :js do
- before do
- find('[data-testid="close-service-templates-deprecated-callout"]').click
-
- visit root_dashboard_path
- end
-
- it 'does not display callout' do
- expect(page).not_to have_content callout_content
- end
- end
- end
- end
-end
diff --git a/spec/features/clusters/cluster_health_dashboard_spec.rb b/spec/features/clusters/cluster_health_dashboard_spec.rb
index 20c07f4d6ac..e4a36f654e5 100644
--- a/spec/features/clusters/cluster_health_dashboard_spec.rb
+++ b/spec/features/clusters/cluster_health_dashboard_spec.rb
@@ -63,21 +63,33 @@ RSpec.describe 'Cluster Health board', :js, :kubeclient, :use_clean_rails_memory
context 'connected, prometheus returns data' do
before do
stub_connected
- end
- it 'renders charts' do
visit cluster_path
click_link 'Health'
wait_for_requests
+ end
+ it 'renders charts' do
expect(page).to have_css('.prometheus-graphs')
expect(page).to have_css('.prometheus-graph')
expect(page).to have_css('.prometheus-graph-title')
expect(page).to have_css('[_echarts_instance_]')
+ expect(page).to have_css('.prometheus-graph', count: 2)
expect(page).to have_content('Avg')
end
+
+ it 'focuses the single panel on toggle', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338341' do
+ click_button('More actions')
+ click_button('Expand panel')
+
+ expect(page).to have_css('.prometheus-graph', count: 1)
+
+ click_button('Collapse panel')
+
+ expect(page).to have_css('.prometheus-graph', count: 2)
+ end
end
def stub_empty_response
diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb
index d0f8767884e..de6cb53fdfa 100644
--- a/spec/features/cycle_analytics_spec.rb
+++ b/spec/features/cycle_analytics_spec.rb
@@ -6,6 +6,8 @@ RSpec.describe 'Value Stream Analytics', :js do
let_it_be(:user) { create(:user) }
let_it_be(:guest) { create(:user) }
let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:stage_table_selector) { '[data-testid="vsa-stage-table"]' }
+ let_it_be(:metrics_selector) { "[data-testid='vsa-time-metrics']" }
let(:issue) { create(:issue, project: project, created_at: 2.days.ago) }
let(:milestone) { create(:milestone, project: project) }
@@ -25,11 +27,13 @@ RSpec.describe 'Value Stream Analytics', :js do
wait_for_requests
end
- it 'shows pipeline summary' do
- expect(new_issues_counter).to have_content('-')
- expect(commits_counter).to have_content('-')
- expect(deploys_counter).to have_content('-')
- expect(deployment_frequency_counter).to have_content('-')
+ it 'displays metrics' do
+ aggregate_failures 'with relevant values' do
+ expect(new_issues_counter).to have_content('-')
+ expect(commits_counter).to have_content('-')
+ expect(deploys_counter).to have_content('-')
+ expect(deployment_frequency_counter).to have_content('-')
+ end
end
it 'shows active stage with empty message' do
@@ -45,9 +49,9 @@ RSpec.describe 'Value Stream Analytics', :js do
@build = create_cycle(user, project, issue, mr, milestone, pipeline)
deploy_master(user, project)
- issue.metrics.update!(first_mentioned_in_commit_at: issue.metrics.first_associated_with_milestone_at + 1.day)
+ issue.metrics.update!(first_mentioned_in_commit_at: issue.metrics.first_associated_with_milestone_at + 1.hour)
merge_request = issue.merge_requests_closing_issues.first.merge_request
- merge_request.update!(created_at: issue.metrics.first_associated_with_milestone_at + 1.day)
+ merge_request.update!(created_at: issue.metrics.first_associated_with_milestone_at + 1.hour)
merge_request.metrics.update!(
latest_build_started_at: 4.hours.ago,
latest_build_finished_at: 3.hours.ago,
@@ -59,11 +63,15 @@ RSpec.describe 'Value Stream Analytics', :js do
visit project_cycle_analytics_path(project)
end
- it 'shows pipeline summary' do
- expect(new_issues_counter).to have_content('1')
- expect(commits_counter).to have_content('2')
- expect(deploys_counter).to have_content('1')
- expect(deployment_frequency_counter).to have_content('0')
+ it 'displays metrics' do
+ metrics_tiles = page.find(metrics_selector)
+
+ aggregate_failures 'with relevant values' do
+ expect(metrics_tiles).to have_content('Commit')
+ expect(metrics_tiles).to have_content('Deploy')
+ expect(metrics_tiles).to have_content('Deployment Frequency')
+ expect(metrics_tiles).to have_content('New Issue')
+ end
end
it 'shows data on each stage', :sidekiq_might_not_need_inline do
@@ -76,13 +84,13 @@ RSpec.describe 'Value Stream Analytics', :js do
expect_merge_request_to_be_present
click_stage('Test')
- expect_build_to_be_present
+ expect_merge_request_to_be_present
click_stage('Review')
expect_merge_request_to_be_present
click_stage('Staging')
- expect_build_to_be_present
+ expect_merge_request_to_be_present
end
context "when I change the time period observed" do
@@ -95,7 +103,7 @@ RSpec.describe 'Value Stream Analytics', :js do
end
it 'shows only relevant data' do
- expect(new_issues_counter).to have_content('1')
+ expect(new_issue_counter).to have_content('1')
end
end
end
@@ -115,60 +123,55 @@ RSpec.describe 'Value Stream Analytics', :js do
end
it 'does not show the commit stats' do
- expect(page).to have_no_selector(:xpath, commits_counter_selector)
+ expect(page.find(metrics_selector)).not_to have_selector("#commits")
end
it 'needs permissions to see restricted stages' do
- expect(find('.stage-events')).to have_content(issue.title)
+ expect(find(stage_table_selector)).to have_content(issue.title)
click_stage('Code')
- expect(find('.stage-events')).to have_content('You need permission.')
+ expect(find(stage_table_selector)).to have_content('You need permission.')
click_stage('Review')
- expect(find('.stage-events')).to have_content('You need permission.')
+ expect(find(stage_table_selector)).to have_content('You need permission.')
end
end
- def new_issues_counter
- find(:xpath, "//p[contains(text(),'New Issue')]/preceding-sibling::h3")
+ def find_metric_tile(sel)
+ page.find("#{metrics_selector} #{sel}")
end
- def commits_counter_selector
- "//p[contains(text(),'Commits')]/preceding-sibling::h3"
+ # When now use proper pluralization for the metric names, which affects the id
+ def new_issue_counter
+ find_metric_tile("#new-issue")
end
- def commits_counter
- find(:xpath, commits_counter_selector)
+ def new_issues_counter
+ find_metric_tile("#new-issues")
end
- def deploys_counter
- find(:xpath, "//p[contains(text(),'Deploy')]/preceding-sibling::h3", match: :first)
+ def commits_counter
+ find_metric_tile("#commits")
end
- def deployment_frequency_counter_selector
- "//p[contains(text(),'Deployment Frequency')]/preceding-sibling::h3"
+ def deploys_counter
+ find_metric_tile("#deploys")
end
def deployment_frequency_counter
- find(:xpath, deployment_frequency_counter_selector)
+ find_metric_tile("#deployment-frequency")
end
def expect_issue_to_be_present
- expect(find('.stage-events')).to have_content(issue.title)
- expect(find('.stage-events')).to have_content(issue.author.name)
- expect(find('.stage-events')).to have_content("##{issue.iid}")
- end
-
- def expect_build_to_be_present
- expect(find('.stage-events')).to have_content(@build.ref)
- expect(find('.stage-events')).to have_content(@build.short_sha)
- expect(find('.stage-events')).to have_content("##{@build.id}")
+ expect(find(stage_table_selector)).to have_content(issue.title)
+ expect(find(stage_table_selector)).to have_content(issue.author.name)
+ expect(find(stage_table_selector)).to have_content("##{issue.iid}")
end
def expect_merge_request_to_be_present
- expect(find('.stage-events')).to have_content(mr.title)
- expect(find('.stage-events')).to have_content(mr.author.name)
- expect(find('.stage-events')).to have_content("!#{mr.iid}")
+ expect(find(stage_table_selector)).to have_content(mr.title)
+ expect(find(stage_table_selector)).to have_content(mr.author.name)
+ expect(find(stage_table_selector)).to have_content("!#{mr.iid}")
end
def click_stage(stage_name)
diff --git a/spec/features/dashboard/active_tab_spec.rb b/spec/features/dashboard/active_tab_spec.rb
deleted file mode 100644
index aa767d75c00..00000000000
--- a/spec/features/dashboard/active_tab_spec.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# frozen_string_literal: true
-
-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
- sign_in(create(:user))
- end
-
- shared_examples 'page has active tab' do |title|
- it "#{title} tab" do
- subject
-
- expect(page).to have_selector('.navbar-sub-nav li.active', count: 1)
- expect(find('.navbar-sub-nav li.active')).to have_content(title)
- end
- end
-
- context 'on dashboard projects' do
- it_behaves_like 'page has active tab', 'Projects' do
- subject { visit dashboard_projects_path }
- end
- end
-
- context 'on dashboard groups' do
- it_behaves_like 'page has active tab', 'Groups' do
- subject { visit dashboard_groups_path }
- end
- end
- end
-
- context 'with combined_menu feature flag off' do
- before do
- stub_feature_flags(combined_menu: false)
- end
-
- it_behaves_like 'combined_menu: feature flag examples'
- 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 3dd993b4bb5..6861fac3cc2 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
@@ -2,66 +2,44 @@
require 'spec_helper'
-RSpec.describe 'The group dashboard' do
+RSpec.describe 'The group dashboard', :js do
include ExternalAuthorizationServiceHelpers
include Spec::Support::Helpers::Features::TopNavSpecHelpers
let(:user) { create(:user) }
- shared_examples 'combined_menu: feature flag examples' do
- before do
- sign_in user
- end
-
- describe 'The top navigation' do
- it 'has all the expected links' do
- visit dashboard_groups_path
-
- 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')
- expect(page).to have_link('Milestones')
- expect(page).to have_link('Snippets')
- end
- end
+ before do
+ sign_in user
+ end
- it 'hides some links when an external authorization service is enabled' do
- enable_external_authorization_service_check
- visit dashboard_groups_path
+ describe 'The top navigation' do
+ it 'has all the expected links' do
+ visit dashboard_groups_path
- open_top_nav
+ 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')
- expect(page).not_to have_link('Milestones')
- expect(page).to have_link('Snippets')
- end
+ within_top_nav do
+ expect(page).to have_button('Projects')
+ expect(page).to have_button('Groups')
+ expect(page).to have_link('Activity')
+ expect(page).to have_link('Milestones')
+ expect(page).to have_link('Snippets')
end
end
- end
- context 'with combined_menu feature flag on', :js do
- let(:needs_rewrite_for_combined_menu_flag_on) { true }
+ it 'hides some links when an external authorization service is enabled' do
+ enable_external_authorization_service_check
+ visit dashboard_groups_path
- before do
- stub_feature_flags(combined_menu: true)
- end
-
- it_behaves_like 'combined_menu: feature flag examples'
- end
+ open_top_nav
- 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)
+ within_top_nav do
+ expect(page).to have_button('Projects')
+ expect(page).to have_button('Groups')
+ expect(page).not_to have_link('Activity')
+ expect(page).not_to have_link('Milestones')
+ expect(page).to have_link('Snippets')
+ end
end
-
- it_behaves_like 'combined_menu: feature flag examples'
end
end
diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb
index 1f0981de7e1..27419479479 100644
--- a/spec/features/dashboard/projects_spec.rb
+++ b/spec/features/dashboard/projects_spec.rb
@@ -194,6 +194,29 @@ RSpec.describe 'Dashboard Projects' do
end
end
+ describe 'with topics' do
+ context 'when project has topics' do
+ before do
+ project.update_attribute(:topic_list, 'topic1')
+ end
+
+ it 'shows project topics if exist' do
+ visit dashboard_projects_path
+
+ expect(page).to have_selector('[data-testid="project_topic_list"]')
+ expect(page).to have_link('topic1', href: explore_projects_path(topic: 'topic1'))
+ end
+ end
+
+ context 'when project does not have topics' do
+ it 'does not show project topics' do
+ visit dashboard_projects_path
+
+ expect(page).not_to have_selector('[data-testid="project_topic_list"]')
+ end
+ end
+ end
+
context 'last push widget', :use_clean_rails_memory_store_caching do
before do
event = create(:push_event, project: project, author: user)
diff --git a/spec/features/dashboard/shortcuts_spec.rb b/spec/features/dashboard/shortcuts_spec.rb
index 7439bfd334b..3f3ab4218f2 100644
--- a/spec/features/dashboard/shortcuts_spec.rb
+++ b/spec/features/dashboard/shortcuts_spec.rb
@@ -3,89 +3,71 @@
require 'spec_helper'
RSpec.describe 'Dashboard shortcuts', :js do
- shared_examples 'combined_menu: feature flag examples' do
- context 'logged in' do
- let(:user) { create(:user) }
- let(:project) { create(:project) }
+ context 'logged in' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
- before do
- project.add_developer(user)
- sign_in(user)
- visit root_dashboard_path
- end
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ visit root_dashboard_path
+ end
- it 'navigate to tabs' do
- find('body').send_keys([:shift, 'I'])
+ it 'navigate to tabs' do
+ find('body').send_keys([:shift, 'I'])
- check_page_title('Issues')
+ check_page_title('Issues')
- find('body').send_keys([:shift, 'M'])
+ find('body').send_keys([:shift, 'M'])
- check_page_title('Merge requests')
+ check_page_title('Merge requests')
- find('body').send_keys([:shift, 'T'])
+ find('body').send_keys([:shift, 'T'])
- check_page_title('To-Do List')
+ check_page_title('To-Do List')
- find('body').send_keys([:shift, 'G'])
+ find('body').send_keys([:shift, 'G'])
- check_page_title('Groups')
+ check_page_title('Groups')
- find('body').send_keys([:shift, 'P'])
+ find('body').send_keys([:shift, 'P'])
- check_page_title('Projects')
+ check_page_title('Projects')
- find('body').send_keys([:shift, 'A'])
+ find('body').send_keys([:shift, 'A'])
- check_page_title('Activity')
+ check_page_title('Activity')
- find('body').send_keys([:shift, 'L'])
+ find('body').send_keys([:shift, 'L'])
- check_page_title('Milestones')
- end
+ check_page_title('Milestones')
end
+ end
- context 'logged out' do
- before do
- visit explore_root_path
- end
-
- it 'navigate to tabs' do
- find('body').send_keys([:shift, 'G'])
+ context 'logged out' do
+ before do
+ visit explore_root_path
+ end
- find('.nothing-here-block')
- expect(page).to have_content('No public groups')
+ it 'navigate to tabs' do
+ find('body').send_keys([:shift, 'G'])
- find('body').send_keys([:shift, 'S'])
+ find('.nothing-here-block')
+ expect(page).to have_content('No public groups')
- find('.nothing-here-block')
- expect(page).to have_content('No snippets found')
+ find('body').send_keys([:shift, 'S'])
- find('body').send_keys([:shift, 'P'])
+ find('.nothing-here-block')
+ expect(page).to have_content('No snippets found')
- find('.nothing-here-block')
- expect(page).to have_content('Explore public groups to find projects to contribute to.')
- end
- end
+ find('body').send_keys([:shift, 'P'])
- def check_page_title(title)
- expect(find('.page-title')).to have_content(title)
+ find('.nothing-here-block')
+ expect(page).to have_content('Explore public groups to find projects to contribute to.')
end
end
- context 'with combined_menu feature flag on' do
- 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
- before do
- stub_feature_flags(combined_menu: false)
- end
-
- it_behaves_like 'combined_menu: feature flag examples'
+ def check_page_title(title)
+ expect(find('.page-title')).to have_content(title)
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 5ea42ce39e3..6bc3b745851 100644
--- a/spec/features/frequently_visited_projects_and_groups_spec.rb
+++ b/spec/features/frequently_visited_projects_and_groups_spec.rb
@@ -7,67 +7,45 @@ RSpec.describe 'Frequently visited items', :js do
let_it_be(:user) { create(:user) }
- shared_examples 'combined_menu: feature flag examples' do
- before do
- sign_in(user)
- end
-
- context 'for projects' do
- let_it_be(:project) { create(:project, :public) }
+ before do
+ sign_in(user)
+ end
- it 'increments localStorage counter when visiting the project' do
- visit project_path(project)
- open_top_nav_projects
+ context 'for projects' do
+ let_it_be(:project) { create(:project, :public) }
- frequent_projects = nil
+ it 'increments localStorage counter when visiting the project' do
+ visit project_path(project)
+ open_top_nav_projects
- wait_for('localStorage frequent-projects') do
- frequent_projects = page.evaluate_script("localStorage['#{user.username}/frequent-projects']")
+ frequent_projects = nil
- frequent_projects.present?
- end
+ wait_for('localStorage frequent-projects') do
+ frequent_projects = page.evaluate_script("localStorage['#{user.username}/frequent-projects']")
- expect(Gitlab::Json.parse(frequent_projects)).to contain_exactly(a_hash_including('id' => project.id, 'frequency' => 1))
+ frequent_projects.present?
end
- end
-
- context 'for groups' do
- let_it_be(:group) { create(:group, :public) }
-
- it 'increments localStorage counter when visiting the group' do
- visit group_path(group)
- open_top_nav_groups
-
- frequent_groups = nil
-
- wait_for('localStorage frequent-groups') do
- frequent_groups = page.evaluate_script("localStorage['#{user.username}/frequent-groups']")
- frequent_groups.present?
- end
-
- expect(Gitlab::Json.parse(frequent_groups)).to contain_exactly(a_hash_including('id' => group.id, 'frequency' => 1))
- end
+ expect(Gitlab::Json.parse(frequent_projects)).to contain_exactly(a_hash_including('id' => project.id, 'frequency' => 1))
end
end
- context 'with combined_menu feature flag on' do
- let(:needs_rewrite_for_combined_menu_flag_on) { true }
+ context 'for groups' do
+ let_it_be(:group) { create(:group, :public) }
- before do
- stub_feature_flags(combined_menu: true)
- end
+ it 'increments localStorage counter when visiting the group' do
+ visit group_path(group)
+ open_top_nav_groups
- it_behaves_like 'combined_menu: feature flag examples'
- end
+ frequent_groups = nil
- context 'with combined_menu feature flag off' do
- let(:needs_rewrite_for_combined_menu_flag_on) { false }
+ wait_for('localStorage frequent-groups') do
+ frequent_groups = page.evaluate_script("localStorage['#{user.username}/frequent-groups']")
- before do
- stub_feature_flags(combined_menu: false)
- end
+ frequent_groups.present?
+ end
- it_behaves_like 'combined_menu: feature flag examples'
+ expect(Gitlab::Json.parse(frequent_groups)).to contain_exactly(a_hash_including('id' => group.id, 'frequency' => 1))
+ end
end
end
diff --git a/spec/features/groups/board_sidebar_spec.rb b/spec/features/groups/board_sidebar_spec.rb
index 690d661ba2f..e2dd2fecab7 100644
--- a/spec/features/groups/board_sidebar_spec.rb
+++ b/spec/features/groups/board_sidebar_spec.rb
@@ -19,8 +19,6 @@ RSpec.describe 'Group Issue Boards', :js do
let(:card) { find('.board:nth-child(1)').first('.board-card') }
before do
- # stubbing until sidebar work is done: https://gitlab.com/gitlab-org/gitlab/-/issues/230711
- stub_feature_flags(graphql_board_lists: false)
sign_in(user)
visit group_board_path(group, board)
@@ -32,6 +30,32 @@ RSpec.describe 'Group Issue Boards', :js do
click_card(card)
page.within('.labels') do
+ click_button 'Edit'
+
+ wait_for_requests
+
+ page.within('[data-testid="dropdown-content"]') do
+ expect(page).to have_content(project_1_label.title)
+ expect(page).to have_content(group_label.title)
+ expect(page).not_to have_content(project_2_label.title)
+ end
+ end
+ end
+ end
+
+ context 'when graphql_board_lists FF disabled' do
+ before do
+ stub_feature_flags(graphql_board_lists: false)
+ sign_in(user)
+
+ visit group_board_path(group, board)
+ wait_for_requests
+ end
+
+ it 'only shows valid labels for the issue project and group' do
+ click_card(card)
+
+ page.within('.labels') do
click_link 'Edit'
wait_for_requests
diff --git a/spec/features/groups/board_spec.rb b/spec/features/groups/board_spec.rb
index b4c60ff4fa3..afe36dabcb5 100644
--- a/spec/features/groups/board_spec.rb
+++ b/spec/features/groups/board_spec.rb
@@ -3,16 +3,21 @@
require 'spec_helper'
RSpec.describe 'Group Boards' do
- let(:group) { create(:group) }
- let!(:project) { create(:project_empty_repo, group: group) }
- let(:user) { create(:group_member, :maintainer, user: create(:user), group: group ).user }
+ include DragTo
+ include MobileHelpers
+ include BoardHelpers
- before do
- sign_in(user)
- end
+ let_it_be(:group) { create(:group) }
+ let_it_be(:user) { create(:user) }
+
+ context 'Creates an issue', :js do
+ let_it_be(:project) { create(:project_empty_repo, group: group) }
- context 'Creates a an issue', :js do
before do
+ group.add_maintainer(user)
+
+ sign_in(user)
+
visit group_boards_path(group)
end
@@ -39,4 +44,58 @@ RSpec.describe 'Group Boards' do
end
end
end
+
+ context "when user is a Reporter in one of the group's projects", :js do
+ let_it_be(:board) { create(:board, group: group) }
+
+ let_it_be(:backlog_list) { create(:backlog_list, board: board) }
+ let_it_be(:group_label1) { create(:group_label, title: "bug", group: group) }
+ let_it_be(:group_label2) { create(:group_label, title: "dev", group: group) }
+ let_it_be(:list1) { create(:list, board: board, label: group_label1, position: 0) }
+ let_it_be(:list2) { create(:list, board: board, label: group_label2, position: 1) }
+
+ let_it_be(:project1) { create(:project_empty_repo, :private, group: group) }
+ let_it_be(:project2) { create(:project_empty_repo, :private, group: group) }
+ let_it_be(:issue1) { create(:issue, title: 'issue1', project: project1, labels: [group_label2]) }
+ let_it_be(:issue2) { create(:issue, title: 'issue2', project: project2) }
+
+ before do
+ project1.add_guest(user)
+ project2.add_reporter(user)
+
+ sign_in(user)
+
+ inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
+ visit group_boards_path(group)
+ end
+ end
+
+ it 'allows user to move issue of project where they are a Reporter' do
+ expect(find('.board:nth-child(1)')).to have_content(issue2.title)
+
+ drag(list_from_index: 0, from_index: 0, list_to_index: 1)
+
+ expect(find('.board:nth-child(2)')).to have_content(issue2.title)
+ expect(issue2.reload.labels).to contain_exactly(group_label1)
+ end
+
+ it 'does not allow user to move issue of project where they are a Guest' do
+ expect(find('.board:nth-child(3)')).to have_content(issue1.title)
+
+ drag(list_from_index: 2, from_index: 0, list_to_index: 1)
+
+ expect(find('.board:nth-child(3)')).to have_content(issue1.title)
+ expect(issue1.reload.labels).to contain_exactly(group_label2)
+ expect(issue2.reload.labels).to eq([])
+ end
+
+ it 'does not allow user to re-position lists' do
+ drag(list_from_index: 1, list_to_index: 2, selector: '.board-header')
+
+ expect(find('.board:nth-child(2) [data-testid="board-list-header"]')).to have_content(group_label1.title)
+ expect(find('.board:nth-child(3) [data-testid="board-list-header"]')).to have_content(group_label2.title)
+ expect(list1.reload.position).to eq(0)
+ expect(list2.reload.position).to eq(1)
+ end
+ end
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
index 7703268af39..02aa418cd73 100644
--- a/spec/features/groups/integrations/user_activates_mattermost_slash_command_spec.rb
+++ b/spec/features/groups/integrations/user_activates_mattermost_slash_command_spec.rb
@@ -13,4 +13,9 @@ RSpec.describe 'User activates the group-level Mattermost Slash Command integrat
let(:edit_path) { edit_group_settings_integration_path(group, :mattermost_slash_commands) }
include_examples 'user activates the Mattermost Slash Command integration'
+
+ it 'does not display the overrides tab' do
+ expect(page).not_to have_link('Settings', href: edit_path)
+ expect(page).not_to have_link('Projects using custom settings', href: overrides_admin_application_settings_integration_path(:mattermost_slash_commands))
+ end
end
diff --git a/spec/features/groups/members/manage_members_spec.rb b/spec/features/groups/members/manage_members_spec.rb
index 1d57d0a9103..38e829bafcc 100644
--- a/spec/features/groups/members/manage_members_spec.rb
+++ b/spec/features/groups/members/manage_members_spec.rb
@@ -84,6 +84,33 @@ RSpec.describe 'Groups > Members > Manage members' do
property: 'existing_user',
user: user1
)
+ expect_no_snowplow_event(
+ category: 'Members::CreateService',
+ action: 'area_of_focus'
+ )
+ end
+
+ it 'adds a user to group with area_of_focus', :js, :snowplow, :aggregate_failures do
+ stub_experiments(member_areas_of_focus: :candidate)
+ group.add_owner(user1)
+
+ visit group_group_members_path(group)
+
+ invite_member(user2.name, role: 'Reporter', area_of_focus: true)
+ wait_for_requests
+
+ expect_snowplow_event(
+ category: 'Members::CreateService',
+ action: 'area_of_focus',
+ label: 'Contribute to the codebase',
+ property: group.members.last.id.to_s
+ )
+ expect_snowplow_event(
+ category: 'Members::CreateService',
+ action: 'area_of_focus',
+ label: 'Collaborate on open issues and merge requests',
+ property: group.members.last.id.to_s
+ )
end
it 'do not disclose email addresses', :js do
@@ -193,9 +220,36 @@ RSpec.describe 'Groups > Members > Manage members' do
property: 'net_new_user',
user: user1
)
+ expect_no_snowplow_event(
+ category: 'Members::CreateService',
+ action: 'area_of_focus'
+ )
end
end
+ it 'invite user to group with area_of_focus', :js, :snowplow, :aggregate_failures do
+ stub_experiments(member_areas_of_focus: :candidate)
+ group.add_owner(user1)
+
+ visit group_group_members_path(group)
+
+ invite_member('test@example.com', role: 'Reporter', area_of_focus: true)
+ wait_for_requests
+
+ expect_snowplow_event(
+ category: 'Members::InviteService',
+ action: 'area_of_focus',
+ label: 'Contribute to the codebase',
+ property: group.members.last.id.to_s
+ )
+ expect_snowplow_event(
+ category: 'Members::InviteService',
+ action: 'area_of_focus',
+ label: 'Collaborate on open issues and merge requests',
+ property: group.members.last.id.to_s
+ )
+ end
+
context 'when user is a guest' do
before do
group.add_guest(user1)
diff --git a/spec/features/groups/packages_spec.rb b/spec/features/groups/packages_spec.rb
index 752303fdd78..9a7950266a5 100644
--- a/spec/features/groups/packages_spec.rb
+++ b/spec/features/groups/packages_spec.rb
@@ -52,6 +52,8 @@ RSpec.describe 'Group Packages' do
it_behaves_like 'package details link'
end
+ it_behaves_like 'package details link'
+
it 'allows you to navigate to the project page' do
find('[data-testid="root-link"]', text: project.name).click
diff --git a/spec/features/groups/settings/manage_applications_spec.rb b/spec/features/groups/settings/manage_applications_spec.rb
new file mode 100644
index 00000000000..5f84f61678d
--- /dev/null
+++ b/spec/features/groups/settings/manage_applications_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User manages applications' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:new_application_path) { group_settings_applications_path(group) }
+
+ before do
+ group.add_owner(user)
+ sign_in(user)
+ end
+
+ include_examples 'manage applications'
+end
diff --git a/spec/features/groups/settings/packages_and_registries_spec.rb b/spec/features/groups/settings/packages_and_registries_spec.rb
index 551a0bc5375..835555480dd 100644
--- a/spec/features/groups/settings/packages_and_registries_spec.rb
+++ b/spec/features/groups/settings/packages_and_registries_spec.rb
@@ -113,7 +113,7 @@ RSpec.describe 'Group Packages & Registries settings' do
end
def find_settings_menu
- find('ul[data-testid="group-settings-menu"]')
+ find('.shortcuts-settings ul')
end
def visit_settings_page
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 c258dd41b03..abf56232aff 100644
--- a/spec/features/groups/settings/user_searches_in_settings_spec.rb
+++ b/spec/features/groups/settings/user_searches_in_settings_spec.rb
@@ -40,7 +40,7 @@ RSpec.describe 'User searches group settings', :js do
visit group_settings_ci_cd_path(group)
end
- it_behaves_like 'can search settings', 'Variables', 'Runners'
+ it_behaves_like 'can search settings', 'Variables', 'Auto DevOps'
end
context 'in Packages & Registries page' do
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index efde570512f..9c11b84fa8f 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -52,7 +52,7 @@ RSpec.describe 'Group' do
click_button 'Create group'
expect(current_path).to eq(new_group_path)
- expect(page).to have_text('Please choose a group URL with no special characters.')
+ expect(page).to have_text('Please choose a group URL with no special characters or spaces.')
end
end
diff --git a/spec/features/invites_spec.rb b/spec/features/invites_spec.rb
index b7e1004aef5..d56bedd4852 100644
--- a/spec/features/invites_spec.rb
+++ b/spec/features/invites_spec.rb
@@ -141,6 +141,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
let(:invite_email) { new_user.email }
let(:group_invite) { create(:group_member, :invited, group: group, invite_email: invite_email, created_by: owner) }
let(:send_email_confirmation) { true }
+ let(:extra_params) { { invite_type: Emails::Members::INITIAL_INVITE } }
before do
stub_application_setting(send_user_confirmation_email: send_email_confirmation)
@@ -148,7 +149,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
context 'when registering using invitation email' do
before do
- visit invite_path(group_invite.raw_invite_token, invite_type: Members::InviteEmailExperiment::INVITE_TYPE)
+ visit invite_path(group_invite.raw_invite_token, extra_params)
end
context 'with admin approval required enabled' do
@@ -188,11 +189,28 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
context 'email confirmation enabled' do
- context 'with members/invite_email experiment', :experiment do
+ context 'with invite email acceptance', :snowplow do
it 'tracks the accepted invite' do
- expect(experiment('members/invite_email')).to track(:accepted)
- .with_context(actor: group_invite)
- .on_next_instance
+ fill_in_sign_up_form(new_user)
+
+ expect_snowplow_event(
+ category: 'RegistrationsController',
+ action: 'accepted',
+ label: 'invite_email',
+ property: group_invite.id.to_s
+ )
+ end
+ end
+
+ context 'with invite email acceptance for the invite_email_preview_text experiment', :experiment do
+ let(:extra_params) do
+ { invite_type: Emails::Members::INITIAL_INVITE, experiment_name: 'invite_email_preview_text' }
+ end
+
+ it 'tracks the accepted invite' do
+ expect(experiment(:invite_email_preview_text)).to track(:accepted)
+ .with_context(actor: group_invite)
+ .on_next_instance
fill_in_sign_up_form(new_user)
end
diff --git a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
index a4c0a84af7d..077c363f78b 100644
--- a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
+++ b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe 'Resolving all open threads in a merge request from an issue', :j
context 'resolving the thread' do
before do
- find('button[data-qa-selector="resolve_discussion_button"]').click
+ find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
end
it 'hides the link for creating a new issue' do
diff --git a/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
index ac3471e8401..3ff8fc5ecca 100644
--- a/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
+++ b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb
@@ -35,7 +35,7 @@ RSpec.describe 'Resolve an open thread in a merge request by creating an issue',
context 'resolving the thread' do
before do
- find('button[data-qa-selector="resolve_discussion_button"]').click
+ find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
end
it 'hides the link for creating a new issue' do
diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb
index 5ca20028485..4bad67acc87 100644
--- a/spec/features/issues/form_spec.rb
+++ b/spec/features/issues/form_spec.rb
@@ -6,13 +6,13 @@ RSpec.describe 'New/edit issue', :js do
include ActionView::Helpers::JavaScriptHelper
include FormHelper
- let!(:project) { create(:project) }
- let!(:user) { create(:user)}
- let!(:user2) { create(:user)}
- let!(:milestone) { create(:milestone, project: project) }
- let!(:label) { create(:label, project: project) }
- let!(:label2) { create(:label, project: project) }
- let!(:issue) { create(:issue, project: project, assignees: [user], milestone: milestone) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user)}
+ let_it_be(:user2) { create(:user)}
+ let_it_be(:milestone) { create(:milestone, project: project) }
+ let_it_be(:label) { create(:label, project: project) }
+ let_it_be(:label2) { create(:label, project: project) }
+ let_it_be(:issue) { create(:issue, project: project, assignees: [user], milestone: milestone) }
before do
stub_licensed_features(multiple_issue_assignees: false, issue_weights: false)
@@ -234,6 +234,28 @@ RSpec.describe 'New/edit issue', :js do
expect(page).to have_selector('.atwho-view')
end
+ describe 'displays issue type options in the dropdown' do
+ before do
+ page.within('.issue-form') do
+ click_button 'Issue'
+ end
+ end
+
+ it 'correctly displays the Issue type option with an icon', :aggregate_failures do
+ page.within('[data-testid="issue-type-select-dropdown"]') do
+ expect(page).to have_selector('[data-testid="issue-type-issue-icon"]')
+ expect(page).to have_content('Issue')
+ end
+ end
+
+ it 'correctly displays the Incident type option with an icon', :aggregate_failures do
+ page.within('[data-testid="issue-type-select-dropdown"]') do
+ expect(page).to have_selector('[data-testid="issue-type-incident-icon"]')
+ expect(page).to have_content('Incident')
+ end
+ end
+ end
+
describe 'milestone' do
let!(:milestone) { create(:milestone, title: '">&lt;img src=x onerror=alert(document.domain)&gt;', project: project) }
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index 0e2ef5cc6eb..e198d9d4ebb 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -408,7 +408,7 @@ RSpec.describe 'Issue Sidebar' do
context 'sidebar', :js do
it 'finds issue copy forwarding email' do
- expect(find('[data-qa-selector="copy-forward-email"]').text).to eq "Issue email: #{issue.creatable_note_email_address(user)}"
+ expect(find('[data-qa-selector="copy-forward-email"]').text).to eq "Issue email: #{issue.creatable_note_email_address(user)}" # rubocop:disable QA/SelectorUsage
end
end
@@ -444,7 +444,7 @@ RSpec.describe 'Issue Sidebar' do
end
it 'does not find issue email' do
- expect(page).not_to have_selector('[data-qa-selector="copy-forward-email"]')
+ expect(page).not_to have_selector('[data-qa-selector="copy-forward-email"]') # rubocop:disable QA/SelectorUsage
end
end
end
diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb
index 4a77e850d51..f46aa5c21b6 100644
--- a/spec/features/issues/user_creates_issue_spec.rb
+++ b/spec/features/issues/user_creates_issue_spec.rb
@@ -182,7 +182,7 @@ RSpec.describe "User creates issue" do
end
it 'does not hide the milestone select' do
- expect(page).to have_selector('.qa-issuable-milestone-dropdown')
+ expect(page).to have_selector('.qa-issuable-milestone-dropdown') # rubocop:disable QA/SelectorUsage
end
end
@@ -202,11 +202,11 @@ RSpec.describe "User creates issue" do
end
it 'shows the milestone select' do
- expect(page).to have_selector('.qa-issuable-milestone-dropdown')
+ expect(page).to have_selector('.qa-issuable-milestone-dropdown') # rubocop:disable QA/SelectorUsage
end
it 'hides the weight input' do
- expect(page).not_to have_selector('.qa-issuable-weight-input')
+ expect(page).not_to have_selector('.qa-issuable-weight-input') # rubocop:disable QA/SelectorUsage
end
it 'shows the incident help text' do
diff --git a/spec/features/jira_connect/branches_spec.rb b/spec/features/jira_connect/branches_spec.rb
new file mode 100644
index 00000000000..6fa600c6906
--- /dev/null
+++ b/spec/features/jira_connect/branches_spec.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Create GitLab branches from Jira', :js do
+ let_it_be(:alice) { create(:user, name: 'Alice') }
+ let_it_be(:bob) { create(:user, name: 'Bob') }
+
+ let_it_be(:project1) { create(:project, :repository, namespace: alice.namespace, title: 'foo') }
+ let_it_be(:project2) { create(:project, :repository, namespace: alice.namespace, title: 'bar') }
+ let_it_be(:project3) { create(:project, namespace: bob.namespace) }
+
+ let(:source_branch) { 'my-source-branch' }
+ let(:new_branch) { 'my-new-branch' }
+
+ before do
+ project2.repository.add_branch(alice, source_branch, 'master')
+ sign_in(alice)
+ end
+
+ def within_dropdown(&block)
+ within('.dropdown-menu', &block)
+ end
+
+ it 'select project and branch and submit the form' do
+ visit new_jira_connect_branch_path(issue_key: 'ACME-123', issue_summary: 'My issue !@#$% title')
+
+ expect(page).to have_field('Branch name', with: 'ACME-123-my-issue-title')
+ expect(page).to have_button('Create branch', disabled: true)
+
+ # Select project1
+
+ click_on 'Select a project'
+
+ within_dropdown do
+ expect(page).to have_text('Alice / foo')
+ expect(page).to have_text('Alice / bar')
+ expect(page).not_to have_text('Bob /')
+
+ fill_in 'Search', with: 'foo'
+
+ expect(page).not_to have_text('Alice / bar')
+
+ click_on 'Alice / foo'
+ end
+
+ expect(page).to have_button('Create branch', disabled: false)
+
+ click_on 'master'
+
+ within_dropdown do
+ fill_in 'Search', with: source_branch
+
+ expect(page).not_to have_text(source_branch)
+
+ fill_in 'Search', with: 'master'
+
+ expect(page).to have_text('master')
+ end
+
+ # Switch to project2
+
+ click_on 'Alice / foo'
+
+ within_dropdown do
+ fill_in 'Search', with: ''
+ click_on 'Alice / bar'
+ end
+
+ click_on 'master'
+
+ within_dropdown do
+ fill_in 'Search', with: source_branch
+ click_on source_branch
+ end
+
+ fill_in 'Branch name', with: new_branch
+ click_on 'Create branch'
+
+ expect(page).to have_text('New branch was successfully created. You can now close this window and return to Jira.')
+
+ expect(project1.commit(new_branch)).to be_nil
+ expect(project2.commit(new_branch)).not_to be_nil
+ expect(project2.commit(new_branch)).to eq(project2.commit(source_branch))
+ end
+end
diff --git a/spec/features/labels_hierarchy_spec.rb b/spec/features/labels_hierarchy_spec.rb
index 0a2f81986be..fca5e946d0c 100644
--- a/spec/features/labels_hierarchy_spec.rb
+++ b/spec/features/labels_hierarchy_spec.rb
@@ -17,7 +17,6 @@ RSpec.describe 'Labels Hierarchy', :js do
let!(:project_label_1) { create(:label, project: project_1, title: 'Label_4') }
before do
- stub_feature_flags(graphql_board_lists: false)
stub_feature_flags(board_new_list: false)
grandparent.add_owner(user)
@@ -25,20 +24,21 @@ RSpec.describe 'Labels Hierarchy', :js do
end
shared_examples 'assigning labels from sidebar' do
- it 'can assign all ancestors labels', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/27952' do
+ it 'can assign all ancestors labels' do
[grandparent_group_label, parent_group_label, project_label_1].each do |label|
page.within('.block.labels') do
- find('.edit-link').click
+ click_on 'Edit'
end
wait_for_requests
find('a.label-item', text: label.title).click
- find('.dropdown-menu-close-icon').click
+ wait_for_requests
+ click_on 'Close'
wait_for_requests
- expect(page).to have_selector('.badge', text: label.title)
+ expect(page).to have_selector('.gl-label', text: label.title)
end
end
@@ -215,6 +215,44 @@ RSpec.describe 'Labels Hierarchy', :js do
end
end
+ context 'issuable sidebar when graphql_board_lists FF disabled' do
+ let!(:issue) { create(:issue, project: project_1) }
+
+ before do
+ stub_feature_flags(graphql_board_lists: false)
+ end
+
+ context 'on project board issue sidebar' do
+ before do
+ project_1.add_developer(user)
+ board = create(:board, project: project_1)
+
+ visit project_board_path(project_1, board)
+
+ wait_for_requests
+
+ find('.board-card').click
+ end
+
+ it_behaves_like 'assigning labels from sidebar'
+ end
+
+ context 'on group board issue sidebar' do
+ before do
+ parent.add_developer(user)
+ board = create(:board, group: parent)
+
+ visit group_board_path(parent, board)
+
+ wait_for_requests
+
+ find('.board-card').click
+ end
+
+ it_behaves_like 'assigning labels from sidebar'
+ end
+ end
+
context 'issuable filtering' do
let!(:labeled_issue) { create(:labeled_issue, project: project_1, labels: [grandparent_group_label, parent_group_label, project_label_1]) }
let!(:issue) { create(:issue, project: project_1) }
@@ -302,6 +340,34 @@ RSpec.describe 'Labels Hierarchy', :js do
let(:board) { create(:board, group: parent) }
before do
+ parent.add_developer(user)
+ visit group_board_path(parent, board)
+ find('.js-new-board-list').click
+ wait_for_requests
+ end
+
+ context 'when graphql_board_lists FF enabled' do
+ it 'creates lists from all ancestor group labels' do
+ [grandparent_group_label, parent_group_label].each do |label|
+ find('a', text: label.title).click
+ end
+
+ wait_for_requests
+
+ expect(page).to have_selector('.board-title-text', text: grandparent_group_label.title)
+ expect(page).to have_selector('.board-title-text', text: parent_group_label.title)
+ end
+
+ it 'does not create lists from descendant groups' do
+ expect(page).not_to have_selector('a', text: child_group_label.title)
+ end
+ end
+ end
+
+ context 'when graphql_board_lists FF disabled' do
+ let(:board) { create(:board, group: parent) }
+
+ before do
stub_feature_flags(graphql_board_lists: false)
parent.add_developer(user)
visit group_board_path(parent, board)
diff --git a/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb b/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb
index 9e1b0135932..af5ba14e310 100644
--- a/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb
+++ b/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb
@@ -64,7 +64,7 @@ RSpec.describe 'Merge request > User merges when pipeline succeeds', :js do
context 'when enabled after it was previously canceled' do
before do
click_button "Merge when pipeline succeeds"
- click_link "Cancel"
+ click_button "Cancel auto-merge"
wait_for_requests
@@ -87,7 +87,7 @@ RSpec.describe 'Merge request > User merges when pipeline succeeds', :js do
before do
merge_request.merge_params['force_remove_source_branch'] = '0'
merge_request.save!
- click_link "Cancel"
+ click_button "Cancel auto-merge"
end
it_behaves_like 'Merge when pipeline succeeds activator'
@@ -114,7 +114,7 @@ RSpec.describe 'Merge request > User merges when pipeline succeeds', :js do
end
it 'allows to cancel the automatic merge' do
- click_link "Cancel"
+ click_button "Cancel auto-merge"
expect(page).to have_button "Merge when pipeline succeeds"
@@ -124,7 +124,7 @@ RSpec.describe 'Merge request > User merges when pipeline succeeds', :js do
end
it 'allows to delete source branch' do
- click_link "Delete source branch"
+ click_button "Delete source branch"
expect(page).to have_content "The source branch will be deleted"
end
diff --git a/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb b/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb
index 73e628bda98..8343e04aef1 100644
--- a/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb
+++ b/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb
@@ -63,7 +63,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'allows user to mark thread as resolved' do
page.within '.diff-content' do
- find('button[data-qa-selector="resolve_discussion_button"]').click
+ find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
end
expect(page).to have_selector('.discussion-body', visible: false)
@@ -80,7 +80,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'allows user to unresolve thread' do
page.within '.diff-content' do
- find('button[data-qa-selector="resolve_discussion_button"]').click
+ find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
click_button 'Unresolve thread'
end
@@ -92,7 +92,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
describe 'resolved thread' do
before do
page.within '.diff-content' do
- find('button[data-qa-selector="resolve_discussion_button"]').click
+ find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
end
visit_merge_request
@@ -193,7 +193,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'allows user to resolve from reply form without a comment' do
page.within '.diff-content' do
- find('button[data-qa-selector="resolve_discussion_button"]').click
+ find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
end
page.within '.line-resolve-all-container' do
@@ -230,7 +230,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'hides jump to next button when all resolved' do
page.within '.diff-content' do
- find('button[data-qa-selector="resolve_discussion_button"]').click
+ find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
end
expect(page).to have_selector('.discussion-next-btn', visible: false)
@@ -326,7 +326,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'allows user to mark all threads as resolved' do
page.all('.discussion-reply-holder', count: 2).each do |reply_holder|
page.within reply_holder do
- find('button[data-qa-selector="resolve_discussion_button"]').click
+ find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
end
end
@@ -338,7 +338,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'allows user to quickly scroll to next unresolved thread' do
page.within('.discussion-reply-holder', match: :first) do
- find('button[data-qa-selector="resolve_discussion_button"]').click
+ find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
end
page.within '.line-resolve-all-container' do
@@ -410,7 +410,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'allows user to mark thread as resolved' do
page.within '.diff-content' do
- find('button[data-qa-selector="resolve_discussion_button"]').click
+ find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
end
page.within '.diff-content .note' do
@@ -425,7 +425,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'allows user to unresolve thread' do
page.within '.diff-content' do
- find('button[data-qa-selector="resolve_discussion_button"]').click
+ find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
click_button 'Unresolve thread'
end
@@ -453,7 +453,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'allows user to comment & unresolve thread' do
page.within '.diff-content' do
- find('button[data-qa-selector="resolve_discussion_button"]').click
+ find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
find_field('Reply…').click
diff --git a/spec/features/merge_request/user_sees_closing_issues_message_spec.rb b/spec/features/merge_request/user_sees_closing_issues_message_spec.rb
index d6cdc15005b..7b7fff5c936 100644
--- a/spec/features/merge_request/user_sees_closing_issues_message_spec.rb
+++ b/spec/features/merge_request/user_sees_closing_issues_message_spec.rb
@@ -31,7 +31,7 @@ RSpec.describe 'Merge request > User sees closing issues message', :js do
let(:merge_request_description) { "Description\n\nclosing #{issue_1.to_reference}, #{issue_2.to_reference}" }
it 'does not display closing issue message' do
- expect(page).to have_content("Closes #{issue_1.to_reference} and #{issue_2.to_reference}")
+ expect(page).to have_content("Closes issues #{issue_1.to_reference} and #{issue_2.to_reference}")
end
end
@@ -39,7 +39,7 @@ RSpec.describe 'Merge request > User sees closing issues message', :js do
let(:merge_request_description) { "Description\n\nRefers to #{issue_1.to_reference} and #{issue_2.to_reference}" }
it 'does not display closing issue message' do
- expect(page).to have_content("Mentions #{issue_1.to_reference} and #{issue_2.to_reference}")
+ expect(page).to have_content("Mentions issues #{issue_1.to_reference} and #{issue_2.to_reference}")
end
end
@@ -47,8 +47,8 @@ RSpec.describe 'Merge request > User sees closing issues message', :js do
let(:merge_request_title) { "closes #{issue_1.to_reference}\n\n refers to #{issue_2.to_reference}" }
it 'does not display closing issue message' do
- expect(page).to have_content("Closes #{issue_1.to_reference}")
- expect(page).to have_content("Mentions #{issue_2.to_reference}")
+ expect(page).to have_content("Closes issue #{issue_1.to_reference}")
+ expect(page).to have_content("Mentions issue #{issue_2.to_reference}")
end
end
@@ -56,7 +56,7 @@ RSpec.describe 'Merge request > User sees closing issues message', :js do
let(:merge_request_title) { "closing #{issue_1.to_reference}, #{issue_2.to_reference}" }
it 'does not display closing issue message' do
- expect(page).to have_content("Closes #{issue_1.to_reference} and #{issue_2.to_reference}")
+ expect(page).to have_content("Closes issues #{issue_1.to_reference} and #{issue_2.to_reference}")
end
end
@@ -64,7 +64,7 @@ RSpec.describe 'Merge request > User sees closing issues message', :js do
let(:merge_request_title) { "Refers to #{issue_1.to_reference} and #{issue_2.to_reference}" }
it 'does not display closing issue message' do
- expect(page).to have_content("Mentions #{issue_1.to_reference} and #{issue_2.to_reference}")
+ expect(page).to have_content("Mentions issues #{issue_1.to_reference} and #{issue_2.to_reference}")
end
end
@@ -72,8 +72,8 @@ RSpec.describe 'Merge request > User sees closing issues message', :js do
let(:merge_request_title) { "closes #{issue_1.to_reference}\n\n refers to #{issue_2.to_reference}" }
it 'does not display closing issue message' do
- expect(page).to have_content("Closes #{issue_1.to_reference}")
- expect(page).to have_content("Mentions #{issue_2.to_reference}")
+ expect(page).to have_content("Closes issue #{issue_1.to_reference}")
+ expect(page).to have_content("Mentions issue #{issue_2.to_reference}")
end
end
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..2a49109d360 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
@@ -43,12 +43,14 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
let!(:push_pipeline) do
Ci::CreatePipelineService.new(project, user, ref: 'feature')
- .execute(:push)
+ .execute(:push)
+ .payload
end
let!(:detached_merge_request_pipeline) do
Ci::CreatePipelineService.new(project, user, ref: 'feature')
- .execute(:merge_request_event, merge_request: merge_request)
+ .execute(:merge_request_event, merge_request: merge_request)
+ .payload
end
before do
@@ -77,12 +79,14 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
context 'when a user updated a merge request in the parent project', :sidekiq_might_not_need_inline do
let!(:push_pipeline_2) do
Ci::CreatePipelineService.new(project, user, ref: 'feature')
- .execute(:push)
+ .execute(:push)
+ .payload
end
let!(:detached_merge_request_pipeline_2) do
Ci::CreatePipelineService.new(project, user, ref: 'feature')
- .execute(:merge_request_event, merge_request: merge_request)
+ .execute(:merge_request_event, merge_request: merge_request)
+ .payload
end
before do
@@ -147,7 +151,7 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
context 'when detached merge request pipeline is pending' do
it 'waits the head pipeline' do
expect(page).to have_content('to be merged automatically when the pipeline succeeds')
- expect(page).to have_link('Cancel')
+ expect(page).to have_button('Cancel auto-merge')
end
end
@@ -174,7 +178,7 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
it 'waits the head pipeline' do
expect(page).to have_content('to be merged automatically when the pipeline succeeds')
- expect(page).to have_link('Cancel')
+ expect(page).to have_button('Cancel auto-merge')
end
end
end
@@ -222,12 +226,14 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
let!(:push_pipeline) do
Ci::CreatePipelineService.new(forked_project, user2, ref: 'feature')
- .execute(:push)
+ .execute(:push)
+ .payload
end
let!(:detached_merge_request_pipeline) do
Ci::CreatePipelineService.new(forked_project, user2, ref: 'feature')
- .execute(:merge_request_event, merge_request: merge_request)
+ .execute(:merge_request_event, merge_request: merge_request)
+ .payload
end
let(:forked_project) { fork_project(project, user2, repository: true) }
@@ -267,12 +273,14 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
context 'when a user updated a merge request from a forked project to the parent project' do
let!(:push_pipeline_2) do
Ci::CreatePipelineService.new(forked_project, user2, ref: 'feature')
- .execute(:push)
+ .execute(:push)
+ .payload
end
let!(:detached_merge_request_pipeline_2) do
Ci::CreatePipelineService.new(forked_project, user2, ref: 'feature')
- .execute(:merge_request_event, merge_request: merge_request)
+ .execute(:merge_request_event, merge_request: merge_request)
+ .payload
end
before do
@@ -369,7 +377,7 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
context 'when detached merge request pipeline is pending' do
it 'waits the head pipeline' do
expect(page).to have_content('to be merged automatically when the pipeline succeeds')
- expect(page).to have_link('Cancel')
+ expect(page).to have_button('Cancel auto-merge')
end
end
@@ -395,7 +403,7 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
it 'waits the head pipeline' do
expect(page).to have_content('to be merged automatically when the pipeline succeeds')
- expect(page).to have_link('Cancel')
+ expect(page).to have_button('Cancel auto-merge')
end
end
end
diff --git a/spec/features/merge_request/user_sees_pipelines_spec.rb b/spec/features/merge_request/user_sees_pipelines_spec.rb
index a6c8b10f5ca..4967f58528e 100644
--- a/spec/features/merge_request/user_sees_pipelines_spec.rb
+++ b/spec/features/merge_request/user_sees_pipelines_spec.rb
@@ -245,7 +245,7 @@ RSpec.describe 'Merge request > User sees pipelines', :js do
threads << Thread.new do
Sidekiq::Worker.skipping_transaction_check do
- @pipeline = Ci::CreatePipelineService.new(project, user, build_push_data).execute(:push)
+ @pipeline = Ci::CreatePipelineService.new(project, user, build_push_data).execute(:push).payload
end
end
diff --git a/spec/features/merge_request/user_views_diffs_spec.rb b/spec/features/merge_request/user_views_diffs_spec.rb
index 09dfe41a718..208ed1f01e7 100644
--- a/spec/features/merge_request/user_views_diffs_spec.rb
+++ b/spec/features/merge_request/user_views_diffs_spec.rb
@@ -60,7 +60,7 @@ RSpec.describe 'User views diffs', :js do
expect(page).not_to have_selector('.mr-loading-status .loading', visible: true)
end
- it 'expands all diffs' do
+ it 'expands all diffs', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/333628' do
first('.diff-toggle-caret').click
expect(page).to have_button('Expand all')
diff --git a/spec/features/merge_requests/user_lists_merge_requests_spec.rb b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
index ab6242784fe..f96717970bf 100644
--- a/spec/features/merge_requests/user_lists_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
@@ -23,7 +23,7 @@ RSpec.describe 'Merge requests > User lists merge requests' do
milestone: create(:milestone, project: project, due_date: '2013-12-11'),
created_at: 1.minute.ago,
updated_at: 1.minute.ago)
- @fix.metrics.update_column(:merged_at, 10.seconds.ago)
+ @fix.metrics.update!(merged_at: 10.seconds.ago, latest_closed_at: 10.seconds.ago)
@markdown = create(:merge_request,
title: 'markdown',
@@ -34,7 +34,7 @@ RSpec.describe 'Merge requests > User lists merge requests' do
milestone: create(:milestone, project: project, due_date: '2013-12-12'),
created_at: 2.minutes.ago,
updated_at: 2.minutes.ago)
- @markdown.metrics.update_column(:merged_at, 50.seconds.ago)
+ @markdown.metrics.update!(merged_at: 10.minutes.ago, latest_closed_at: 10.seconds.ago)
@merge_test = create(:merge_request,
title: 'merge-test',
@@ -42,7 +42,15 @@ RSpec.describe 'Merge requests > User lists merge requests' do
source_branch: 'merge-test',
created_at: 3.minutes.ago,
updated_at: 10.seconds.ago)
- @merge_test.metrics.update_column(:merged_at, 10.seconds.ago)
+ @merge_test.metrics.update!(merged_at: 10.seconds.ago, latest_closed_at: 10.seconds.ago)
+
+ @feature = create(:merge_request,
+ title: 'feature',
+ source_project: project,
+ source_branch: 'feautre',
+ created_at: 2.minutes.ago,
+ updated_at: 1.minute.ago)
+ @feature.metrics.update!(merged_at: 10.seconds.ago, latest_closed_at: 10.minutes.ago)
end
context 'merge request reviewers' do
@@ -71,9 +79,10 @@ RSpec.describe 'Merge requests > User lists merge requests' do
expect(current_path).to eq(project_merge_requests_path(project))
expect(page).to have_content 'merge-test'
+ expect(page).to have_content 'feature'
expect(page).not_to have_content 'fix'
expect(page).not_to have_content 'markdown'
- expect(count_merge_requests).to eq(1)
+ expect(count_merge_requests).to eq(2)
end
it 'filters on a specific assignee' do
@@ -90,28 +99,35 @@ RSpec.describe 'Merge requests > User lists merge requests' do
expect(first_merge_request).to include('fix')
expect(last_merge_request).to include('merge-test')
- expect(count_merge_requests).to eq(3)
+ expect(count_merge_requests).to eq(4)
end
it 'sorts by last updated' do
visit_merge_requests(project, sort: sort_value_recently_updated)
expect(first_merge_request).to include('merge-test')
- expect(count_merge_requests).to eq(3)
+ expect(count_merge_requests).to eq(4)
end
it 'sorts by milestone' do
visit_merge_requests(project, sort: sort_value_milestone)
expect(first_merge_request).to include('fix')
- expect(count_merge_requests).to eq(3)
+ expect(count_merge_requests).to eq(4)
end
it 'sorts by merged at' do
visit_merge_requests(project, sort: sort_value_merged_date)
expect(first_merge_request).to include('markdown')
- expect(count_merge_requests).to eq(3)
+ expect(count_merge_requests).to eq(4)
+ end
+
+ it 'sorts by closed at' do
+ visit_merge_requests(project, sort: sort_value_closed_date)
+
+ expect(first_merge_request).to include('feature')
+ expect(count_merge_requests).to eq(4)
end
it 'filters on one label and sorts by due date' do
diff --git a/spec/features/nav/top_nav_responsive_spec.rb b/spec/features/nav/top_nav_responsive_spec.rb
index dfe3e76f172..5c6a12a37a3 100644
--- a/spec/features/nav/top_nav_responsive_spec.rb
+++ b/spec/features/nav/top_nav_responsive_spec.rb
@@ -8,8 +8,6 @@ RSpec.describe 'top nav responsive', :js do
let_it_be(:user) { create(:user) }
before do
- stub_feature_flags(combined_menu: true)
-
sign_in(user)
visit explore_projects_path
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index 0f453f1c1e5..9a261c6d9c8 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -74,8 +74,6 @@ RSpec.describe 'Profile account page', :js do
expect(find('#feed_token').value).not_to eq(previous_token)
end
-
- expect(page).to have_content 'Feed token was successfully reset'
end
end
diff --git a/spec/features/profiles/user_manages_applications_spec.rb b/spec/features/profiles/user_manages_applications_spec.rb
index 22eed748c00..c76ef2613fd 100644
--- a/spec/features/profiles/user_manages_applications_spec.rb
+++ b/spec/features/profiles/user_manages_applications_spec.rb
@@ -3,55 +3,12 @@
require 'spec_helper'
RSpec.describe 'User manages applications' do
- let(:user) { create(:user) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:new_application_path) { applications_profile_path }
before do
sign_in(user)
- visit applications_profile_path
end
- it 'manages applications' do
- expect(page).to have_content 'Add new application'
-
- fill_in :doorkeeper_application_name, with: 'test'
- fill_in :doorkeeper_application_redirect_uri, with: 'https://test.com'
- check :doorkeeper_application_scopes_read_user
- click_on 'Save application'
-
- expect(page).to have_content 'Application: test'
- expect(page).to have_content 'Application ID'
- expect(page).to have_content 'Secret'
- expect(page).to have_content 'Confidential Yes'
-
- click_on 'Edit'
-
- expect(page).to have_content 'Edit application'
- fill_in :doorkeeper_application_name, with: 'test_changed'
- uncheck :doorkeeper_application_confidential
- click_on 'Save application'
-
- expect(page).to have_content 'test_changed'
- expect(page).to have_content 'Application ID'
- expect(page).to have_content 'Secret'
- expect(page).to have_content 'Confidential No'
-
- visit applications_profile_path
-
- page.within '.oauth-applications' do
- click_on 'Destroy'
- end
- expect(page.find('.oauth-applications')).not_to have_content 'test_changed'
- end
-
- context 'when scopes are blank' do
- it 'returns an error' do
- expect(page).to have_content 'Add new application'
-
- fill_in :doorkeeper_application_name, with: 'test'
- fill_in :doorkeeper_application_redirect_uri, with: 'https://test.com'
- click_on 'Save application'
-
- expect(page).to have_content("Scopes can't be blank")
- end
- end
+ include_examples 'manage applications'
end
diff --git a/spec/features/project_variables_spec.rb b/spec/features/project_variables_spec.rb
index 62565eaabe1..5139c724d82 100644
--- a/spec/features/project_variables_spec.rb
+++ b/spec/features/project_variables_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe 'Project variables', :js do
click_button('Add variable')
page.within('#add-ci-variable') do
- find('[data-qa-selector="ci_variable_key_field"] input').set('akey')
+ find('[data-qa-selector="ci_variable_key_field"] input').set('akey') # rubocop:disable QA/SelectorUsage
find('#ci-variable-value').set('akey_value')
find('[data-testid="environment-scope"]').click
find('[data-testid="ci-environment-search"]').set('review/*')
diff --git a/spec/features/projects/activity/user_sees_design_activity_spec.rb b/spec/features/projects/activity/user_sees_design_activity_spec.rb
index 389e86299e5..70153921b82 100644
--- a/spec/features/projects/activity/user_sees_design_activity_spec.rb
+++ b/spec/features/projects/activity/user_sees_design_activity_spec.rb
@@ -34,26 +34,26 @@ RSpec.describe 'Projects > Activity > User sees design Activity', :js do
visit activity_project_path(project)
expect(page).to have_content('joined project')
- expect(page).to have_content(design_activity(uploader, 'uploaded'))
- expect(page).to have_content(design_activity(editor, 'revised'))
- expect(page).to have_content(design_activity(deleter, 'deleted'))
+ expect(page).to have_content(design_activity(uploader, 'added'))
+ expect(page).to have_content(design_activity(editor, 'updated'))
+ expect(page).to have_content(design_activity(deleter, 'removed'))
end
it 'allows filtering out the design events', :aggregate_failures do
visit activity_project_path(project, event_filter: EventFilter::ISSUE)
- expect(page).not_to have_content(design_activity(uploader, 'uploaded'))
- expect(page).not_to have_content(design_activity(editor, 'revised'))
- expect(page).not_to have_content(design_activity(deleter, 'deleted'))
+ expect(page).not_to have_content(design_activity(uploader, 'added'))
+ expect(page).not_to have_content(design_activity(editor, 'updated'))
+ expect(page).not_to have_content(design_activity(deleter, 'removed'))
end
it 'allows filtering in the design events', :aggregate_failures do
visit activity_project_path(project, event_filter: EventFilter::DESIGNS)
expect(page).not_to have_content('joined project')
- expect(page).to have_content(design_activity(uploader, 'uploaded'))
- expect(page).to have_content(design_activity(editor, 'revised'))
- expect(page).to have_content(design_activity(deleter, 'deleted'))
+ expect(page).to have_content(design_activity(uploader, 'added'))
+ expect(page).to have_content(design_activity(editor, 'updated'))
+ expect(page).to have_content(design_activity(deleter, 'removed'))
end
end
diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb
index 595304789a6..8281e82959b 100644
--- a/spec/features/projects/blobs/blob_show_spec.rb
+++ b/spec/features/projects/blobs/blob_show_spec.rb
@@ -13,6 +13,22 @@ RSpec.describe 'File blob', :js do
wait_for_requests
end
+ def create_file(file_name, content)
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add #{file_name}",
+ file_path: file_name,
+ file_content: <<-SPEC.strip_heredoc
+ #{content}
+ SPEC
+ ).execute
+ end
+
context 'Ruby file' do
before do
visit_blob('files/ruby/popen.rb')
@@ -121,7 +137,7 @@ RSpec.describe 'File blob', :js do
context 'when ref switch' do
def switch_ref_to(ref_name)
- first('.qa-branches-select').click
+ first('.qa-branches-select').click # rubocop:disable QA/SelectorUsage
page.within '.project-refs-form' do
click_link ref_name
@@ -584,94 +600,483 @@ RSpec.describe 'File blob', :js do
end
end
- describe '.gitlab-ci.yml' do
+ context 'files with auxiliary viewers' do
before do
- project.add_maintainer(project.creator)
+ stub_feature_flags(refactor_blob_viewer: true)
+ end
- Files::CreateService.new(
- project,
- project.creator,
- start_branch: 'master',
- branch_name: 'master',
- commit_message: "Add .gitlab-ci.yml",
- file_path: '.gitlab-ci.yml',
- file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
- ).execute
+ describe '.gitlab-ci.yml' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab-ci.yml",
+ file_path: '.gitlab-ci.yml',
+ file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
+ ).execute
+
+ visit_blob('.gitlab-ci.yml')
+ end
- visit_blob('.gitlab-ci.yml')
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that configuration is valid
+ expect(page).to have_content('This GitLab CI configuration is valid.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
end
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows that configuration is valid
- expect(page).to have_content('This GitLab CI configuration is valid.')
+ describe '.gitlab/route-map.yml' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab/route-map.yml",
+ file_path: '.gitlab/route-map.yml',
+ file_content: <<-MAP.strip_heredoc
+ # Team data
+ - source: 'data/team.yml'
+ public: 'team/'
+ MAP
+ ).execute
+
+ visit_blob('.gitlab/route-map.yml')
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that map is valid
+ expect(page).to have_content('This Route Map is valid.')
- # shows a learn more link
- expect(page).to have_link('Learn more')
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
end
end
- end
- describe '.gitlab/route-map.yml' do
- before do
- project.add_maintainer(project.creator)
+ describe '.gitlab/dashboards/custom-dashboard.yml' do
+ before do
+ project.add_maintainer(project.creator)
- Files::CreateService.new(
- project,
- project.creator,
- start_branch: 'master',
- branch_name: 'master',
- commit_message: "Add .gitlab/route-map.yml",
- file_path: '.gitlab/route-map.yml',
- file_content: <<-MAP.strip_heredoc
- # Team data
- - source: 'data/team.yml'
- public: 'team/'
- MAP
- ).execute
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab/dashboards/custom-dashboard.yml",
+ file_path: '.gitlab/dashboards/custom-dashboard.yml',
+ file_content: file_content
+ ).execute
+ end
+
+ context 'with metrics_dashboard_exhaustive_validations feature flag off' do
+ before do
+ stub_feature_flags(metrics_dashboard_exhaustive_validations: false)
+ visit_blob('.gitlab/dashboards/custom-dashboard.yml')
+ end
+
+ context 'valid dashboard file' do
+ let(:file_content) { File.read(Rails.root.join('config/prometheus/common_metrics.yml')) }
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that dashboard yaml is valid
+ expect(page).to have_content('Metrics Dashboard YAML definition is valid.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+
+ context 'invalid dashboard file' do
+ let(:file_content) { "dashboard: 'invalid'" }
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that dashboard yaml is invalid
+ expect(page).to have_content('Metrics Dashboard YAML definition is invalid:')
+ expect(page).to have_content("panel_groups: should be an array of panel_groups objects")
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+ end
+
+ context 'with metrics_dashboard_exhaustive_validations feature flag on' do
+ before do
+ stub_feature_flags(metrics_dashboard_exhaustive_validations: true)
+ visit_blob('.gitlab/dashboards/custom-dashboard.yml')
+ end
+
+ context 'valid dashboard file' do
+ let(:file_content) { File.read(Rails.root.join('config/prometheus/common_metrics.yml')) }
- visit_blob('.gitlab/route-map.yml')
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that dashboard yaml is valid
+ expect(page).to have_content('Metrics Dashboard YAML definition is valid.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+
+ context 'invalid dashboard file' do
+ let(:file_content) { "dashboard: 'invalid'" }
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that dashboard yaml is invalid
+ expect(page).to have_content('Metrics Dashboard YAML definition is invalid:')
+ expect(page).to have_content("root is missing required keys: panel_groups")
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+ end
end
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows that map is valid
- expect(page).to have_content('This Route Map is valid.')
+ context 'LICENSE' do
+ before do
+ visit_blob('LICENSE')
+ end
- # shows a learn more link
- expect(page).to have_link('Learn more')
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows license
+ expect(page).to have_content('This project is licensed under the MIT License.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more', href: 'http://choosealicense.com/licenses/mit/')
+ end
end
end
- end
- describe '.gitlab/dashboards/custom-dashboard.yml' do
- before do
- project.add_maintainer(project.creator)
+ context '*.gemspec' do
+ before do
+ project.add_maintainer(project.creator)
- Files::CreateService.new(
- project,
- project.creator,
- start_branch: 'master',
- branch_name: 'master',
- commit_message: "Add .gitlab/dashboards/custom-dashboard.yml",
- file_path: '.gitlab/dashboards/custom-dashboard.yml',
- file_content: file_content
- ).execute
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add activerecord.gemspec",
+ file_path: 'activerecord.gemspec',
+ file_content: <<-SPEC.strip_heredoc
+ Gem::Specification.new do |s|
+ s.platform = Gem::Platform::RUBY
+ s.name = "activerecord"
+ end
+ SPEC
+ ).execute
+
+ visit_blob('activerecord.gemspec')
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows names of dependency manager and package
+ expect(page).to have_content('This project manages its dependencies using RubyGems.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more', href: 'https://rubygems.org/')
+ end
+ end
end
- context 'with metrics_dashboard_exhaustive_validations feature flag off' do
+ context 'CONTRIBUTING.md' do
before do
- stub_feature_flags(metrics_dashboard_exhaustive_validations: false)
- visit_blob('.gitlab/dashboards/custom-dashboard.yml')
+ file_name = 'CONTRIBUTING.md'
+
+ create_file(file_name, '## Contribution guidelines')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("After you've reviewed these contribution guidelines, you'll be all set to contribute to this project.")
+ end
+ end
+ end
+
+ context 'CHANGELOG.md' do
+ before do
+ file_name = 'CHANGELOG.md'
+
+ create_file(file_name, '## Changelog for v1.0.0')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("To find the state of this project's repository at the time of any of these versions, check out the tags.")
+ end
+ end
+ end
+
+ context 'Cargo.toml' do
+ before do
+ file_name = 'Cargo.toml'
+
+ create_file(file_name, '
+ [package]
+ name = "hello_world" # the name of the package
+ version = "0.1.0" # the current version, obeying semver
+ authors = ["Alice <a@example.com>", "Bob <b@example.com>"]
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Cargo.")
+ end
+ end
+ end
+
+ context 'Cartfile' do
+ before do
+ file_name = 'Cartfile'
+
+ create_file(file_name, '
+ gitlab "Alamofire/Alamofire" == 4.9.0
+ gitlab "Alamofire/AlamofireImage" ~> 3.4
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Carthage.")
+ end
+ end
+ end
+
+ context 'composer.json' do
+ before do
+ file_name = 'composer.json'
+
+ create_file(file_name, '
+ {
+ "license": "MIT"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Composer.")
+ end
end
+ end
+
+ context 'Gemfile' do
+ before do
+ file_name = 'Gemfile'
+
+ create_file(file_name, '
+ source "https://rubygems.org"
- context 'valid dashboard file' do
- let(:file_content) { File.read(Rails.root.join('config/prometheus/common_metrics.yml')) }
+ # Gems here
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Bundler.")
+ end
+ end
+ end
+
+ context 'Godeps.json' do
+ before do
+ file_name = 'Godeps.json'
+
+ create_file(file_name, '
+ {
+ "GoVersion": "go1.6"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using godep.")
+ end
+ end
+ end
+
+ context 'go.mod' do
+ before do
+ file_name = 'go.mod'
+
+ create_file(file_name, '
+ module example.com/mymodule
+
+ go 1.14
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Go Modules.")
+ end
+ end
+ end
+
+ context 'package.json' do
+ before do
+ file_name = 'package.json'
+
+ create_file(file_name, '
+ {
+ "name": "my-awesome-package",
+ "version": "1.0.0"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using npm.")
+ end
+ end
+ end
+
+ context 'podfile' do
+ before do
+ file_name = 'podfile'
+
+ create_file(file_name, 'platform :ios, "8.0"')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using CocoaPods.")
+ end
+ end
+ end
+
+ context 'test.podspec' do
+ before do
+ file_name = 'test.podspec'
+
+ create_file(file_name, '
+ Pod::Spec.new do |s|
+ s.name = "TensorFlowLiteC"
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using CocoaPods.")
+ end
+ end
+ end
+
+ context 'JSON.podspec.json' do
+ before do
+ file_name = 'JSON.podspec.json'
+
+ create_file(file_name, '
+ {
+ "name": "JSON"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using CocoaPods.")
+ end
+ end
+ end
+
+ context 'requirements.txt' do
+ before do
+ file_name = 'requirements.txt'
+
+ create_file(file_name, 'Project requirements')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using pip.")
+ end
+ end
+ end
+
+ context 'yarn.lock' do
+ before do
+ file_name = 'yarn.lock'
+
+ create_file(file_name, '
+ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+ # yarn lockfile v1
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Yarn.")
+ end
+ end
+ end
+
+ context 'when refactor_blob_viewer is disabled' do
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ end
+
+ describe '.gitlab-ci.yml' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab-ci.yml",
+ file_path: '.gitlab-ci.yml',
+ file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
+ ).execute
+
+ visit_blob('.gitlab-ci.yml')
+ end
it 'displays an auxiliary viewer' do
aggregate_failures do
- # shows that dashboard yaml is valid
- expect(page).to have_content('Metrics Dashboard YAML definition is valid.')
+ # shows that configuration is valid
+ expect(page).to have_content('This GitLab CI configuration is valid.')
# shows a learn more link
expect(page).to have_link('Learn more')
@@ -679,104 +1084,422 @@ RSpec.describe 'File blob', :js do
end
end
- context 'invalid dashboard file' do
- let(:file_content) { "dashboard: 'invalid'" }
+ describe '.gitlab/route-map.yml' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab/route-map.yml",
+ file_path: '.gitlab/route-map.yml',
+ file_content: <<-MAP.strip_heredoc
+ # Team data
+ - source: 'data/team.yml'
+ public: 'team/'
+ MAP
+ ).execute
+
+ visit_blob('.gitlab/route-map.yml')
+ end
it 'displays an auxiliary viewer' do
aggregate_failures do
- # shows that dashboard yaml is invalid
- expect(page).to have_content('Metrics Dashboard YAML definition is invalid:')
- expect(page).to have_content("panel_groups: should be an array of panel_groups objects")
+ # shows that map is valid
+ expect(page).to have_content('This Route Map is valid.')
# shows a learn more link
expect(page).to have_link('Learn more')
end
end
end
- end
- context 'with metrics_dashboard_exhaustive_validations feature flag on' do
- before do
- stub_feature_flags(metrics_dashboard_exhaustive_validations: true)
- visit_blob('.gitlab/dashboards/custom-dashboard.yml')
+ describe '.gitlab/dashboards/custom-dashboard.yml' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab/dashboards/custom-dashboard.yml",
+ file_path: '.gitlab/dashboards/custom-dashboard.yml',
+ file_content: file_content
+ ).execute
+ end
+
+ context 'with metrics_dashboard_exhaustive_validations feature flag off' do
+ before do
+ stub_feature_flags(metrics_dashboard_exhaustive_validations: false)
+ visit_blob('.gitlab/dashboards/custom-dashboard.yml')
+ end
+
+ context 'valid dashboard file' do
+ let(:file_content) { File.read(Rails.root.join('config/prometheus/common_metrics.yml')) }
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that dashboard yaml is valid
+ expect(page).to have_content('Metrics Dashboard YAML definition is valid.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+
+ context 'invalid dashboard file' do
+ let(:file_content) { "dashboard: 'invalid'" }
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that dashboard yaml is invalid
+ expect(page).to have_content('Metrics Dashboard YAML definition is invalid:')
+ expect(page).to have_content("panel_groups: should be an array of panel_groups objects")
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+ end
+
+ context 'with metrics_dashboard_exhaustive_validations feature flag on' do
+ before do
+ stub_feature_flags(metrics_dashboard_exhaustive_validations: true)
+ visit_blob('.gitlab/dashboards/custom-dashboard.yml')
+ end
+
+ context 'valid dashboard file' do
+ let(:file_content) { File.read(Rails.root.join('config/prometheus/common_metrics.yml')) }
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that dashboard yaml is valid
+ expect(page).to have_content('Metrics Dashboard YAML definition is valid.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+
+ context 'invalid dashboard file' do
+ let(:file_content) { "dashboard: 'invalid'" }
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that dashboard yaml is invalid
+ expect(page).to have_content('Metrics Dashboard YAML definition is invalid:')
+ expect(page).to have_content("root is missing required keys: panel_groups")
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+ end
end
- context 'valid dashboard file' do
- let(:file_content) { File.read(Rails.root.join('config/prometheus/common_metrics.yml')) }
+ context 'LICENSE' do
+ before do
+ visit_blob('LICENSE')
+ end
it 'displays an auxiliary viewer' do
aggregate_failures do
- # shows that dashboard yaml is valid
- expect(page).to have_content('Metrics Dashboard YAML definition is valid.')
+ # shows license
+ expect(page).to have_content('This project is licensed under the MIT License.')
# shows a learn more link
- expect(page).to have_link('Learn more')
+ expect(page).to have_link('Learn more', href: 'http://choosealicense.com/licenses/mit/')
end
end
end
- context 'invalid dashboard file' do
- let(:file_content) { "dashboard: 'invalid'" }
+ context '*.gemspec' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add activerecord.gemspec",
+ file_path: 'activerecord.gemspec',
+ file_content: <<-SPEC.strip_heredoc
+ Gem::Specification.new do |s|
+ s.platform = Gem::Platform::RUBY
+ s.name = "activerecord"
+ end
+ SPEC
+ ).execute
+
+ visit_blob('activerecord.gemspec')
+ end
it 'displays an auxiliary viewer' do
aggregate_failures do
- # shows that dashboard yaml is invalid
- expect(page).to have_content('Metrics Dashboard YAML definition is invalid:')
- expect(page).to have_content("root is missing required keys: panel_groups")
+ # shows names of dependency manager and package
+ expect(page).to have_content('This project manages its dependencies using RubyGems.')
# shows a learn more link
- expect(page).to have_link('Learn more')
+ expect(page).to have_link('Learn more', href: 'https://rubygems.org/')
end
end
end
- end
- end
- context 'LICENSE' do
- before do
- visit_blob('LICENSE')
- end
+ context 'CONTRIBUTING.md' do
+ before do
+ file_name = 'CONTRIBUTING.md'
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows license
- expect(page).to have_content('This project is licensed under the MIT License.')
+ create_file(file_name, '## Contribution guidelines')
+ visit_blob(file_name)
+ end
- # shows a learn more link
- expect(page).to have_link('Learn more', href: 'http://choosealicense.com/licenses/mit/')
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("After you've reviewed these contribution guidelines, you'll be all set to contribute to this project.")
+ end
+ end
end
- end
- end
- context '*.gemspec' do
- before do
- project.add_maintainer(project.creator)
+ context 'CHANGELOG.md' do
+ before do
+ file_name = 'CHANGELOG.md'
- Files::CreateService.new(
- project,
- project.creator,
- start_branch: 'master',
- branch_name: 'master',
- commit_message: "Add activerecord.gemspec",
- file_path: 'activerecord.gemspec',
- file_content: <<-SPEC.strip_heredoc
- Gem::Specification.new do |s|
- s.platform = Gem::Platform::RUBY
- s.name = "activerecord"
- end
- SPEC
- ).execute
+ create_file(file_name, '## Changelog for v1.0.0')
+ visit_blob(file_name)
+ end
- visit_blob('activerecord.gemspec')
- end
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("To find the state of this project's repository at the time of any of these versions, check out the tags.")
+ end
+ end
+ end
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows names of dependency manager and package
- expect(page).to have_content('This project manages its dependencies using RubyGems.')
+ context 'Cargo.toml' do
+ before do
+ file_name = 'Cargo.toml'
+
+ create_file(file_name, '
+ [package]
+ name = "hello_world" # the name of the package
+ version = "0.1.0" # the current version, obeying semver
+ authors = ["Alice <a@example.com>", "Bob <b@example.com>"]
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Cargo.")
+ end
+ end
+ end
+
+ context 'Cartfile' do
+ before do
+ file_name = 'Cartfile'
+
+ create_file(file_name, '
+ gitlab "Alamofire/Alamofire" == 4.9.0
+ gitlab "Alamofire/AlamofireImage" ~> 3.4
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Carthage.")
+ end
+ end
+ end
+
+ context 'composer.json' do
+ before do
+ file_name = 'composer.json'
+
+ create_file(file_name, '
+ {
+ "license": "MIT"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Composer.")
+ end
+ end
+ end
+
+ context 'Gemfile' do
+ before do
+ file_name = 'Gemfile'
+
+ create_file(file_name, '
+ source "https://rubygems.org"
+
+ # Gems here
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Bundler.")
+ end
+ end
+ end
+
+ context 'Godeps.json' do
+ before do
+ file_name = 'Godeps.json'
+
+ create_file(file_name, '
+ {
+ "GoVersion": "go1.6"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using godep.")
+ end
+ end
+ end
+
+ context 'go.mod' do
+ before do
+ file_name = 'go.mod'
+
+ create_file(file_name, '
+ module example.com/mymodule
- # shows a learn more link
- expect(page).to have_link('Learn more', href: 'https://rubygems.org/')
+ go 1.14
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Go Modules.")
+ end
+ end
+ end
+
+ context 'package.json' do
+ before do
+ file_name = 'package.json'
+
+ create_file(file_name, '
+ {
+ "name": "my-awesome-package",
+ "version": "1.0.0"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using npm.")
+ end
+ end
+ end
+
+ context 'podfile' do
+ before do
+ file_name = 'podfile'
+
+ create_file(file_name, 'platform :ios, "8.0"')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using CocoaPods.")
+ end
+ end
+ end
+
+ context 'test.podspec' do
+ before do
+ file_name = 'test.podspec'
+
+ create_file(file_name, '
+ Pod::Spec.new do |s|
+ s.name = "TensorFlowLiteC"
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using CocoaPods.")
+ end
+ end
+ end
+
+ context 'JSON.podspec.json' do
+ before do
+ file_name = 'JSON.podspec.json'
+
+ create_file(file_name, '
+ {
+ "name": "JSON"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using CocoaPods.")
+ end
+ end
+ end
+
+ context 'requirements.txt' do
+ before do
+ file_name = 'requirements.txt'
+
+ create_file(file_name, 'Project requirements')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using pip.")
+ end
+ end
+ end
+
+ context 'yarn.lock' do
+ before do
+ file_name = 'yarn.lock'
+
+ create_file(file_name, '
+ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+ # yarn lockfile v1
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Yarn.")
+ end
+ end
end
end
end
diff --git a/spec/features/projects/ci/editor_spec.rb b/spec/features/projects/ci/editor_spec.rb
index c0cc12eac66..192bccd6f6e 100644
--- a/spec/features/projects/ci/editor_spec.rb
+++ b/spec/features/projects/ci/editor_spec.rb
@@ -5,17 +5,55 @@ require 'spec_helper'
RSpec.describe 'Pipeline Editor', :js do
include Spec::Support::Helpers::Features::SourceEditorSpecHelpers
- let(:project) { create(:project, :repository) }
+ let(:project) { create(:project_empty_repo, :public) }
let(:user) { create(:user) }
+ let(:default_branch) { 'main' }
+ let(:other_branch) { 'test' }
+
before do
sign_in(user)
project.add_developer(user)
+ project.repository.create_file(user, project.ci_config_path_or_default, 'Default Content', message: 'Create CI file for main', branch_name: default_branch)
+ project.repository.create_file(user, project.ci_config_path_or_default, 'Other Content', message: 'Create CI file for test', branch_name: other_branch)
+
visit project_ci_pipeline_editor_path(project)
+ wait_for_requests
end
it 'user sees the Pipeline Editor page' do
expect(page).to have_content('Pipeline Editor')
end
+
+ context 'branch switcher' do
+ before do
+ stub_feature_flags(pipeline_editor_branch_switcher: true)
+ end
+
+ def switch_to_branch(branch)
+ find('[data-testid="branch-selector"]').click
+
+ page.within '[data-testid="branch-selector"]' do
+ click_button branch
+ wait_for_requests
+ end
+ end
+
+ it 'displays current branch' do
+ page.within('[data-testid="branch-selector"]') do
+ expect(page).to have_content(default_branch)
+ expect(page).not_to have_content(other_branch)
+ end
+ end
+
+ it 'displays updated current branch after switching branches' do
+ switch_to_branch(other_branch)
+
+ page.within('[data-testid="branch-selector"]') do
+ expect(page).to have_content(other_branch)
+ expect(page).not_to have_content(default_branch)
+ end
+ end
+ end
end
diff --git a/spec/features/projects/commit/mini_pipeline_graph_spec.rb b/spec/features/projects/commit/mini_pipeline_graph_spec.rb
index 6de02556175..57b35d81bb8 100644
--- a/spec/features/projects/commit/mini_pipeline_graph_spec.rb
+++ b/spec/features/projects/commit/mini_pipeline_graph_spec.rb
@@ -19,6 +19,7 @@ RSpec.describe 'Mini Pipeline Graph in Commit View', :js do
before do
build.run
visit project_commit_path(project, project.commit.id)
+ wait_for_requests
end
it 'display icon with status' do
@@ -26,7 +27,7 @@ RSpec.describe 'Mini Pipeline Graph in Commit View', :js do
end
it 'displays a mini pipeline graph' do
- expect(page).to have_selector('[data-testid="pipeline-mini-graph"]')
+ expect(page).to have_selector('[data-testid="commit-box-mini-graph"]')
first('.mini-pipeline-graph-dropdown-toggle').click
diff --git a/spec/features/projects/environments/environment_metrics_spec.rb b/spec/features/projects/environments/environment_metrics_spec.rb
index e8f197b67c2..0f858c627bc 100644
--- a/spec/features/projects/environments/environment_metrics_spec.rb
+++ b/spec/features/projects/environments/environment_metrics_spec.rb
@@ -27,12 +27,12 @@ RSpec.describe 'Environment > Metrics' do
shared_examples 'has environment selector' do
it 'has a working environment selector', :js do
- click_link('See metrics')
+ click_link 'Monitoring'
expect(page).to have_current_path(project_metrics_dashboard_path(project, environment: environment.id))
- expect(page).to have_css('[data-qa-selector="environments_dropdown"]')
+ expect(page).to have_css('[data-qa-selector="environments_dropdown"]') # rubocop:disable QA/SelectorUsage
- within('[data-qa-selector="environments_dropdown"]') do
+ within('[data-qa-selector="environments_dropdown"]') do # rubocop:disable QA/SelectorUsage
# Click on the dropdown
click_on(environment.name)
@@ -55,10 +55,10 @@ RSpec.describe 'Environment > Metrics' do
create(:deployment, environment: environment, deployable: build)
end
- it 'shows metrics' do
- click_link('See metrics')
+ it 'shows metrics', :js do
+ click_link 'Monitoring'
- expect(page).to have_css('div#prometheus-graphs')
+ expect(page).to have_css('[data-qa-selector="prometheus_graphs"]') # rubocop:disable QA/SelectorUsage
end
it_behaves_like 'has environment selector'
diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb
index fea054de64e..5320f68b525 100644
--- a/spec/features/projects/environments/environment_spec.rb
+++ b/spec/features/projects/environments/environment_spec.rb
@@ -27,20 +27,6 @@ RSpec.describe 'Environment' do
visit_environment(environment)
end
- it 'shows environment name' do
- expect(page).to have_content(environment.name)
- end
-
- context 'without auto-stop' do
- it 'does not show auto-stop text' do
- expect(page).not_to have_content('Auto stops')
- end
-
- it 'does not show auto-stop button' do
- expect(page).not_to have_selector(auto_stop_button_selector)
- end
- end
-
context 'with auto-stop' do
let!(:environment) { create(:environment, :will_auto_stop, name: 'staging', project: project) }
@@ -48,11 +34,11 @@ RSpec.describe 'Environment' do
visit_environment(environment)
end
- it 'shows auto stop info' do
+ it 'shows auto stop info', :js do
expect(page).to have_content('Auto stops')
end
- it 'shows auto stop button' do
+ it 'shows auto stop button', :js do
expect(page).to have_selector(auto_stop_button_selector)
expect(page.find(auto_stop_button_selector).find(:xpath, '..')['action']).to have_content(cancel_auto_stop_project_environment_path(environment.project, environment))
end
@@ -80,7 +66,6 @@ RSpec.describe 'Environment' do
it 'does show deployment SHA' do
expect(page).to have_link(deployment.short_sha)
expect(page).not_to have_link('Re-deploy')
- expect(page).not_to have_terminal_button
end
end
@@ -186,7 +171,7 @@ RSpec.describe 'Environment' do
let(:build) { create(:ci_build, pipeline: pipeline) }
let(:deployment) { create(:deployment, :success, environment: environment, deployable: build) }
- it 'does show an external link button' do
+ it 'does show an external link button', :js do
expect(page).to have_link(nil, href: environment.external_url)
end
end
@@ -200,10 +185,6 @@ RSpec.describe 'Environment' do
context 'for project maintainer' do
let(:role) { :maintainer }
- it 'shows the terminal button' do
- expect(page).to have_terminal_button
- end
-
context 'web terminal', :js do
before do
# Stub #terminals as it causes js-enabled feature specs to
@@ -224,14 +205,6 @@ RSpec.describe 'Environment' do
end
end
end
-
- context 'for developer' do
- let(:role) { :developer }
-
- it 'does not show terminal button' do
- expect(page).not_to have_terminal_button
- end
- end
end
end
@@ -259,7 +232,7 @@ RSpec.describe 'Environment' do
click_button('Stop')
click_button('Stop environment') # confirm modal
wait_for_all_requests
- expect(page).to have_content('close_app')
+ expect(page).to have_button('Delete')
end
end
@@ -269,7 +242,7 @@ RSpec.describe 'Environment' do
name: action.ref, project: project)
end
- it 'does not allow to stop environment' do
+ it 'does not allow to stop environment', :js do
expect(page).not_to have_button('Stop')
end
end
@@ -277,7 +250,7 @@ RSpec.describe 'Environment' do
context 'for reporter' do
let(:role) { :reporter }
- it 'does not show stop button' do
+ it 'does not show stop button', :js do
expect(page).not_to have_button('Stop')
end
end
@@ -287,7 +260,7 @@ RSpec.describe 'Environment' do
context 'when environment is stopped' do
let(:environment) { create(:environment, project: project, state: :stopped) }
- it 'does not show stop button' do
+ it 'does not show stop button', :js do
expect(page).not_to have_button('Stop')
end
end
@@ -323,7 +296,7 @@ RSpec.describe 'Environment' do
ref: 'feature')
end
- it 'user visits environment page' do
+ it 'user visits environment page', :js do
visit_environment(environment)
expect(page).to have_button('Stop')
@@ -380,8 +353,4 @@ RSpec.describe 'Environment' do
def visit_environment(environment)
visit project_environment_path(environment.project, environment)
end
-
- def have_terminal_button
- have_link(nil, href: terminal_project_environment_path(project, environment))
- end
end
diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb
index 0dd4bd55d46..9413fae02e0 100644
--- a/spec/features/projects/environments/environments_spec.rb
+++ b/spec/features/projects/environments/environments_spec.rb
@@ -455,10 +455,10 @@ RSpec.describe 'Environments page', :js do
expect(page).to have_content 'review-1'
expect(page).to have_content 'review-2'
within('.ci-table') do
- within('[data-qa-selector="environment_item"]', text: 'review-1') do
+ within('[data-qa-selector="environment_item"]', text: 'review-1') do # rubocop:disable QA/SelectorUsage
expect(find('.js-auto-stop').text).not_to be_empty
end
- within('[data-qa-selector="environment_item"]', text: 'review-2') do
+ within('[data-qa-selector="environment_item"]', text: 'review-2') do # rubocop:disable QA/SelectorUsage
expect(find('.js-auto-stop').text).not_to be_empty
end
end
diff --git a/spec/features/projects/environments_pod_logs_spec.rb b/spec/features/projects/environments_pod_logs_spec.rb
index 5019e45593c..7d31de2b418 100644
--- a/spec/features/projects/environments_pod_logs_spec.rb
+++ b/spec/features/projects/environments_pod_logs_spec.rb
@@ -50,7 +50,7 @@ RSpec.describe 'Environment > Pod Logs', :js, :kubeclient do
wait_for_requests
- page.within('.qa-pods-dropdown') do
+ page.within('.qa-pods-dropdown') do # rubocop:disable QA/SelectorUsage
find(".dropdown-toggle:not([disabled])").click
dropdown_items = find(".dropdown-menu").all(".dropdown-item:not([disabled])")
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 30bfcb645f4..221f07a2f75 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
@@ -91,7 +91,7 @@ RSpec.describe 'User sees feature flag list', :js do
it 'shows the empty page' do
expect(page).to have_text 'Get started with feature flags'
expect(page).to have_selector('.btn-confirm', text: 'New feature flag')
- expect(page).to have_selector('[data-qa-selector="configure_feature_flags_button"]', text: 'Configure')
+ expect(page).to have_selector('[data-qa-selector="configure_feature_flags_button"]', text: 'Configure') # rubocop:disable QA/SelectorUsage
end
end
end
diff --git a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
index 42f8daf9d5e..37583870cfd 100644
--- a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
+++ b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe 'Projects > Files > Project owner sees a link to create a license
expect(current_path).to eq("/-/ide/project/#{project.full_path}/edit/master/-/LICENSE")
- expect(page).to have_selector('.qa-file-templates-bar')
+ expect(page).to have_selector('.qa-file-templates-bar') # rubocop:disable QA/SelectorUsage
select_template('MIT License')
diff --git a/spec/features/projects/fork_spec.rb b/spec/features/projects/fork_spec.rb
index 9a6d1961a02..69e4303cce7 100644
--- a/spec/features/projects/fork_spec.rb
+++ b/spec/features/projects/fork_spec.rb
@@ -181,8 +181,8 @@ RSpec.describe 'Project fork' do
it 'allows user to fork only to the group on fork page', :js do
visit new_project_fork_path(project)
- to_personal_namespace = find('[data-qa-selector=fork_namespace_button].disabled')
- to_group = find(".fork-groups button[data-qa-name=#{group.name}]")
+ to_personal_namespace = find('[data-qa-selector=fork_namespace_button].disabled') # rubocop:disable QA/SelectorUsage
+ to_group = find(".fork-groups button[data-qa-name=#{group.name}]") # rubocop:disable QA/SelectorUsage
expect(to_personal_namespace).not_to be_nil
expect(to_group).not_to be_disabled
diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb
index 7f8ded4fa43..ccf3ccc6a96 100644
--- a/spec/features/projects/import_export/export_file_spec.rb
+++ b/spec/features/projects/import_export/export_file_spec.rb
@@ -82,8 +82,7 @@ RSpec.describe 'Import/Export - project export integration test', :js do
relations << Gitlab::Json.parse(IO.read(project_json_path))
Dir.glob(File.join(tmpdir, 'tree/project', '*.ndjson')) do |rb_filename|
File.foreach(rb_filename) do |line|
- json = ActiveSupport::JSON.decode(line)
- relations << json
+ relations << Gitlab::Json.parse(line)
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 a4c57e83bdd..302187917b7 100644
--- a/spec/features/projects/import_export/import_file_spec.rb
+++ b/spec/features/projects/import_export/import_file_spec.rb
@@ -62,6 +62,6 @@ RSpec.describe 'Import/Export - project import integration test', :js do
end
def click_import_project
- find('[data-qa-panel-name="import_project"]').click
+ find('[data-qa-panel-name="import_project"]').click # rubocop:disable QA/SelectorUsage
end
end
diff --git a/spec/features/projects/infrastructure_registry_spec.rb b/spec/features/projects/infrastructure_registry_spec.rb
index c3cb3955092..16dd96e6c02 100644
--- a/spec/features/projects/infrastructure_registry_spec.rb
+++ b/spec/features/projects/infrastructure_registry_spec.rb
@@ -11,9 +11,9 @@ RSpec.describe 'Infrastructure Registry' do
project.add_maintainer(user)
end
- context 'when feature is not available' do
+ context 'when packages registry is not enabled' do
before do
- stub_feature_flags(infrastructure_registry_page: false)
+ stub_config(packages: { enabled: false })
end
it 'gives 404' do
@@ -23,7 +23,7 @@ RSpec.describe 'Infrastructure Registry' do
end
end
- context 'when feature is available', :js do
+ context 'when packages registry is enabled', :js do
before do
visit_project_infrastructure_registry
end
diff --git a/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb b/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb
new file mode 100644
index 00000000000..f46cade9d5f
--- /dev/null
+++ b/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb
@@ -0,0 +1,91 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User uses inherited settings', :js do
+ include JiraServiceHelper
+
+ include_context 'project service activation'
+
+ before do
+ stub_jira_integration_test
+ end
+
+ shared_examples 'inherited settings' do
+ let_it_be(:project_settings) { { url: 'http://project.com', password: 'project' } }
+
+ describe 'switching from inherited to custom settings' do
+ let_it_be(:integration) { create(:jira_integration, project: project, inherit_from_id: parent_integration.id, **project_settings) }
+
+ it 'clears the form fields and saves the entered values' do
+ visit_project_integration('Jira')
+
+ expect(page).not_to have_button('Use custom settings')
+ expect(page).to have_field('Web URL', with: parent_settings[:url], readonly: true)
+ expect(page).to have_field('Enter new password or API token', with: '', readonly: true)
+
+ click_on 'Use default settings'
+ click_on 'Use custom settings'
+
+ expect(page).not_to have_button('Use default settings')
+ expect(page).to have_field('Web URL', with: project_settings[:url], readonly: false)
+ expect(page).to have_field('Enter new password or API token', with: '', readonly: false)
+
+ fill_in 'Web URL', with: 'http://custom.com'
+ fill_in 'Enter new password or API token', with: 'custom'
+
+ click_save_integration
+
+ expect(page).to have_text('Jira settings saved and active.')
+ expect(integration.reload).to have_attributes(
+ inherit_from_id: nil,
+ url: 'http://custom.com',
+ password: 'custom'
+ )
+ end
+ end
+
+ describe 'switching from custom to inherited settings' do
+ let_it_be(:integration) { create(:jira_integration, project: project, **project_settings) }
+
+ it 'resets the form fields, makes them read-only, and saves the inherited values' do
+ visit_project_integration('Jira')
+
+ expect(page).not_to have_button('Use default settings')
+ expect(page).to have_field('URL', with: project_settings[:url], readonly: false)
+ expect(page).to have_field('Enter new password or API token', with: '', readonly: false)
+
+ click_on 'Use custom settings'
+ click_on 'Use default settings'
+
+ expect(page).not_to have_button('Use custom settings')
+ expect(page).to have_field('URL', with: parent_settings[:url], readonly: true)
+ expect(page).to have_field('Enter new password or API token', with: '', readonly: true)
+
+ click_save_integration
+
+ expect(page).to have_text('Jira settings saved and active.')
+ expect(integration.reload).to have_attributes(
+ inherit_from_id: parent_integration.id,
+ **parent_settings
+ )
+ end
+ end
+ end
+
+ context 'with instance settings' do
+ let_it_be(:parent_settings) { { url: 'http://instance.com', password: 'instance' } }
+ let_it_be(:parent_integration) { create(:jira_integration, :instance, **parent_settings) }
+
+ it_behaves_like 'inherited settings'
+ end
+
+ context 'with group settings' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group) }
+ let_it_be(:parent_settings) { { url: 'http://group.com', password: 'group' } }
+ let_it_be(:parent_integration) { create(:jira_integration, group: group, project: nil, **parent_settings) }
+
+ it_behaves_like 'inherited settings'
+ end
+end
diff --git a/spec/features/projects/members/invite_group_spec.rb b/spec/features/projects/members/invite_group_spec.rb
index 6ce6834b5d5..8c3646125a5 100644
--- a/spec/features/projects/members/invite_group_spec.rb
+++ b/spec/features/projects/members/invite_group_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe 'Project > Members > Invite group', :js do
using RSpec::Parameterized::TableSyntax
where(:invite_members_group_modal_enabled, :expected_invite_group_selector) do
- true | 'button[data-qa-selector="invite_a_group_button"]'
+ true | 'button[data-qa-selector="invite_a_group_button"]' # rubocop:disable QA/SelectorUsage
false | '#invite-group-tab'
end
@@ -43,7 +43,7 @@ RSpec.describe 'Project > Members > Invite group', :js do
end
describe 'Share with group lock' do
- let(:invite_group_selector) { 'button[data-qa-selector="invite_a_group_button"]' }
+ let(:invite_group_selector) { 'button[data-qa-selector="invite_a_group_button"]' } # rubocop:disable QA/SelectorUsage
shared_examples 'the project can be shared with groups' do
it 'the "Invite a group" button exists' do
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index ef28979798f..0b293970703 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -6,374 +6,352 @@ 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
- let(:user) { create(:user) }
+ context 'as a user' do
+ let(:user) { create(:user) }
- before do
- sign_in(user)
- end
+ before do
+ sign_in(user)
+ end
- it 'shows a message if multiple levels are restricted' do
- Gitlab::CurrentSettings.update!(
- restricted_visibility_levels: [Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::INTERNAL]
- )
+ it 'shows a message if multiple levels are restricted' do
+ Gitlab::CurrentSettings.update!(
+ restricted_visibility_levels: [Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::INTERNAL]
+ )
- visit new_project_path
- find('[data-qa-panel-name="blank_project"]').click
+ visit new_project_path
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
- expect(page).to have_content 'Other visibility settings have been disabled by the administrator.'
- end
+ expect(page).to have_content 'Other visibility settings have been disabled by the administrator.'
+ end
- it 'shows a message if all levels are restricted' do
- Gitlab::CurrentSettings.update!(
- restricted_visibility_levels: Gitlab::VisibilityLevel.values
- )
+ it 'shows a message if all levels are restricted' do
+ Gitlab::CurrentSettings.update!(
+ restricted_visibility_levels: Gitlab::VisibilityLevel.values
+ )
- visit new_project_path
- find('[data-qa-panel-name="blank_project"]').click
+ visit new_project_path
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
- expect(page).to have_content 'Visibility settings have been disabled by the administrator.'
- end
+ expect(page).to have_content 'Visibility settings have been disabled by the administrator.'
end
+ end
- context 'as an admin' do
- let(:user) { create(:admin) }
+ context 'as an admin' do
+ let(:user) { create(:admin) }
- before do
- sign_in(user)
- end
+ before do
+ sign_in(user)
+ end
- it 'shows "New project" page', :js do
- visit new_project_path
- find('[data-qa-panel-name="blank_project"]').click
+ it 'shows "New project" page', :js do
+ visit new_project_path
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
- expect(page).to have_content('Project name')
- expect(page).to have_content('Project URL')
- expect(page).to have_content('Project slug')
+ expect(page).to have_content('Project name')
+ expect(page).to have_content('Project URL')
+ expect(page).to have_content('Project slug')
- click_link('New project')
- find('[data-qa-panel-name="import_project"]').click
+ click_link('New project')
+ find('[data-qa-panel-name="import_project"]').click # rubocop:disable QA/SelectorUsage
- expect(page).to have_link('GitHub')
- expect(page).to have_link('Bitbucket')
- expect(page).to have_link('GitLab.com')
- expect(page).to have_button('Repo by URL')
- expect(page).to have_link('GitLab export')
- end
+ expect(page).to have_link('GitHub')
+ expect(page).to have_link('Bitbucket')
+ expect(page).to have_link('GitLab.com')
+ expect(page).to have_button('Repo by URL')
+ expect(page).to have_link('GitLab export')
+ end
- describe 'manifest import option' do
- before do
- visit new_project_path
+ describe 'manifest import option' do
+ before do
+ visit new_project_path
- find('[data-qa-panel-name="import_project"]').click
- end
+ find('[data-qa-panel-name="import_project"]').click # rubocop:disable QA/SelectorUsage
+ end
- it 'has Manifest file' do
- expect(page).to have_link('Manifest file')
- end
+ it 'has Manifest file' do
+ expect(page).to have_link('Manifest file')
end
+ end
- context 'Visibility level selector', :js do
- Gitlab::VisibilityLevel.options.each do |key, level|
- it "sets selector to #{key}" do
- stub_application_setting(default_project_visibility: level)
+ context 'Visibility level selector', :js do
+ Gitlab::VisibilityLevel.options.each do |key, level|
+ it "sets selector to #{key}" do
+ stub_application_setting(default_project_visibility: level)
- visit new_project_path
- find('[data-qa-panel-name="blank_project"]').click
- page.within('#blank-project-pane') do
- expect(find_field("project_visibility_level_#{level}")).to be_checked
- end
+ visit new_project_path
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
+ page.within('#blank-project-pane') do
+ expect(find_field("project_visibility_level_#{level}")).to be_checked
end
+ end
- it "saves visibility level #{level} on validation error" do
- visit new_project_path
- find('[data-qa-panel-name="blank_project"]').click
+ it "saves visibility level #{level} on validation error" do
+ visit new_project_path
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
- choose(key)
- click_button('Create project')
- page.within('#blank-project-pane') do
- expect(find_field("project_visibility_level_#{level}")).to be_checked
- end
+ choose(key)
+ click_button('Create project')
+ page.within('#blank-project-pane') do
+ expect(find_field("project_visibility_level_#{level}")).to be_checked
end
end
+ end
- context 'when group visibility is private but default is internal' do
- let_it_be(:group) { create(:group, visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
+ context 'when group visibility is private but default is internal' do
+ let_it_be(:group) { create(:group, visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
- before do
- stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
- end
+ before do
+ stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
+ end
- context 'when admin mode is enabled', :enable_admin_mode do
- it 'has private selected' do
- visit new_project_path(namespace_id: group.id)
- find('[data-qa-panel-name="blank_project"]').click
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it 'has private selected' do
+ visit new_project_path(namespace_id: group.id)
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
- page.within('#blank-project-pane') do
- expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
- end
+ page.within('#blank-project-pane') do
+ expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
end
end
+ end
- context 'when admin mode is disabled' do
- it 'is not allowed' do
- visit new_project_path(namespace_id: group.id)
+ context 'when admin mode is disabled' do
+ it 'is not allowed' do
+ visit new_project_path(namespace_id: group.id)
- expect(page).to have_content('Not Found')
- end
+ expect(page).to have_content('Not Found')
end
end
+ end
- context 'when group visibility is public but user requests private' do
- let_it_be(:group) { create(:group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ context 'when group visibility is public but user requests private' do
+ let_it_be(:group) { create(:group, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
- before do
- stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
- end
+ before do
+ stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
+ end
- context 'when admin mode is enabled', :enable_admin_mode do
- it 'has private selected' do
- visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
- find('[data-qa-panel-name="blank_project"]').click
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it 'has private selected' do
+ visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
- page.within('#blank-project-pane') do
- expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
- end
+ page.within('#blank-project-pane') do
+ expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
end
end
+ end
- context 'when admin mode is disabled' do
- it 'is not allowed' do
- visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
+ context 'when admin mode is disabled' do
+ it 'is not allowed' do
+ visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
- expect(page).to have_content('Not Found')
- end
+ expect(page).to have_content('Not Found')
end
end
end
+ end
- context 'Readme selector' do
- it 'shows the initialize with Readme checkbox on "Blank project" tab' do
- visit new_project_path
- find('[data-qa-panel-name="blank_project"]').click
+ context 'Readme selector' do
+ it 'shows the initialize with Readme checkbox on "Blank project" tab' do
+ visit new_project_path
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
- expect(page).to have_css('input#project_initialize_with_readme')
- expect(page).to have_content('Initialize repository with a README')
- end
+ expect(page).to have_css('input#project_initialize_with_readme')
+ expect(page).to have_content('Initialize repository with a README')
+ end
- it 'does not show the initialize with Readme checkbox on "Create from template" tab' do
- visit new_project_path
- find('[data-qa-panel-name="create_from_template"]').click
- first('.choose-template').click
+ it 'does not show the initialize with Readme checkbox on "Create from template" tab' do
+ visit new_project_path
+ find('[data-qa-panel-name="create_from_template"]').click # rubocop:disable QA/SelectorUsage
+ first('.choose-template').click
- page.within '.project-fields-form' do
- expect(page).not_to have_css('input#project_initialize_with_readme')
- expect(page).not_to have_content('Initialize repository with a README')
- end
+ page.within '.project-fields-form' do
+ expect(page).not_to have_css('input#project_initialize_with_readme')
+ expect(page).not_to have_content('Initialize repository with a README')
end
+ end
- it 'does not show the initialize with Readme checkbox on "Import project" tab' do
- visit new_project_path
- find('[data-qa-panel-name="import_project"]').click
- first('.js-import-git-toggle-button').click
+ it 'does not show the initialize with Readme checkbox on "Import project" tab' do
+ visit new_project_path
+ find('[data-qa-panel-name="import_project"]').click # rubocop:disable QA/SelectorUsage
+ first('.js-import-git-toggle-button').click
- page.within '#import-project-pane' do
- expect(page).not_to have_css('input#project_initialize_with_readme')
- expect(page).not_to have_content('Initialize repository with a README')
- end
+ page.within '#import-project-pane' do
+ expect(page).not_to have_css('input#project_initialize_with_readme')
+ expect(page).not_to have_content('Initialize repository with a README')
end
end
+ end
- context 'Namespace selector' do
- context 'with user namespace' do
- before do
- visit new_project_path
- find('[data-qa-panel-name="blank_project"]').click
- end
+ context 'Namespace selector' do
+ context 'with user namespace' do
+ before do
+ visit new_project_path
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
+ end
- it 'selects the user namespace' do
- page.within('#blank-project-pane') do
- expect(page).to have_select('project[namespace_id]', visible: false, selected: user.username)
- end
+ it 'selects the user namespace' do
+ page.within('#blank-project-pane') do
+ expect(page).to have_select('project[namespace_id]', visible: false, selected: user.username)
end
end
+ end
- context 'with group namespace' do
- let(:group) { create(:group, :private) }
+ context 'with group namespace' do
+ let(:group) { create(:group, :private) }
- before do
- group.add_owner(user)
- visit new_project_path(namespace_id: group.id)
- find('[data-qa-panel-name="blank_project"]').click
- end
+ before do
+ group.add_owner(user)
+ visit new_project_path(namespace_id: group.id)
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
+ end
- it 'selects the group namespace' do
- page.within('#blank-project-pane') do
- expect(page).to have_select('project[namespace_id]', visible: false, selected: group.name)
- end
+ it 'selects the group namespace' do
+ page.within('#blank-project-pane') do
+ expect(page).to have_select('project[namespace_id]', visible: false, selected: group.name)
end
end
+ end
- context 'with subgroup namespace' do
- let(:group) { create(:group) }
- let(:subgroup) { create(:group, parent: group) }
-
- before do
- group.add_maintainer(user)
- visit new_project_path(namespace_id: subgroup.id)
- find('[data-qa-panel-name="blank_project"]').click
- end
+ context 'with subgroup namespace' do
+ let(:group) { create(:group) }
+ let(:subgroup) { create(:group, parent: group) }
- it 'selects the group namespace' do
- page.within('#blank-project-pane') do
- expect(page).to have_select('project[namespace_id]', visible: false, selected: subgroup.full_path)
- end
- end
+ before do
+ group.add_maintainer(user)
+ visit new_project_path(namespace_id: subgroup.id)
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
end
- context 'when changing namespaces dynamically', :js do
- let(:public_group) { create(:group, :public) }
- let(:internal_group) { create(:group, :internal) }
- let(:private_group) { create(:group, :private) }
-
- before do
- public_group.add_owner(user)
- internal_group.add_owner(user)
- private_group.add_owner(user)
- visit new_project_path(namespace_id: public_group.id)
- find('[data-qa-panel-name="blank_project"]').click
- end
-
- it 'enables the correct visibility options' do
- select2(user.namespace_id, from: '#project_namespace_id')
- expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
- expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
- expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled
-
- select2(public_group.id, from: '#project_namespace_id')
- expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
- expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
- expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled
-
- select2(internal_group.id, from: '#project_namespace_id')
- expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
- expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
- expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled
-
- select2(private_group.id, from: '#project_namespace_id')
- expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
- expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).to be_disabled
- expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled
+ it 'selects the group namespace' do
+ page.within('#blank-project-pane') do
+ expect(page).to have_select('project[namespace_id]', visible: false, selected: subgroup.full_path)
end
end
end
- context 'Import project options', :js do
+ context 'when changing namespaces dynamically', :js do
+ let(:public_group) { create(:group, :public) }
+ let(:internal_group) { create(:group, :internal) }
+ let(:private_group) { create(:group, :private) }
+
before do
- visit new_project_path
- find('[data-qa-panel-name="import_project"]').click
+ public_group.add_owner(user)
+ internal_group.add_owner(user)
+ private_group.add_owner(user)
+ visit new_project_path(namespace_id: public_group.id)
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
end
- context 'from git repository url, "Repo by URL"' do
- before do
- first('.js-import-git-toggle-button').click
- end
-
- it 'does not autocomplete sensitive git repo URL' do
- autocomplete = find('#project_import_url')['autocomplete']
-
- expect(autocomplete).to eq('off')
- end
+ it 'enables the correct visibility options' do
+ select2(user.namespace_id, from: '#project_namespace_id')
+ expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
+ expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
+ expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled
+
+ select2(public_group.id, from: '#project_namespace_id')
+ expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
+ expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
+ expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).not_to be_disabled
+
+ select2(internal_group.id, from: '#project_namespace_id')
+ expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
+ expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).not_to be_disabled
+ expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled
+
+ select2(private_group.id, from: '#project_namespace_id')
+ expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).not_to be_disabled
+ expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::INTERNAL}")).to be_disabled
+ expect(find("#project_visibility_level_#{Gitlab::VisibilityLevel::PUBLIC}")).to be_disabled
+ end
+ end
+ end
- it 'shows import instructions' do
- git_import_instructions = first('.js-toggle-content')
+ context 'Import project options', :js do
+ before do
+ visit new_project_path
+ find('[data-qa-panel-name="import_project"]').click # rubocop:disable QA/SelectorUsage
+ end
- expect(git_import_instructions).to be_visible
- expect(git_import_instructions).to have_content 'Git repository URL'
- end
+ context 'from git repository url, "Repo by URL"' do
+ before do
+ first('.js-import-git-toggle-button').click
+ end
- it 'reports error if repo URL does not end with .git' do
- fill_in 'project_import_url', with: 'http://foo/bar'
- # simulate blur event
- find('body').click
+ it 'does not autocomplete sensitive git repo URL' do
+ autocomplete = find('#project_import_url')['autocomplete']
- expect(page).to have_text('A repository URL usually ends in a .git suffix')
- end
+ expect(autocomplete).to eq('off')
+ end
- it 'keeps "Import project" tab open after form validation error' do
- collision_project = create(:project, name: 'test-name-collision', namespace: user.namespace)
+ it 'shows import instructions' do
+ git_import_instructions = first('.js-toggle-content')
- fill_in 'project_import_url', with: collision_project.http_url_to_repo
- fill_in 'project_name', with: collision_project.name
+ expect(git_import_instructions).to be_visible
+ expect(git_import_instructions).to have_content 'Git repository URL'
+ end
- click_on 'Create project'
+ it 'reports error if repo URL does not end with .git' do
+ fill_in 'project_import_url', with: 'http://foo/bar'
+ # simulate blur event
+ find('body').click
- expect(page).to have_css('#import-project-pane.active')
- expect(page).not_to have_css('.toggle-import-form.hide')
- end
+ expect(page).to have_text('A repository URL usually ends in a .git suffix')
end
- context 'from GitHub' do
- before do
- first('.js-import-github').click
- end
+ it 'keeps "Import project" tab open after form validation error' do
+ collision_project = create(:project, name: 'test-name-collision', namespace: user.namespace)
- it 'shows import instructions' do
- expect(page).to have_content('Authenticate with GitHub')
- expect(current_path).to eq new_import_github_path
- end
- end
+ fill_in 'project_import_url', with: collision_project.http_url_to_repo
+ fill_in 'project_name', with: collision_project.name
- context 'from manifest file' do
- before do
- first('.import_manifest').click
- end
+ click_on 'Create project'
- it 'shows import instructions' do
- expect(page).to have_content('Manifest file import')
- expect(current_path).to eq new_import_manifest_path
- end
+ expect(page).to have_css('#import-project-pane.active')
+ expect(page).not_to have_css('.toggle-import-form.hide')
end
end
- context 'Namespace selector' do
- context 'with group with DEVELOPER_MAINTAINER_PROJECT_ACCESS project_creation_level' do
- let(:group) { create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) }
-
- before do
- group.add_developer(user)
- visit new_project_path(namespace_id: group.id)
- find('[data-qa-panel-name="blank_project"]').click
- end
+ context 'from GitHub' do
+ before do
+ first('.js-import-github').click
+ end
- it 'selects the group namespace' do
- page.within('#blank-project-pane') do
- expect(page).to have_select('project[namespace_id]', visible: false, selected: group.full_path)
- end
- end
+ it 'shows import instructions' do
+ expect(page).to have_content('Authenticate with GitHub')
+ expect(current_path).to eq new_import_github_path
end
end
- end
- end
- context 'with combined_menu feature flag on' do
- let(:needs_rewrite_for_combined_menu_flag_on) { true }
+ context 'from manifest file' do
+ before do
+ first('.import_manifest').click
+ end
- before do
- stub_feature_flags(combined_menu: true)
+ it 'shows import instructions' do
+ expect(page).to have_content('Manifest file import')
+ expect(current_path).to eq new_import_manifest_path
+ end
+ end
end
- it_behaves_like 'combined_menu: feature flag examples'
- end
+ context 'Namespace selector' do
+ context 'with group with DEVELOPER_MAINTAINER_PROJECT_ACCESS project_creation_level' do
+ let(:group) { create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) }
- context 'with combined_menu feature flag off' do
- let(:needs_rewrite_for_combined_menu_flag_on) { false }
+ before do
+ group.add_developer(user)
+ visit new_project_path(namespace_id: group.id)
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
+ end
- before do
- stub_feature_flags(combined_menu: false)
+ it 'selects the group namespace' do
+ page.within('#blank-project-pane') do
+ expect(page).to have_select('project[namespace_id]', visible: false, selected: group.full_path)
+ end
+ end
+ end
end
-
- it_behaves_like 'combined_menu: feature flag examples'
end
end
diff --git a/spec/features/projects/packages_spec.rb b/spec/features/projects/packages_spec.rb
index fa4c57c305d..30298f79312 100644
--- a/spec/features/projects/packages_spec.rb
+++ b/spec/features/projects/packages_spec.rb
@@ -45,6 +45,8 @@ RSpec.describe 'Packages' do
it_behaves_like 'package details link'
end
+ it_behaves_like 'package details link'
+
context 'deleting a package' do
let_it_be(:project) { create(:project) }
let_it_be(:package) { create(:package, project: project) }
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index ce2083b397a..944cee2a998 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -240,10 +240,14 @@ RSpec.describe 'Pipeline', :js do
end
end
- it 'is possible to retry the success job' do
+ it 'is possible to retry the success job', :sidekiq_might_not_need_inline do
find('#ci-badge-build .ci-action-icon-container').click
+ wait_for_requests
expect(page).not_to have_content('Retry job')
+ within('.js-pipeline-header-container') do
+ expect(page).to have_selector('.js-ci-status-icon-running')
+ end
end
end
@@ -282,10 +286,14 @@ RSpec.describe 'Pipeline', :js do
end
end
- it 'is possible to retry the failed build' do
+ it 'is possible to retry the failed build', :sidekiq_might_not_need_inline do
find('#ci-badge-test .ci-action-icon-container').click
+ wait_for_requests
expect(page).not_to have_content('Retry job')
+ within('.js-pipeline-header-container') do
+ expect(page).to have_selector('.js-ci-status-icon-running')
+ end
end
it 'includes the failure reason' do
@@ -308,10 +316,14 @@ RSpec.describe 'Pipeline', :js do
end
end
- it 'is possible to play the manual job' do
+ it 'is possible to play the manual job', :sidekiq_might_not_need_inline do
find('#ci-badge-manual-build .ci-action-icon-container').click
+ wait_for_requests
expect(page).not_to have_content('Play job')
+ within('.js-pipeline-header-container') do
+ expect(page).to have_selector('.js-ci-status-icon-running')
+ end
end
end
@@ -411,11 +423,18 @@ RSpec.describe 'Pipeline', :js do
context 'when retrying' do
before do
find('[data-testid="retryPipeline"]').click
+ wait_for_requests
end
it 'does not show a "Retry" button', :sidekiq_might_not_need_inline do
expect(page).not_to have_content('Retry')
end
+
+ it 'shows running status in pipeline header', :sidekiq_might_not_need_inline do
+ within('.js-pipeline-header-container') do
+ expect(page).to have_selector('.js-ci-status-icon-running')
+ end
+ end
end
end
@@ -437,44 +456,28 @@ RSpec.describe 'Pipeline', :js do
end
end
- shared_context 'delete pipeline' do
- context 'deleting pipeline' do
- context 'when user can not delete' do
- before do
- visit_pipeline
- end
-
- it { expect(page).not_to have_button('Delete') }
- end
-
- context 'when deleting' do
- before do
- group.add_owner(user)
-
- visit_pipeline
-
- click_button 'Delete'
- click_button 'Delete pipeline'
- end
-
- it 'redirects to pipeline overview page', :sidekiq_inline do
- expect(page).to have_content('The pipeline has been deleted')
- expect(current_path).to eq(project_pipelines_path(project))
- end
- end
+ context 'when user can not delete' do
+ before do
+ visit_pipeline
end
- end
- context 'when cancel_pipelines_prior_to_destroy is enabled' do
- include_context 'delete pipeline'
+ it { expect(page).not_to have_button('Delete') }
end
- context 'when cancel_pipelines_prior_to_destroy is disabled' do
+ context 'when deleting' do
before do
- stub_feature_flags(cancel_pipelines_prior_to_destroy: false)
+ group.add_owner(user)
+
+ visit_pipeline
+
+ click_button 'Delete'
+ click_button 'Delete pipeline'
end
- include_context 'delete pipeline'
+ it 'redirects to pipeline overview page', :sidekiq_inline do
+ expect(page).to have_content('The pipeline has been deleted')
+ expect(current_path).to eq(project_pipelines_path(project))
+ end
end
context 'when pipeline ref does not exist in repository anymore' do
@@ -775,65 +778,10 @@ RSpec.describe 'Pipeline', :js do
describe 'GET /:project/-/pipelines/:id' do
subject { visit project_pipeline_path(project, pipeline) }
- # remove when :graphql_pipeline_details flag is removed
- # https://gitlab.com/gitlab-org/gitlab/-/issues/299112
- context 'when :graphql_pipeline_details flag is off' do
- before do
- stub_feature_flags(graphql_pipeline_details: false)
- stub_feature_flags(graphql_pipeline_details_users: false)
- end
-
- it 'shows deploy job as created' do
- subject
-
- within('.pipeline-header-container') do
- expect(page).to have_content('pending')
- end
-
- within('.js-pipeline-graph') do
- within '.stage-column:nth-child(1)' do
- expect(page).to have_content('test')
- expect(page).to have_css('.ci-status-icon-pending')
- end
-
- within '.stage-column:nth-child(2)' do
- expect(page).to have_content('deploy')
- expect(page).to have_css('.ci-status-icon-created')
- end
- end
- end
-
- context 'when test job succeeded' do
- before do
- test_job.success!
- end
-
- it 'shows deploy job as pending' do
- subject
-
- within('.pipeline-header-container') do
- expect(page).to have_content('running')
- end
-
- within('.pipeline-graph') do
- within '.stage-column:nth-child(1)' do
- expect(page).to have_content('test')
- expect(page).to have_css('.ci-status-icon-success')
- end
-
- within '.stage-column:nth-child(2)' do
- expect(page).to have_content('deploy')
- expect(page).to have_css('.ci-status-icon-pending')
- end
- end
- end
- end
- end
-
it 'shows deploy job as created' do
subject
- within('.pipeline-header-container') do
+ within('.js-pipeline-header-container') do
expect(page).to have_content('pending')
end
@@ -858,7 +806,7 @@ RSpec.describe 'Pipeline', :js do
it 'shows deploy job as pending' do
subject
- within('.pipeline-header-container') do
+ within('.js-pipeline-header-container') do
expect(page).to have_content('running')
end
@@ -887,7 +835,7 @@ RSpec.describe 'Pipeline', :js do
it 'shows deploy job as waiting for resource' do
subject
- within('.pipeline-header-container') do
+ within('.js-pipeline-header-container') do
expect(page).to have_content('waiting')
end
@@ -899,29 +847,6 @@ RSpec.describe 'Pipeline', :js do
end
end
- # remove when :graphql_pipeline_details flag is removed
- # https://gitlab.com/gitlab-org/gitlab/-/issues/299112
- context 'when :graphql_pipeline_details flag is off' do
- before do
- stub_feature_flags(graphql_pipeline_details: false)
- stub_feature_flags(graphql_pipeline_details_users: false)
- end
- it 'shows deploy job as waiting for resource' do
- subject
-
- within('.pipeline-header-container') do
- expect(page).to have_content('waiting')
- end
-
- within('.pipeline-graph') do
- within '.stage-column:nth-child(2)' do
- expect(page).to have_content('deploy')
- expect(page).to have_css('.ci-status-icon-waiting-for-resource')
- end
- end
- end
- end
-
context 'when resource is released from another job' do
before do
another_job.success!
@@ -930,7 +855,7 @@ RSpec.describe 'Pipeline', :js do
it 'shows deploy job as pending' do
subject
- within('.pipeline-header-container') do
+ within('.js-pipeline-header-container') do
expect(page).to have_content('running')
end
@@ -941,29 +866,6 @@ RSpec.describe 'Pipeline', :js do
end
end
end
-
- # remove when :graphql_pipeline_details flag is removed
- # https://gitlab.com/gitlab-org/gitlab/-/issues/299112
- context 'when :graphql_pipeline_details flag is off' do
- before do
- stub_feature_flags(graphql_pipeline_details: false)
- stub_feature_flags(graphql_pipeline_details_users: false)
- end
- it 'shows deploy job as pending' do
- subject
-
- within('.pipeline-header-container') do
- expect(page).to have_content('running')
- end
-
- within('.pipeline-graph') do
- within '.stage-column:nth-child(2)' do
- expect(page).to have_content('deploy')
- expect(page).to have_css('.ci-status-icon-pending')
- end
- end
- end
- end
end
context 'when deploy job is a bridge to trigger a downstream pipeline' do
@@ -975,7 +877,7 @@ RSpec.describe 'Pipeline', :js do
it 'shows deploy job as waiting for resource' do
subject
- within('.pipeline-header-container') do
+ within('.js-pipeline-header-container') do
expect(page).to have_content('waiting')
end
@@ -997,7 +899,7 @@ RSpec.describe 'Pipeline', :js do
it 'shows deploy job as waiting for resource' do
subject
- within('.pipeline-header-container') do
+ within('.js-pipeline-header-container') do
expect(page).to have_content('waiting')
end
@@ -1231,23 +1133,6 @@ RSpec.describe 'Pipeline', :js do
expect(page).not_to have_content('Failed Jobs')
expect(page).to have_selector('.js-pipeline-graph')
end
-
- # remove when :graphql_pipeline_details flag is removed
- # https://gitlab.com/gitlab-org/gitlab/-/issues/299112
- context 'when :graphql_pipeline_details flag is off' do
- before do
- stub_feature_flags(graphql_pipeline_details: false)
- stub_feature_flags(graphql_pipeline_details_users: false)
- end
-
- it 'displays the pipeline graph' do
- subject
-
- expect(current_path).to eq(pipeline_path(pipeline))
- expect(page).not_to have_content('Failed Jobs')
- expect(page).to have_selector('.pipeline-visualization')
- end
- end
end
end
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 1de0eea4657..bd22c8632e4 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -12,8 +12,6 @@ RSpec.describe 'Pipelines', :js do
before do
sign_in(user)
- stub_feature_flags(graphql_pipeline_details: false)
- stub_feature_flags(graphql_pipeline_details_users: false)
project.add_developer(user)
project.update!(auto_devops_attributes: { enabled: false })
@@ -585,6 +583,26 @@ RSpec.describe 'Pipelines', :js do
expect(page).to have_selector('.gl-pagination .page-link', count: 4)
end
end
+
+ context 'with pipeline key selection' do
+ before do
+ visit project_pipelines_path(project)
+ wait_for_requests
+ end
+
+ it 'changes the Pipeline ID column for Pipeline IID' do
+ page.find('[data-testid="pipeline-key-dropdown"]').click
+
+ within '.gl-new-dropdown-contents' do
+ dropdown_options = page.find_all '.gl-new-dropdown-item'
+
+ dropdown_options[1].click
+ end
+
+ expect(page.find('[data-testid="pipeline-th"]')).to have_content 'Pipeline IID'
+ expect(page.find('[data-testid="pipeline-url-link"]')).to have_content "##{pipeline.iid}"
+ end
+ end
end
describe 'GET /:project/-/pipelines/show' do
diff --git a/spec/features/projects/services/user_activates_irker_spec.rb b/spec/features/projects/services/user_activates_irker_spec.rb
index e4d92dc30ff..004aa116bb3 100644
--- a/spec/features/projects/services/user_activates_irker_spec.rb
+++ b/spec/features/projects/services/user_activates_irker_spec.rb
@@ -2,16 +2,16 @@
require 'spec_helper'
-RSpec.describe 'User activates Irker (IRC gateway)' do
+RSpec.describe 'User activates irker (IRC gateway)' do
include_context 'project service activation'
it 'activates service', :js do
- visit_project_integration('Irker (IRC gateway)')
+ visit_project_integration('irker (IRC gateway)')
check('Colorize messages')
fill_in('Recipients', with: 'irc://chat.freenode.net/#commits')
click_test_then_save_integration(expect_test_to_fail: false)
- expect(page).to have_content('Irker (IRC gateway) settings saved and active.')
+ expect(page).to have_content('irker (IRC gateway) settings saved and active.')
end
end
diff --git a/spec/features/projects/services/user_activates_pushover_spec.rb b/spec/features/projects/services/user_activates_pushover_spec.rb
index 97003ab7c2a..d92f69e700a 100644
--- a/spec/features/projects/services/user_activates_pushover_spec.rb
+++ b/spec/features/projects/services/user_activates_pushover_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe 'User activates Pushover' do
fill_in('API key', with: 'verySecret')
fill_in('User key', with: 'verySecret')
fill_in('Device', with: 'myDevice')
- select('High Priority', from: 'Priority')
+ select('High priority', from: 'Priority')
select('Bike', from: 'Sound')
click_test_then_save_integration(expect_test_to_fail: false)
diff --git a/spec/features/projects/services/user_views_services_spec.rb b/spec/features/projects/services/user_views_services_spec.rb
index b936a7f38f6..201a58ba379 100644
--- a/spec/features/projects/services/user_views_services_spec.rb
+++ b/spec/features/projects/services/user_views_services_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe 'User views services', :js do
expect(page).to have_content('Atlassian Bamboo')
expect(page).to have_content('JetBrains TeamCity')
expect(page).to have_content('Asana')
- expect(page).to have_content('Irker (IRC gateway)')
+ expect(page).to have_content('irker (IRC gateway)')
expect(page).to have_content('Packagist')
end
end
diff --git a/spec/features/projects/settings/registry_settings_spec.rb b/spec/features/projects/settings/registry_settings_spec.rb
index 3f9f2dae453..509729d526d 100644
--- a/spec/features/projects/settings/registry_settings_spec.rb
+++ b/spec/features/projects/settings/registry_settings_spec.rb
@@ -9,12 +9,12 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
let_it_be(:project, reload: true) { create(:project, namespace: user.namespace) }
let(:container_registry_enabled) { true }
- let(:container_registry_enabled_on_project) { true }
+ let(:container_registry_enabled_on_project) { ProjectFeature::ENABLED }
subject { visit project_settings_packages_and_registries_path(project) }
before do
- project.update!(container_registry_enabled: container_registry_enabled_on_project)
+ project.project_feature.update!(container_registry_access_level: container_registry_enabled_on_project)
project.container_expiration_policy.update!(enabled: true)
sign_in(user)
@@ -104,7 +104,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
end
context 'when container registry is disabled on project' do
- let(:container_registry_enabled_on_project) { false }
+ let(:container_registry_enabled_on_project) { ProjectFeature::DISABLED }
it 'does not exists' do
subject
diff --git a/spec/features/projects/show/schema_markup_spec.rb b/spec/features/projects/show/schema_markup_spec.rb
index 28803db924a..8adbdb64f1b 100644
--- a/spec/features/projects/show/schema_markup_spec.rb
+++ b/spec/features/projects/show/schema_markup_spec.rb
@@ -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.topic_list.map(&:capitalize))
+ expect(find_all('[itemprop="keywords"]').map(&:text)).to match_array(project.topic_list)
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 613033373e8..552f068ecc7 100644
--- a/spec/features/projects/show/user_sees_collaboration_links_spec.rb
+++ b/spec/features/projects/show/user_sees_collaboration_links_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js do
# The dropdown above the tree
page.within('.repo-breadcrumb') do
- find('.qa-add-to-tree').click
+ find('.qa-add-to-tree').click # rubocop:disable QA/SelectorUsage
aggregate_failures 'dropdown links above the repo tree' do
expect(page).to have_link('New file')
@@ -71,7 +71,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js do
find_new_menu_toggle.click
end
- expect(page).not_to have_selector('.qa-add-to-tree')
+ expect(page).not_to have_selector('.qa-add-to-tree') # rubocop:disable QA/SelectorUsage
expect(page).not_to have_link('Web IDE')
end
diff --git a/spec/features/projects/tags/user_edits_tags_spec.rb b/spec/features/projects/tags/user_edits_tags_spec.rb
index 7a8a685f3d9..9f66b7274e8 100644
--- a/spec/features/projects/tags/user_edits_tags_spec.rb
+++ b/spec/features/projects/tags/user_edits_tags_spec.rb
@@ -55,7 +55,7 @@ RSpec.describe 'Project > Tags', :js do
note_textarea = page.find('.js-gfm-input')
# Click on Bold button
- page.find('.md-header-toolbar button.toolbar-btn:first-child').click
+ page.find('.md-header-toolbar button:first-child').click
expect(note_textarea.value).to eq('****')
end
diff --git a/spec/features/projects/terraform_spec.rb b/spec/features/projects/terraform_spec.rb
index d080d101285..2c63f2bfc02 100644
--- a/spec/features/projects/terraform_spec.rb
+++ b/spec/features/projects/terraform_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe 'Terraform', :js do
it 'displays a table with terraform states' do
expect(page).to have_selector(
- '[data-testid="terraform-states-table-name"]',
+ "[data-testid='terraform-states-table-name']",
count: project.terraform_states.size
)
end
@@ -64,7 +64,7 @@ RSpec.describe 'Terraform', :js do
expect(page).to have_content(additional_state.name)
find("[data-testid='terraform-state-actions-#{additional_state.name}']").click
- find('[data-testid="terraform-state-remove"]').click
+ find("[data-testid='terraform-state-remove']").click
fill_in "terraform-state-remove-input-#{additional_state.name}", with: additional_state.name
click_button 'Remove'
@@ -72,6 +72,21 @@ RSpec.describe 'Terraform', :js do
expect { additional_state.reload }.to raise_error ActiveRecord::RecordNotFound
end
end
+
+ context 'when clicking on copy Terraform init command' do
+ it 'shows the modal with the init command' do
+ visit project_terraform_index_path(project)
+
+ expect(page).to have_content(terraform_state.name)
+
+ page.within("[data-testid='terraform-state-actions-#{terraform_state.name}']") do
+ click_button class: 'gl-dropdown-toggle'
+ click_button 'Copy Terraform init command'
+ end
+
+ expect(page).to have_content("To get access to this terraform state from your local computer, run the following command at the command line.")
+ end
+ end
end
end
@@ -87,11 +102,11 @@ RSpec.describe 'Terraform', :js do
context 'when user visits the index page' do
it 'displays a table without an action dropdown', :aggregate_failures do
expect(page).to have_selector(
- '[data-testid="terraform-states-table-name"]',
+ "[data-testid='terraform-states-table-name']",
count: project.terraform_states.size
)
- expect(page).not_to have_selector('[data-testid*="terraform-state-actions"]')
+ expect(page).not_to have_selector("[data-testid*='terraform-state-actions']")
end
end
end
diff --git a/spec/features/projects/tree/create_directory_spec.rb b/spec/features/projects/tree/create_directory_spec.rb
index e2ae858cb9b..f6127b38bd6 100644
--- a/spec/features/projects/tree/create_directory_spec.rb
+++ b/spec/features/projects/tree/create_directory_spec.rb
@@ -49,8 +49,8 @@ RSpec.describe 'Multi-file editor new directory', :js do
# Compact mode depends on the size of window. If it is shorter than MAX_WINDOW_HEIGHT_COMPACT,
# (as it is with WEBDRIVER_HEADLESS=0), this initial commit button will exist. Otherwise, if it is
# taller (as it is by default with chrome headless) then the button will not exist.
- if page.has_css?('.qa-begin-commit-button')
- find('.qa-begin-commit-button').click
+ if page.has_css?('.qa-begin-commit-button') # rubocop:disable QA/SelectorUsage
+ find('.qa-begin-commit-button').click # rubocop:disable QA/SelectorUsage
end
fill_in('commit-message', with: 'commit message ide')
diff --git a/spec/features/projects/tree/create_file_spec.rb b/spec/features/projects/tree/create_file_spec.rb
index 956b8898854..33be02a9121 100644
--- a/spec/features/projects/tree/create_file_spec.rb
+++ b/spec/features/projects/tree/create_file_spec.rb
@@ -39,8 +39,8 @@ RSpec.describe 'Multi-file editor new file', :js do
# Compact mode depends on the size of window. If it is shorter than MAX_WINDOW_HEIGHT_COMPACT,
# (as it is with WEBDRIVER_HEADLESS=0), this initial commit button will exist. Otherwise, if it is
# taller (as it is by default with chrome headless) then the button will not exist.
- if page.has_css?('.qa-begin-commit-button')
- find('.qa-begin-commit-button').click
+ if page.has_css?('.qa-begin-commit-button') # rubocop:disable QA/SelectorUsage
+ find('.qa-begin-commit-button').click # rubocop:disable QA/SelectorUsage
end
fill_in('commit-message', with: 'commit message ide')
diff --git a/spec/features/projects/tree/tree_show_spec.rb b/spec/features/projects/tree/tree_show_spec.rb
index ca9e0a23888..f8bbaa9535b 100644
--- a/spec/features/projects/tree/tree_show_spec.rb
+++ b/spec/features/projects/tree/tree_show_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe 'Projects tree', :js do
expect(page).to have_selector('.tree-item')
expect(page).to have_content('add tests for .gitattributes custom highlighting')
expect(page).not_to have_selector('.flash-alert')
- expect(page).not_to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS')
+ expect(page).not_to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS') # rubocop:disable QA/SelectorUsage
end
it 'renders tree table for a subtree without errors' do
@@ -35,7 +35,7 @@ RSpec.describe 'Projects tree', :js do
expect(page).to have_selector('.tree-item')
expect(page).to have_content('add spaces in whitespace file')
- expect(page).not_to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS')
+ expect(page).not_to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS') # rubocop:disable QA/SelectorUsage
expect(page).not_to have_selector('.flash-alert')
end
@@ -112,7 +112,7 @@ RSpec.describe 'Projects tree', :js do
it 'renders LFS badge on blob item' do
visit project_tree_path(project, File.join('master', 'files/lfs'))
- expect(page).to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS')
+ expect(page).to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS') # rubocop:disable QA/SelectorUsage
end
end
diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb
index a5b51bac747..2dc2f168896 100644
--- a/spec/features/projects/user_creates_project_spec.rb
+++ b/spec/features/projects/user_creates_project_spec.rb
@@ -8,17 +8,14 @@ RSpec.describe 'User creates a project', :js do
before do
sign_in(user)
create(:personal_key, user: user)
-
- stub_experiments(new_project_readme: :candidate)
end
it 'creates a new project' do
visit(new_project_path)
- find('[data-qa-panel-name="blank_project"]').click
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
fill_in(:project_name, with: 'Empty')
- # part of the new_project_readme experiment
expect(page).to have_checked_field 'Initialize repository with a README'
uncheck 'Initialize repository with a README'
@@ -46,7 +43,7 @@ RSpec.describe 'User creates a project', :js do
it 'creates a new project' do
visit(new_project_path)
- find('[data-qa-panel-name="blank_project"]').click
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
fill_in :project_name, with: 'A Subgroup Project'
fill_in :project_path, with: 'a-subgroup-project'
@@ -75,7 +72,7 @@ RSpec.describe 'User creates a project', :js do
it 'creates a new project' do
visit(new_project_path)
- find('[data-qa-panel-name="blank_project"]').click
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
fill_in :project_name, with: 'a-new-project'
fill_in :project_path, with: 'a-new-project'
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
index a3d134d49eb..59ad7d31ea7 100644
--- a/spec/features/projects_spec.rb
+++ b/spec/features/projects_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe 'Project' do
shared_examples 'creates from template' do |template, sub_template_tab = nil|
it "is created from template", :js do
- find('[data-qa-panel-name="create_from_template"]').click
+ find('[data-qa-panel-name="create_from_template"]').click # rubocop:disable QA/SelectorUsage
find(".project-template #{sub_template_tab}").click if sub_template_tab
find("label[for=#{template.name}]").click
fill_in("project_name", with: template.name)
@@ -132,8 +132,8 @@ RSpec.describe 'Project' do
visit path
- expect(page).to have_css('.home-panel-topic-list')
- expect(page).to have_link('Topic1', href: explore_projects_path(topic: 'topic1'))
+ expect(page).to have_selector('[data-testid="project_topic_list"]')
+ expect(page).to have_link('topic1', href: explore_projects_path(topic: 'topic1'))
end
it 'shows up to 3 project topics' do
@@ -141,10 +141,10 @@ RSpec.describe 'Project' do
visit path
- expect(page).to have_css('.home-panel-topic-list')
- expect(page).to have_link('Topic1', href: explore_projects_path(topic: 'topic1'))
- expect(page).to have_link('Topic2', href: explore_projects_path(topic: 'topic2'))
- expect(page).to have_link('Topic3', href: explore_projects_path(topic: 'topic3'))
+ expect(page).to have_selector('[data-testid="project_topic_list"]')
+ expect(page).to have_link('topic1', href: explore_projects_path(topic: 'topic1'))
+ expect(page).to have_link('topic2', href: explore_projects_path(topic: 'topic2'))
+ expect(page).to have_link('topic3', href: explore_projects_path(topic: 'topic3'))
expect(page).to have_content('+ 1 more')
end
end
@@ -290,7 +290,7 @@ RSpec.describe 'Project' do
it 'has working links to submodules' do
click_link('645f6c4c')
- expect(page).to have_selector('.qa-branches-select', text: '645f6c4c82fd3f5e06f67134450a570b795e55a6')
+ expect(page).to have_selector('.qa-branches-select', text: '645f6c4c82fd3f5e06f67134450a570b795e55a6') # rubocop:disable QA/SelectorUsage
end
context 'for signed commit on default branch', :js do
diff --git a/spec/features/registrations/welcome_spec.rb b/spec/features/registrations/welcome_spec.rb
deleted file mode 100644
index 74320b69f19..00000000000
--- a/spec/features/registrations/welcome_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'Welcome screen' do
- let(:user) { create(:user) }
-
- before do
- gitlab_sign_in(user)
-
- visit users_sign_up_welcome_path
- end
-
- it 'shows the email opt in' do
- select 'Software Developer', from: 'user_role'
- check 'user_email_opted_in'
- click_button 'Get started!'
-
- expect(user.reload.email_opted_in).to eq(true)
- end
-end
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index b61a769185e..22de77f7cd0 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -16,10 +16,10 @@ RSpec.describe 'Runners' do
project.add_maintainer(user)
end
- it 'user can see a button to install runners on kubernetes clusters' do
+ it 'user can see a link with instructions on how to install GitLab Runner' do
visit project_runners_path(project)
- expect(page).to have_link('Install GitLab Runner on Kubernetes', href: project_clusters_path(project))
+ expect(page).to have_link('Install GitLab Runner and ensure it\'s running.', href: "https://docs.gitlab.com/runner/install/")
end
end
@@ -343,12 +343,6 @@ RSpec.describe 'Runners' do
expect(page).to have_content 'No runners found'
end
-
- it 'user can see a link to install runners on kubernetes clusters' do
- visit group_settings_ci_cd_path(group)
-
- expect(page).to have_link('Install GitLab Runner on Kubernetes', href: group_clusters_path(group))
- end
end
context 'group with a runner' do
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 c002d199b01..8736f16b991 100644
--- a/spec/features/search/user_uses_header_search_field_spec.rb
+++ b/spec/features/search/user_uses_header_search_field_spec.rb
@@ -254,6 +254,7 @@ RSpec.describe 'User uses header search field', :js do
href = search_path(search: term)
href.concat("&project_id=#{project_id}") if project_id
href.concat("&group_id=#{group_id}") if group_id
+ href.concat("&nav_source=navbar")
".dropdown a[href='#{href}']"
end
diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb
index 0309df8f32a..fb2873f1c96 100644
--- a/spec/features/users/show_spec.rb
+++ b/spec/features/users/show_spec.rb
@@ -57,6 +57,56 @@ RSpec.describe 'User page' do
end
end
+ context 'location' do
+ let_it_be(:location) { 'San Francisco, CA' }
+
+ context 'when location is set' do
+ let_it_be(:user) { create(:user, location: location) }
+
+ it 'shows location' do
+ subject
+
+ expect(page).to have_content(location)
+ end
+ end
+
+ context 'when location is not set' do
+ it 'does not show location' do
+ subject
+
+ expect(page).not_to have_content(location)
+ end
+ end
+ end
+
+ context 'timezone' do
+ let_it_be(:timezone) { 'America/Los_Angeles' }
+
+ before do
+ travel_to Time.find_zone(timezone).local(2021, 7, 20, 15, 30, 45)
+ end
+
+ context 'when timezone is set' do
+ let_it_be(:user) { create(:user, timezone: timezone) }
+
+ it 'shows local time' do
+ subject
+
+ expect(page).to have_content('3:30 PM')
+ end
+ end
+
+ context 'when timezone is invalid' do
+ let_it_be(:user) { create(:user, timezone: 'Foo/Bar') }
+
+ it 'shows local time using the configured default timezone (UTC in this case)' do
+ subject
+
+ expect(page).to have_content('10:30 PM')
+ end
+ end
+ end
+
context 'follow/unfollow and followers/following' do
let_it_be(:followee) { create(:user) }
let_it_be(:follower) { create(:user) }
@@ -228,6 +278,14 @@ RSpec.describe 'User page' do
expect(page).to have_content("(they/them)")
end
+ it 'shows the pronunctiation of the user if there was one' do
+ user.user_detail.update_column(:pronunciation, 'pruh-nuhn-see-ay-shn')
+
+ subject
+
+ expect(page).to have_content("Pronounced as: pruh-nuhn-see-ay-shn")
+ end
+
context 'signup disabled' do
it 'shows the sign in link' do
stub_application_setting(signup_enabled: false)