Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Speicher <rspeicher@gmail.com>2021-01-20 22:34:23 +0300
committerRobert Speicher <rspeicher@gmail.com>2021-01-20 22:34:23 +0300
commit6438df3a1e0fb944485cebf07976160184697d72 (patch)
tree00b09bfd170e77ae9391b1a2f5a93ef6839f2597 /spec/features
parent42bcd54d971da7ef2854b896a7b34f4ef8601067 (diff)
Add latest changes from gitlab-org/gitlab@13-8-stable-eev13.8.0-rc42
Diffstat (limited to 'spec/features')
-rw-r--r--spec/features/admin/admin_groups_spec.rb1
-rw-r--r--spec/features/admin/admin_runners_spec.rb6
-rw-r--r--spec/features/admin/admin_settings_spec.rb31
-rw-r--r--spec/features/alert_management/user_filters_alerts_by_status_spec.rb1
-rw-r--r--spec/features/alert_management/user_searches_alerts_spec.rb1
-rw-r--r--spec/features/alert_management/user_updates_alert_status_spec.rb1
-rw-r--r--spec/features/dashboard/merge_requests_spec.rb6
-rw-r--r--spec/features/dashboard/projects_spec.rb2
-rw-r--r--spec/features/groups/board_spec.rb11
-rw-r--r--spec/features/groups/import_export/connect_instance_spec.rb2
-rw-r--r--spec/features/groups/members/manage_groups_spec.rb1
-rw-r--r--spec/features/groups/members/manage_members_spec.rb28
-rw-r--r--spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb1
-rw-r--r--spec/features/groups/members/master_manages_access_requests_spec.rb1
-rw-r--r--spec/features/groups/members/sort_members_spec.rb196
-rw-r--r--spec/features/groups/settings/ci_cd_spec.rb2
-rw-r--r--spec/features/groups/settings/packages_and_registries_spec.rb59
-rw-r--r--spec/features/incidents/incident_details_spec.rb2
-rw-r--r--spec/features/issues/gfm_autocomplete_spec.rb163
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb358
-rw-r--r--spec/features/issues/issue_state_spec.rb10
-rw-r--r--spec/features/issues/user_comments_on_issue_spec.rb1
-rw-r--r--spec/features/issues/user_creates_issue_spec.rb4
-rw-r--r--spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb2
-rw-r--r--spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb3
-rw-r--r--spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb1
-rw-r--r--spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb9
-rw-r--r--spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb22
-rw-r--r--spec/features/merge_request/user_sees_merge_widget_spec.rb46
-rw-r--r--spec/features/merge_request/user_sees_pipelines_spec.rb10
-rw-r--r--spec/features/merge_request/user_sees_versions_spec.rb4
-rw-r--r--spec/features/merge_request/user_suggests_changes_on_diff_spec.rb3
-rw-r--r--spec/features/merge_request/user_uses_quick_actions_spec.rb1
-rw-r--r--spec/features/projects/ci/lint_spec.rb4
-rw-r--r--spec/features/projects/commit/user_reverts_commit_spec.rb38
-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.rb36
-rw-r--r--spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb117
-rw-r--r--spec/features/projects/files/dockerfile_dropdown_spec.rb2
-rw-r--r--spec/features/projects/files/gitlab_ci_syntax_yml_dropdown_spec.rb56
-rw-r--r--spec/features/projects/issues/design_management/user_uploads_designs_spec.rb2
-rw-r--r--spec/features/projects/issues/email_participants_spec.rb34
-rw-r--r--spec/features/projects/jobs/permissions_spec.rb57
-rw-r--r--spec/features/projects/jobs/user_browses_jobs_spec.rb2
-rw-r--r--spec/features/projects/members/group_members_spec.rb55
-rw-r--r--spec/features/projects/members/groups_with_access_list_spec.rb17
-rw-r--r--spec/features/projects/members/invite_group_spec.rb10
-rw-r--r--spec/features/projects/members/list_spec.rb5
-rw-r--r--spec/features/projects/members/master_manages_access_requests_spec.rb1
-rw-r--r--spec/features/projects/members/tabs_spec.rb73
-rw-r--r--spec/features/projects/releases/user_creates_release_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_alerts_spec.rb74
-rw-r--r--spec/features/projects/settings/pipelines_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/user_manages_project_members_spec.rb6
-rw-r--r--spec/features/projects/snippets/user_deletes_snippet_spec.rb4
-rw-r--r--spec/features/promotion_spec.rb2
-rw-r--r--spec/features/protected_tags_spec.rb2
-rw-r--r--spec/features/runners_spec.rb34
-rw-r--r--spec/features/security/dashboard_access_spec.rb2
-rw-r--r--spec/features/security/profile_access_spec.rb12
-rw-r--r--spec/features/users/login_spec.rb67
-rw-r--r--spec/features/users/signup_spec.rb6
62 files changed, 857 insertions, 856 deletions
diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb
index 0e350a5e12e..a8e18385bd2 100644
--- a/spec/features/admin/admin_groups_spec.rb
+++ b/spec/features/admin/admin_groups_spec.rb
@@ -175,6 +175,7 @@ RSpec.describe 'Admin Groups' do
describe 'add admin himself to a group' do
before do
+ stub_feature_flags(invite_members_group_modal: false)
group.add_user(:user, Gitlab::Access::OWNER)
end
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index e16cde3fa1c..4f135b81bdf 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -23,7 +23,7 @@ RSpec.describe "Admin Runners" do
create(:ci_build, pipeline: pipeline, runner_id: runner.id)
visit admin_runners_path
- expect(page).to have_text "Set up a shared Runner manually"
+ expect(page).to have_text "Set up a shared runner manually"
expect(page).to have_text "Runners currently online: 1"
end
@@ -227,7 +227,7 @@ RSpec.describe "Admin Runners" do
end
it 'has all necessary texts including no runner message' do
- expect(page).to have_text "Set up a shared Runner manually"
+ expect(page).to have_text "Set up a shared runner manually"
expect(page).to have_text "Runners currently online: 0"
expect(page).to have_text 'No runners found'
end
@@ -389,7 +389,7 @@ RSpec.describe "Admin Runners" do
let(:page_token) { find('#registration_token').text }
before do
- click_button 'Reset runners registration token'
+ click_button 'Reset registration token'
end
it 'changes registration token' do
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 06d31b544ea..0c66775c323 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -17,10 +17,7 @@ RSpec.describe 'Admin updates settings' do
end
context 'General page' do
- let(:gitpod_feature_enabled) { true }
-
before do
- stub_feature_flags(gitpod: gitpod_feature_enabled)
visit general_admin_application_settings_path
end
@@ -224,28 +221,16 @@ RSpec.describe 'Admin updates settings' do
end
context 'Configure Gitpod' do
- context 'with feature disabled' do
- let(:gitpod_feature_enabled) { false }
-
- it 'do not show settings' do
- expect(page).not_to have_selector('#js-gitpod-settings')
+ it 'changes gitpod settings' do
+ page.within('#js-gitpod-settings') do
+ check 'Enable Gitpod integration'
+ fill_in 'Gitpod URL', with: 'https://gitpod.test/'
+ click_button 'Save changes'
end
- end
-
- context 'with feature enabled' do
- let(:gitpod_feature_enabled) { true }
- it 'changes gitpod settings' do
- page.within('#js-gitpod-settings') do
- check 'Enable Gitpod integration'
- fill_in 'Gitpod URL', with: 'https://gitpod.test/'
- click_button 'Save changes'
- end
-
- expect(page).to have_content 'Application settings saved successfully'
- expect(current_settings.gitpod_url).to eq('https://gitpod.test/')
- expect(current_settings.gitpod_enabled).to be(true)
- end
+ expect(page).to have_content 'Application settings saved successfully'
+ expect(current_settings.gitpod_url).to eq('https://gitpod.test/')
+ expect(current_settings.gitpod_enabled).to be(true)
end
end
end
diff --git a/spec/features/alert_management/user_filters_alerts_by_status_spec.rb b/spec/features/alert_management/user_filters_alerts_by_status_spec.rb
index ee516418cd6..bebbbcbf5f7 100644
--- a/spec/features/alert_management/user_filters_alerts_by_status_spec.rb
+++ b/spec/features/alert_management/user_filters_alerts_by_status_spec.rb
@@ -5,7 +5,6 @@ require 'spec_helper'
RSpec.describe 'User filters Alert Management table by status', :js do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user) }
- let_it_be(:alerts_service) { create(:alerts_service, project: project) }
let_it_be(:alert1, reload: true) { create(:alert_management_alert, :triggered, project: project) }
let_it_be(:alert2, reload: true) { create(:alert_management_alert, :acknowledged, project: project) }
let_it_be(:alert3, reload: true) { create(:alert_management_alert, :acknowledged, project: project) }
diff --git a/spec/features/alert_management/user_searches_alerts_spec.rb b/spec/features/alert_management/user_searches_alerts_spec.rb
index 568321de025..3bb1b260f36 100644
--- a/spec/features/alert_management/user_searches_alerts_spec.rb
+++ b/spec/features/alert_management/user_searches_alerts_spec.rb
@@ -5,7 +5,6 @@ require 'spec_helper'
RSpec.describe 'User searches Alert Management alerts', :js do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user) }
- let_it_be(:alerts_service) { create(:alerts_service, project: project) }
let_it_be(:alert) { create(:alert_management_alert, project: project, status: 'triggered') }
before_all do
diff --git a/spec/features/alert_management/user_updates_alert_status_spec.rb b/spec/features/alert_management/user_updates_alert_status_spec.rb
index 8974796662c..2d7be3a0022 100644
--- a/spec/features/alert_management/user_updates_alert_status_spec.rb
+++ b/spec/features/alert_management/user_updates_alert_status_spec.rb
@@ -5,7 +5,6 @@ require 'spec_helper'
RSpec.describe 'User updates Alert Management status', :js do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user) }
- let_it_be(:alerts_service) { create(:alerts_service, project: project) }
let_it_be(:alert) { create(:alert_management_alert, project: project, status: 'triggered') }
before_all do
diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb
index 0e76b5478a1..26b376be660 100644
--- a/spec/features/dashboard/merge_requests_spec.rb
+++ b/spec/features/dashboard/merge_requests_spec.rb
@@ -110,6 +110,12 @@ RSpec.describe 'Dashboard Merge Requests' do
visit merge_requests_dashboard_path(assignee_username: current_user.username)
end
+ it 'includes assigned and reviewers in badge' do
+ expect(find('.merge-requests-count')).to have_content('3')
+ expect(find('.js-assigned-mr-count')).to have_content('2')
+ expect(find('.js-reviewer-mr-count')).to have_content('1')
+ end
+
it 'shows assigned merge requests' do
expect(page).to have_content(assigned_merge_request.title)
expect(page).to have_content(assigned_merge_request_from_fork.title)
diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb
index f870adbbdb6..8705c22c41a 100644
--- a/spec/features/dashboard/projects_spec.rb
+++ b/spec/features/dashboard/projects_spec.rb
@@ -259,7 +259,7 @@ RSpec.describe 'Dashboard Projects' do
# 4. ProjectsHelper#load_pipeline_status
# 5. RendersMemberAccess#preload_max_member_access_for_collection
# 6. User#max_member_access_for_project_ids
- # 7. CommitWithPipeline#last_pipeline
+ # 7. Ci::CommitWithPipeline#last_pipeline
expect { visit dashboard_projects_path }.not_to exceed_query_limit(control_count + 7)
end
diff --git a/spec/features/groups/board_spec.rb b/spec/features/groups/board_spec.rb
index b25aa26d906..aab3f5e68d5 100644
--- a/spec/features/groups/board_spec.rb
+++ b/spec/features/groups/board_spec.rb
@@ -20,14 +20,19 @@ RSpec.describe 'Group Boards' do
page.within(find('.board', match: :first)) do
issue_title = 'New Issue'
find(:css, '.issue-count-badge-add-button').click
+
+ wait_for_requests
+
expect(find('.board-new-issue-form')).to be_visible
fill_in 'issue_title', with: issue_title
- find('.dropdown-menu-toggle').click
- wait_for_requests
+ page.within("[data-testid='project-select-dropdown']") do
+ find('button.gl-dropdown-toggle').click
+
+ find('.gl-new-dropdown-item button').click
+ end
- click_link(project.name)
click_button 'Submit issue'
expect(page).to have_content(issue_title)
diff --git a/spec/features/groups/import_export/connect_instance_spec.rb b/spec/features/groups/import_export/connect_instance_spec.rb
index c0f967fd0b9..2e1bf27ba8b 100644
--- a/spec/features/groups/import_export/connect_instance_spec.rb
+++ b/spec/features/groups/import_export/connect_instance_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do
pat = 'demo-pat'
stub_path = 'stub-group'
- stub_request(:get, "%{url}/api/v4/groups?page=1&per_page=30&top_level_only=true" % { url: source_url }).to_return(
+ stub_request(:get, "%{url}/api/v4/groups?page=1&per_page=30&top_level_only=true&min_access_level=40" % { url: source_url }).to_return(
body: [{
id: 2595438,
web_url: 'https://gitlab.com/groups/auto-breakfast',
diff --git a/spec/features/groups/members/manage_groups_spec.rb b/spec/features/groups/members/manage_groups_spec.rb
index 31a2c868cac..e9bbe9de3c9 100644
--- a/spec/features/groups/members/manage_groups_spec.rb
+++ b/spec/features/groups/members/manage_groups_spec.rb
@@ -17,6 +17,7 @@ RSpec.describe 'Groups > Members > Manage groups', :js do
let_it_be(:group_to_add) { create(:group) }
before do
+ stub_feature_flags(invite_members_group_modal: false)
group.add_owner(user)
visit group_group_members_path(group)
end
diff --git a/spec/features/groups/members/manage_members_spec.rb b/spec/features/groups/members/manage_members_spec.rb
index e6da05c4873..c27d0afba6f 100644
--- a/spec/features/groups/members/manage_members_spec.rb
+++ b/spec/features/groups/members/manage_members_spec.rb
@@ -11,9 +11,37 @@ RSpec.describe 'Groups > Members > Manage members' do
let(:group) { create(:group) }
before do
+ stub_feature_flags(invite_members_group_modal: false)
sign_in(user1)
end
+ shared_examples 'includes the correct Invite Members link' do |should_include, should_not_include|
+ it 'includes either the form or the modal trigger' do
+ group.add_owner(user1)
+
+ visit group_group_members_path(group)
+
+ expect(page).to have_selector(should_include)
+ expect(page).not_to have_selector(should_not_include)
+ end
+ end
+
+ context 'when Invite Members modal is enabled' do
+ before do
+ stub_feature_flags(invite_members_group_modal: true)
+ end
+
+ it_behaves_like 'includes the correct Invite Members link', '.js-invite-members-trigger', '.invite-users-form'
+ end
+
+ context 'when Invite Members modal is disabled' do
+ before do
+ stub_feature_flags(invite_members_group_modal: false)
+ end
+
+ it_behaves_like 'includes the correct Invite Members link', '.invite-users-form', '.js-invite-members-trigger'
+ end
+
it 'update user to owner level', :js do
group.add_owner(user1)
group.add_developer(user2)
diff --git a/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb
index de9b32e00aa..38deee547a3 100644
--- a/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb
+++ b/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe 'Groups > Members > Owner adds member with expiration date', :js
let(:new_member) { create(:user, name: 'Mary Jane') }
before do
+ stub_feature_flags(invite_members_group_modal: false)
group.add_owner(user1)
sign_in(user1)
end
diff --git a/spec/features/groups/members/master_manages_access_requests_spec.rb b/spec/features/groups/members/master_manages_access_requests_spec.rb
index 71c9b280ebe..2a17e7d2a5c 100644
--- a/spec/features/groups/members/master_manages_access_requests_spec.rb
+++ b/spec/features/groups/members/master_manages_access_requests_spec.rb
@@ -4,7 +4,6 @@ require 'spec_helper'
RSpec.describe 'Groups > Members > Maintainer manages access requests' do
it_behaves_like 'Maintainer manages access requests' do
- let(:has_tabs) { true }
let(:entity) { create(:group, :public) }
let(:members_page_path) { group_group_members_path(entity) }
end
diff --git a/spec/features/groups/members/sort_members_spec.rb b/spec/features/groups/members/sort_members_spec.rb
index 68a748aa76a..03758e0d401 100644
--- a/spec/features/groups/members/sort_members_spec.rb
+++ b/spec/features/groups/members/sort_members_spec.rb
@@ -16,174 +16,92 @@ RSpec.describe 'Groups > Members > Sort members', :js do
sign_in(owner)
end
- context 'when `group_members_filtered_search` feature flag is enabled' do
- def expect_sort_by(text, sort_direction)
- within('[data-testid="members-sort-dropdown"]') do
- expect(page).to have_css('button[aria-haspopup="true"]', text: text)
- expect(page).to have_button("Sorting Direction: #{sort_direction == :asc ? 'Ascending' : 'Descending'}")
- end
- end
-
- it 'sorts by account by default' do
- visit_members_list(sort: nil)
-
- expect(first_row.text).to include(owner.name)
- expect(second_row.text).to include(developer.name)
-
- expect_sort_by('Account', :asc)
- end
-
- it 'sorts by max role ascending' do
- visit_members_list(sort: :access_level_asc)
-
- expect(first_row.text).to include(developer.name)
- expect(second_row.text).to include(owner.name)
-
- expect_sort_by('Max role', :asc)
- end
-
- it 'sorts by max role descending' do
- visit_members_list(sort: :access_level_desc)
-
- expect(first_row.text).to include(owner.name)
- expect(second_row.text).to include(developer.name)
-
- expect_sort_by('Max role', :desc)
- end
-
- it 'sorts by access granted ascending' do
- visit_members_list(sort: :last_joined)
-
- expect(first_row.text).to include(developer.name)
- expect(second_row.text).to include(owner.name)
-
- expect_sort_by('Access granted', :asc)
- end
-
- it 'sorts by access granted descending' do
- visit_members_list(sort: :oldest_joined)
-
- expect(first_row.text).to include(owner.name)
- expect(second_row.text).to include(developer.name)
-
- expect_sort_by('Access granted', :desc)
- end
-
- it 'sorts by account ascending' do
- visit_members_list(sort: :name_asc)
-
- expect(first_row.text).to include(owner.name)
- expect(second_row.text).to include(developer.name)
-
- expect_sort_by('Account', :asc)
+ def expect_sort_by(text, sort_direction)
+ within('[data-testid="members-sort-dropdown"]') do
+ expect(page).to have_css('button[aria-haspopup="true"]', text: text)
+ expect(page).to have_button("Sorting Direction: #{sort_direction == :asc ? 'Ascending' : 'Descending'}")
end
+ end
- it 'sorts by account descending' do
- visit_members_list(sort: :name_desc)
+ it 'sorts by account by default' do
+ visit_members_list(sort: nil)
- expect(first_row.text).to include(developer.name)
- expect(second_row.text).to include(owner.name)
+ expect(first_row.text).to include(owner.name)
+ expect(second_row.text).to include(developer.name)
- expect_sort_by('Account', :desc)
- end
+ expect_sort_by('Account', :asc)
+ end
- it 'sorts by last sign-in ascending', :clean_gitlab_redis_shared_state do
- visit_members_list(sort: :recent_sign_in)
+ it 'sorts by max role ascending' do
+ visit_members_list(sort: :access_level_asc)
- expect(first_row.text).to include(owner.name)
- expect(second_row.text).to include(developer.name)
+ expect(first_row.text).to include(developer.name)
+ expect(second_row.text).to include(owner.name)
- expect_sort_by('Last sign-in', :asc)
- end
+ expect_sort_by('Max role', :asc)
+ end
- it 'sorts by last sign-in descending', :clean_gitlab_redis_shared_state do
- visit_members_list(sort: :oldest_sign_in)
+ it 'sorts by max role descending' do
+ visit_members_list(sort: :access_level_desc)
- expect(first_row.text).to include(developer.name)
- expect(second_row.text).to include(owner.name)
+ expect(first_row.text).to include(owner.name)
+ expect(second_row.text).to include(developer.name)
- expect_sort_by('Last sign-in', :desc)
- end
+ expect_sort_by('Max role', :desc)
end
- context 'when `group_members_filtered_search` feature flag is disabled' do
- dropdown_toggle_selector = '[data-testid="user-sort-dropdown"] [data-testid="dropdown-toggle"]'
+ it 'sorts by access granted ascending' do
+ visit_members_list(sort: :last_joined)
- before do
- stub_feature_flags(group_members_filtered_search: false)
- end
-
- it 'sorts alphabetically by default' do
- visit_members_list(sort: nil)
-
- expect(first_row.text).to include(owner.name)
- expect(second_row.text).to include(developer.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Name, ascending')
- end
+ expect(first_row.text).to include(developer.name)
+ expect(second_row.text).to include(owner.name)
- it 'sorts by access level ascending' do
- visit_members_list(sort: :access_level_asc)
+ expect_sort_by('Access granted', :asc)
+ end
- expect(first_row.text).to include(developer.name)
- expect(second_row.text).to include(owner.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Access level, ascending')
- end
+ it 'sorts by access granted descending' do
+ visit_members_list(sort: :oldest_joined)
- it 'sorts by access level descending' do
- visit_members_list(sort: :access_level_desc)
+ expect(first_row.text).to include(owner.name)
+ expect(second_row.text).to include(developer.name)
- expect(first_row.text).to include(owner.name)
- expect(second_row.text).to include(developer.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Access level, descending')
- end
+ expect_sort_by('Access granted', :desc)
+ end
- it 'sorts by last joined' do
- visit_members_list(sort: :last_joined)
+ it 'sorts by account ascending' do
+ visit_members_list(sort: :name_asc)
- expect(first_row.text).to include(developer.name)
- expect(second_row.text).to include(owner.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Last joined')
- end
+ expect(first_row.text).to include(owner.name)
+ expect(second_row.text).to include(developer.name)
- it 'sorts by oldest joined' do
- visit_members_list(sort: :oldest_joined)
+ expect_sort_by('Account', :asc)
+ end
- expect(first_row.text).to include(owner.name)
- expect(second_row.text).to include(developer.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Oldest joined')
- end
+ it 'sorts by account descending' do
+ visit_members_list(sort: :name_desc)
- it 'sorts by name ascending' do
- visit_members_list(sort: :name_asc)
+ expect(first_row.text).to include(developer.name)
+ expect(second_row.text).to include(owner.name)
- expect(first_row.text).to include(owner.name)
- expect(second_row.text).to include(developer.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Name, ascending')
- end
+ expect_sort_by('Account', :desc)
+ end
- it 'sorts by name descending' do
- visit_members_list(sort: :name_desc)
+ it 'sorts by last sign-in ascending', :clean_gitlab_redis_shared_state do
+ visit_members_list(sort: :recent_sign_in)
- expect(first_row.text).to include(developer.name)
- expect(second_row.text).to include(owner.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Name, descending')
- end
+ expect(first_row.text).to include(owner.name)
+ expect(second_row.text).to include(developer.name)
- it 'sorts by recent sign in', :clean_gitlab_redis_shared_state do
- visit_members_list(sort: :recent_sign_in)
+ expect_sort_by('Last sign-in', :asc)
+ end
- expect(first_row.text).to include(owner.name)
- expect(second_row.text).to include(developer.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Recent sign in')
- end
+ it 'sorts by last sign-in descending', :clean_gitlab_redis_shared_state do
+ visit_members_list(sort: :oldest_sign_in)
- it 'sorts by oldest sign in', :clean_gitlab_redis_shared_state do
- visit_members_list(sort: :oldest_sign_in)
+ expect(first_row.text).to include(developer.name)
+ expect(second_row.text).to include(owner.name)
- expect(first_row.text).to include(developer.name)
- expect(second_row.text).to include(owner.name)
- expect(page).to have_css(dropdown_toggle_selector, text: 'Oldest sign in')
- end
+ expect_sort_by('Last sign-in', :desc)
end
def visit_members_list(sort:)
diff --git a/spec/features/groups/settings/ci_cd_spec.rb b/spec/features/groups/settings/ci_cd_spec.rb
index 9c2f9512b9d..b059cd8da29 100644
--- a/spec/features/groups/settings/ci_cd_spec.rb
+++ b/spec/features/groups/settings/ci_cd_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'Group CI/CD settings' do
let(:page_token) { find('#registration_token').text }
before do
- click_button 'Reset runners registration token'
+ click_button 'Reset registration token'
end
it 'changes registration token' do
diff --git a/spec/features/groups/settings/packages_and_registries_spec.rb b/spec/features/groups/settings/packages_and_registries_spec.rb
new file mode 100644
index 00000000000..b8ffd73335d
--- /dev/null
+++ b/spec/features/groups/settings/packages_and_registries_spec.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Group Packages & Registries settings' do
+ include WaitForRequests
+
+ let(:user) { create(:user) }
+ let(:group) { create(:group) }
+
+ before do
+ group.add_owner(user)
+ sign_in(user)
+ end
+
+ context 'when the feature flag is off' do
+ before do
+ stub_feature_flags(packages_and_registries_group_settings: false)
+ end
+
+ it 'the menu item is not visible' do
+ visit group_path(group)
+
+ settings_menu = find_settings_menu
+
+ expect(settings_menu).not_to have_content 'Packages & Registries'
+ end
+ end
+
+ context 'when the feature flag is on' do
+ it 'the menu item is visible' do
+ visit group_path(group)
+
+ settings_menu = find_settings_menu
+ expect(settings_menu).to have_content 'Packages & Registries'
+ end
+
+ it 'has a page title set' do
+ visit_settings_page
+
+ expect(page).to have_title _('Packages & Registries')
+ end
+
+ it 'sidebar menu is open' do
+ visit_settings_page
+
+ sidebar = find('.nav-sidebar')
+ expect(sidebar).to have_link _('Packages & Registries')
+ end
+ end
+
+ def find_settings_menu
+ find('ul[data-testid="group-settings-menu"]')
+ end
+
+ def visit_settings_page
+ visit group_settings_packages_and_registries_path(group)
+ end
+end
diff --git a/spec/features/incidents/incident_details_spec.rb b/spec/features/incidents/incident_details_spec.rb
index 3ec7717b649..96f8cf0062c 100644
--- a/spec/features/incidents/incident_details_spec.rb
+++ b/spec/features/incidents/incident_details_spec.rb
@@ -45,7 +45,7 @@ RSpec.describe 'Incident details', :js do
expect(page).to have_selector('.right-sidebar[data-issuable-type="issue"]')
expect(sidebar).to have_selector('.incident-severity')
- expect(sidebar).not_to have_selector('.milestone')
+ expect(sidebar).to have_selector('.milestone')
end
end
end
diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb
index 07bf821a590..9b2a11c4b0e 100644
--- a/spec/features/issues/gfm_autocomplete_spec.rb
+++ b/spec/features/issues/gfm_autocomplete_spec.rb
@@ -294,6 +294,15 @@ RSpec.describe 'GFM autocomplete', :js do
user_item = find('.atwho-view li', text: user.username)
expect(user_item).to have_content(user.username)
end
+
+ it 'does not limit quick actions autocomplete list to 5' do
+ note = find('#note-body')
+ page.within '.timeline-content-form' do
+ note.native.send_keys('/')
+ end
+
+ expect(page).to have_selector('.atwho-view li', minimum: 6, visible: true)
+ end
end
context 'assignees' do
@@ -426,36 +435,16 @@ RSpec.describe 'GFM autocomplete', :js do
visit project_issue_path(project, issue)
note = find('#note-body')
- start_comment_with_emoji(note)
+ start_comment_with_emoji(note, '.atwho-view li')
start_and_cancel_discussion
note.fill_in(with: '')
- start_comment_with_emoji(note)
+ start_comment_with_emoji(note, '.atwho-view li')
note.native.send_keys(:enter)
expect(note.value).to eql('Hello :100: ')
end
-
- def start_comment_with_emoji(note)
- note.native.send_keys('Hello :10')
-
- wait_for_requests
-
- find('.atwho-view li', text: '100')
- end
-
- def start_and_cancel_discussion
- click_button('Reply...')
-
- fill_in('note_note', with: 'Whoops!')
-
- page.accept_alert 'Are you sure you want to cancel creating this comment?' do
- click_button('Cancel')
- end
-
- wait_for_requests
- end
end
shared_examples 'autocomplete suggestions' do
@@ -599,6 +588,33 @@ RSpec.describe 'GFM autocomplete', :js do
expect(page).not_to have_selector('.tribute-container', visible: true)
end
+ it 'does not open autocomplete menu when ":" is prefixed by a number and letters' do
+ note = find('#note-body')
+
+ # Number.
+ page.within '.timeline-content-form' do
+ note.native.send_keys('7:')
+ end
+
+ expect(page).not_to have_selector('.tribute-container', visible: true)
+
+ # ASCII letter.
+ page.within '.timeline-content-form' do
+ note.set('')
+ note.native.send_keys('w:')
+ end
+
+ expect(page).not_to have_selector('.tribute-container', visible: true)
+
+ # Non-ASCII letter.
+ page.within '.timeline-content-form' do
+ note.set('')
+ note.native.send_keys('Ё:')
+ end
+
+ expect(page).not_to have_selector('.tribute-container', visible: true)
+ end
+
it 'selects the first item for assignee dropdowns' do
page.within '.timeline-content-form' do
find('#note-body').native.send_keys('@')
@@ -624,6 +640,16 @@ RSpec.describe 'GFM autocomplete', :js do
expect(find('.tribute-container ul', visible: true)).to have_content(user.name)
end
+ it 'selects the first item for non-assignee dropdowns if a query is entered' do
+ page.within '.timeline-content-form' do
+ find('#note-body').native.send_keys(':1')
+ end
+
+ wait_for_requests
+
+ expect(find('.tribute-container ul', visible: true)).to have_selector('.highlight:first-of-type')
+ end
+
context 'when autocompleting for groups' do
it 'shows the group when searching for the name of the group' do
page.within '.timeline-content-form' do
@@ -687,20 +713,34 @@ RSpec.describe 'GFM autocomplete', :js do
expect_to_wrap(false, user_item, note, user.username)
end
- it 'triggers autocomplete after selecting a quick action' do
+ it 'does not wrap for emoji values' do
note = find('#note-body')
page.within '.timeline-content-form' do
- note.native.send_keys('/as')
+ note.native.send_keys(":cartwheel_")
end
- find('.atwho-view li', text: '/assign')
- note.native.send_keys(:tab)
- note.native.send_keys(:right)
+ emoji_item = first('.tribute-container li', text: 'cartwheel_tone1', visible: true)
- wait_for_requests
+ expect_to_wrap(false, emoji_item, note, 'cartwheel_tone1')
+ end
- user_item = find('.tribute-container ul', text: user.username, visible: true)
- expect(user_item).to have_content(user.username)
+ it 'does not open autocomplete if there is no space before' do
+ page.within '.timeline-content-form' do
+ find('#note-body').native.send_keys("hello:#{user.username[0..2]}")
+ end
+
+ expect(page).not_to have_selector('.tribute-container')
+ end
+
+ it 'autocompletes for quick actions' do
+ note = find('#note-body')
+ page.within '.timeline-content-form' do
+ note.native.send_keys('/as')
+ wait_for_requests
+ note.native.send_keys(:tab)
+ end
+
+ expect(note.value).to have_text('/assign')
end
end
@@ -719,15 +759,14 @@ RSpec.describe 'GFM autocomplete', :js do
note = find('#note-body')
page.within '.timeline-content-form' do
- note.native.send_keys('/as')
+ note.native.send_keys('/assign ')
+ # The `/assign` ajax response might replace the one by `@` below causing a failed test
+ # so we need to wait for the `/assign` ajax request to finish first
+ wait_for_requests
+ note.native.send_keys('@')
+ wait_for_requests
end
- find('.atwho-view li', text: '/assign')
- note.native.send_keys(:tab)
- note.native.send_keys(:right)
-
- wait_for_requests
-
expect(find('.tribute-container ul', visible: true)).not_to have_content(user.username)
expect(find('.tribute-container ul', visible: true)).to have_content(unassigned_user.username)
end
@@ -739,12 +778,14 @@ RSpec.describe 'GFM autocomplete', :js do
page.within '.timeline-content-form' do
note.native.send_keys('/assign @user2')
note.native.send_keys(:enter)
- note.native.send_keys('/assign @')
- note.native.send_keys(:right)
+ note.native.send_keys('/assign ')
+ # The `/assign` ajax response might replace the one by `@` below causing a failed test
+ # so we need to wait for the `/assign` ajax request to finish first
+ wait_for_requests
+ note.native.send_keys('@')
+ wait_for_requests
end
- wait_for_requests
-
expect(find('.tribute-container ul', visible: true)).not_to have_content(user.username)
expect(find('.tribute-container ul', visible: true)).to have_content(unassigned_user.username)
end
@@ -824,6 +865,26 @@ RSpec.describe 'GFM autocomplete', :js do
end
end
+ context 'when other notes are destroyed' do
+ let!(:discussion) { create(:discussion_note_on_issue, noteable: issue, project: issue.project) }
+
+ # This is meant to protect against this issue https://gitlab.com/gitlab-org/gitlab/-/issues/228729
+ it 'keeps autocomplete key listeners' do
+ visit project_issue_path(project, issue)
+ note = find('#note-body')
+
+ start_comment_with_emoji(note, '.tribute-container li')
+
+ start_and_cancel_discussion
+
+ note.fill_in(with: '')
+ start_comment_with_emoji(note, '.tribute-container li')
+ note.native.send_keys(:enter)
+
+ expect(note.value).to eql('Hello :100: ')
+ end
+ end
+
shared_examples 'autocomplete suggestions' do
it 'suggests objects correctly' do
page.within '.timeline-content-form' do
@@ -913,4 +974,24 @@ RSpec.describe 'GFM autocomplete', :js do
note.native.send_keys(text)
end
end
+
+ def start_comment_with_emoji(note, selector)
+ note.native.send_keys('Hello :10')
+
+ wait_for_requests
+
+ find(selector, text: '100')
+ end
+
+ def start_and_cancel_discussion
+ click_button('Reply...')
+
+ fill_in('note_note', with: 'Whoops!')
+
+ page.accept_alert 'Are you sure you want to cancel creating this comment?' do
+ click_button('Cancel')
+ end
+
+ wait_for_requests
+ end
end
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index 94a1de06488..59fba5f65e0 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -13,256 +13,280 @@ RSpec.describe 'Issue Sidebar' do
let!(:xss_label) { create(:label, project: project, title: '&lt;script&gt;alert("xss");&lt;&#x2F;script&gt;') }
before do
- sign_in(user)
+ stub_incoming_email_setting(enabled: true, address: "p+%{key}@gl.ab")
end
- context 'when concerning the assignee', :js do
- let(:user2) { create(:user) }
- let(:issue2) { create(:issue, project: project, author: user2) }
-
- include_examples 'issuable invite members experiments' do
- let(:issuable_path) { project_issue_path(project, issue2) }
+ context 'when signed in' do
+ before do
+ sign_in(user)
end
- context 'when user is a developer' do
- before do
- project.add_developer(user)
- visit_issue(project, issue2)
-
- find('.block.assignee .edit-link').click
+ context 'when concerning the assignee', :js do
+ let(:user2) { create(:user) }
+ let(:issue2) { create(:issue, project: project, author: user2) }
- wait_for_requests
+ include_examples 'issuable invite members experiments' do
+ let(:issuable_path) { project_issue_path(project, issue2) }
end
- it 'shows author in assignee dropdown' do
- page.within '.dropdown-menu-user' do
- expect(page).to have_content(user2.name)
- end
- end
+ context 'when user is a developer' do
+ before do
+ project.add_developer(user)
+ visit_issue(project, issue2)
- it 'shows author when filtering assignee dropdown' do
- page.within '.dropdown-menu-user' do
- find('.dropdown-input-field').set(user2.name)
+ find('.block.assignee .edit-link').click
wait_for_requests
+ end
- expect(page).to have_content(user2.name)
+ it 'shows author in assignee dropdown' do
+ page.within '.dropdown-menu-user' do
+ expect(page).to have_content(user2.name)
+ end
end
- end
- it 'assigns yourself' do
- find('.block.assignee .dropdown-menu-toggle').click
+ it 'shows author when filtering assignee dropdown' do
+ page.within '.dropdown-menu-user' do
+ find('.dropdown-input-field').set(user2.name)
- click_button 'assign yourself'
+ wait_for_requests
- wait_for_requests
+ expect(page).to have_content(user2.name)
+ end
+ end
- find('.block.assignee .edit-link').click
+ it 'assigns yourself' do
+ find('.block.assignee .dropdown-menu-toggle').click
- page.within '.dropdown-menu-user' do
- expect(page.find('.dropdown-header')).to be_visible
- expect(page.find('.dropdown-menu-user-link.is-active')).to have_content(user.name)
- end
- end
+ click_button 'assign yourself'
- it 'keeps your filtered term after filtering and dismissing the dropdown' do
- find('.dropdown-input-field').set(user2.name)
+ wait_for_requests
- wait_for_requests
+ find('.block.assignee .edit-link').click
- page.within '.dropdown-menu-user' do
- expect(page).not_to have_content 'Unassigned'
- click_link user2.name
+ page.within '.dropdown-menu-user' do
+ expect(page.find('.dropdown-header')).to be_visible
+ expect(page.find('.dropdown-menu-user-link.is-active')).to have_content(user.name)
+ end
end
- find('.js-right-sidebar').click
- find('.block.assignee .edit-link').click
-
- expect(page.all('.dropdown-menu-user li').length).to eq(1)
- expect(find('.dropdown-input-field').value).to eq(user2.name)
- end
- end
+ it 'keeps your filtered term after filtering and dismissing the dropdown' do
+ find('.dropdown-input-field').set(user2.name)
- it 'shows label text as "Apply" when assignees are changed' do
- project.add_developer(user)
- visit_issue(project, issue2)
+ wait_for_requests
- find('.block.assignee .edit-link').click
- wait_for_requests
+ page.within '.dropdown-menu-user' do
+ expect(page).not_to have_content 'Unassigned'
+ click_link user2.name
+ end
- click_on 'Unassigned'
+ find('.js-right-sidebar').click
+ find('.block.assignee .edit-link').click
- expect(page).to have_link('Apply')
- end
- end
+ expect(page.all('.dropdown-menu-user li').length).to eq(1)
+ expect(find('.dropdown-input-field').value).to eq(user2.name)
+ end
+ end
- context 'as a allowed user' do
- before do
- project.add_developer(user)
- visit_issue(project, issue)
- end
+ it 'shows label text as "Apply" when assignees are changed' do
+ project.add_developer(user)
+ visit_issue(project, issue2)
- context 'sidebar', :js do
- it 'changes size when the screen size is smaller' do
- sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed'
- # Resize the window
- resize_screen_sm
- # Make sure the sidebar is collapsed
- find(sidebar_selector)
- expect(page).to have_css(sidebar_selector)
- # Once is collapsed let's open the sidebard and reload
- open_issue_sidebar
- refresh
- find(sidebar_selector)
- expect(page).to have_css(sidebar_selector)
- # Restore the window size as it was including the sidebar
- restore_window_size
- open_issue_sidebar
- end
+ find('.block.assignee .edit-link').click
+ wait_for_requests
- it 'escapes XSS when viewing issue labels' do
- page.within('.block.labels') do
- click_on 'Edit'
+ click_on 'Unassigned'
- expect(page).to have_content '<script>alert("xss");</script>'
- end
+ expect(page).to have_link('Apply')
end
end
- context 'editing issue labels', :js do
+ context 'as a allowed user' do
before do
- issue.update(labels: [label])
- page.within('.block.labels') do
- click_on 'Edit'
- end
+ project.add_developer(user)
+ visit_issue(project, issue)
end
- it 'shows the current set of labels' do
- page.within('.issuable-show-labels') do
- expect(page).to have_content label.title
+ context 'sidebar', :js do
+ it 'changes size when the screen size is smaller' do
+ sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed'
+ # Resize the window
+ resize_screen_sm
+ # Make sure the sidebar is collapsed
+ find(sidebar_selector)
+ expect(page).to have_css(sidebar_selector)
+ # Once is collapsed let's open the sidebard and reload
+ open_issue_sidebar
+ refresh
+ find(sidebar_selector)
+ expect(page).to have_css(sidebar_selector)
+ # Restore the window size as it was including the sidebar
+ restore_window_size
+ open_issue_sidebar
end
- end
- it 'shows option to create a project label' do
- page.within('.block.labels') do
- expect(page).to have_content 'Create project'
+ it 'escapes XSS when viewing issue labels' do
+ page.within('.block.labels') do
+ click_on 'Edit'
+
+ expect(page).to have_content '<script>alert("xss");</script>'
+ end
end
end
- context 'creating a project label', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/27992' do
+ context 'editing issue labels', :js do
before do
+ issue.update(labels: [label])
page.within('.block.labels') do
- click_link 'Create project'
+ click_on 'Edit'
end
end
- it 'shows dropdown switches to "create label" section' do
- page.within('.block.labels') do
- expect(page).to have_content 'Create project label'
+ it 'shows the current set of labels' do
+ page.within('.issuable-show-labels') do
+ expect(page).to have_content label.title
end
end
- it 'adds new label' do
+ it 'shows option to create a project label' do
page.within('.block.labels') do
- fill_in 'new_label_name', with: 'wontfix'
- page.find('.suggest-colors a', match: :first).click
- page.find('button', text: 'Create').click
+ expect(page).to have_content 'Create project'
+ end
+ end
- page.within('.dropdown-page-one') do
- expect(page).to have_content 'wontfix'
+ context 'creating a project label', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/27992' do
+ before do
+ page.within('.block.labels') do
+ click_link 'Create project'
end
end
- end
- it 'shows error message if label title is taken' do
- page.within('.block.labels') do
- fill_in 'new_label_name', with: label.title
- page.find('.suggest-colors a', match: :first).click
- page.find('button', text: 'Create').click
+ it 'shows dropdown switches to "create label" section' do
+ page.within('.block.labels') do
+ expect(page).to have_content 'Create project label'
+ end
+ end
+
+ it 'adds new label' do
+ page.within('.block.labels') do
+ fill_in 'new_label_name', with: 'wontfix'
+ page.find('.suggest-colors a', match: :first).click
+ page.find('button', text: 'Create').click
+
+ page.within('.dropdown-page-one') do
+ expect(page).to have_content 'wontfix'
+ end
+ end
+ end
- page.within('.dropdown-page-two') do
- expect(page).to have_content 'Title has already been taken'
+ it 'shows error message if label title is taken' do
+ page.within('.block.labels') do
+ fill_in 'new_label_name', with: label.title
+ page.find('.suggest-colors a', match: :first).click
+ page.find('button', text: 'Create').click
+
+ page.within('.dropdown-page-two') do
+ expect(page).to have_content 'Title has already been taken'
+ end
end
end
end
end
- end
- context 'interacting with collapsed sidebar', :js do
- collapsed_sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed'
- expanded_sidebar_selector = 'aside.right-sidebar.right-sidebar-expanded'
- confidentiality_sidebar_block = '.block.confidentiality'
- lock_sidebar_block = '.block.lock'
- collapsed_sidebar_block_icon = '.sidebar-collapsed-icon'
+ context 'interacting with collapsed sidebar', :js do
+ collapsed_sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed'
+ expanded_sidebar_selector = 'aside.right-sidebar.right-sidebar-expanded'
+ confidentiality_sidebar_block = '.block.confidentiality'
+ lock_sidebar_block = '.block.lock'
+ collapsed_sidebar_block_icon = '.sidebar-collapsed-icon'
- before do
- resize_screen_sm
- end
+ before do
+ resize_screen_sm
+ end
- it 'confidentiality block expands then collapses sidebar' do
- expect(page).to have_css(collapsed_sidebar_selector)
+ it 'confidentiality block expands then collapses sidebar' do
+ expect(page).to have_css(collapsed_sidebar_selector)
- page.within(confidentiality_sidebar_block) do
- find(collapsed_sidebar_block_icon).click
+ page.within(confidentiality_sidebar_block) do
+ find(collapsed_sidebar_block_icon).click
+ end
+
+ expect(page).to have_css(expanded_sidebar_selector)
+
+ page.within(confidentiality_sidebar_block) do
+ page.find('button', text: 'Cancel').click
+ end
+
+ expect(page).to have_css(collapsed_sidebar_selector)
end
- expect(page).to have_css(expanded_sidebar_selector)
+ it 'lock block expands then collapses sidebar' do
+ expect(page).to have_css(collapsed_sidebar_selector)
+
+ page.within(lock_sidebar_block) do
+ find(collapsed_sidebar_block_icon).click
+ end
+
+ expect(page).to have_css(expanded_sidebar_selector)
+
+ page.within(lock_sidebar_block) do
+ page.find('button', text: 'Cancel').click
+ end
- page.within(confidentiality_sidebar_block) do
- page.find('button', text: 'Cancel').click
+ expect(page).to have_css(collapsed_sidebar_selector)
end
+ end
+ end
- expect(page).to have_css(collapsed_sidebar_selector)
+ context 'as a guest' do
+ before do
+ project.add_guest(user)
+ visit_issue(project, issue)
end
- it 'lock block expands then collapses sidebar' do
- expect(page).to have_css(collapsed_sidebar_selector)
+ it 'does not have a option to edit labels' do
+ expect(page).not_to have_selector('.block.labels .js-sidebar-dropdown-toggle')
+ end
- page.within(lock_sidebar_block) do
- find(collapsed_sidebar_block_icon).click
+ 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)}"
end
+ end
- expect(page).to have_css(expanded_sidebar_selector)
+ context 'interacting with collapsed sidebar', :js do
+ collapsed_sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed'
+ expanded_sidebar_selector = 'aside.right-sidebar.right-sidebar-expanded'
+ lock_sidebar_block = '.block.lock'
+ lock_button = '.block.lock .btn-close'
+ collapsed_sidebar_block_icon = '.sidebar-collapsed-icon'
- page.within(lock_sidebar_block) do
- page.find('button', text: 'Cancel').click
+ before do
+ resize_screen_sm
end
- expect(page).to have_css(collapsed_sidebar_selector)
- end
- end
- end
+ it 'expands then does not show the lock dialog form' do
+ expect(page).to have_css(collapsed_sidebar_selector)
- context 'as a guest' do
- before do
- project.add_guest(user)
- visit_issue(project, issue)
- end
+ page.within(lock_sidebar_block) do
+ find(collapsed_sidebar_block_icon).click
+ end
- it 'does not have a option to edit labels' do
- expect(page).not_to have_selector('.block.labels .js-sidebar-dropdown-toggle')
+ expect(page).to have_css(expanded_sidebar_selector)
+ expect(page).not_to have_selector(lock_button)
+ end
+ end
end
+ end
- context 'interacting with collapsed sidebar', :js do
- collapsed_sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed'
- expanded_sidebar_selector = 'aside.right-sidebar.right-sidebar-expanded'
- lock_sidebar_block = '.block.lock'
- lock_button = '.block.lock .btn-close'
- collapsed_sidebar_block_icon = '.sidebar-collapsed-icon'
-
+ context 'when not signed in' do
+ context 'sidebar', :js do
before do
- resize_screen_sm
+ visit_issue(project, issue)
end
- it 'expands then does not show the lock dialog form' do
- expect(page).to have_css(collapsed_sidebar_selector)
-
- page.within(lock_sidebar_block) do
- find(collapsed_sidebar_block_icon).click
- end
-
- expect(page).to have_css(expanded_sidebar_selector)
- expect(page).not_to have_selector(lock_button)
+ it 'does not find issue email' do
+ expect(page).not_to have_selector('[data-qa-selector="copy-forward-email"]')
end
end
end
diff --git a/spec/features/issues/issue_state_spec.rb b/spec/features/issues/issue_state_spec.rb
index 0ef6eb56dff..d5a115433aa 100644
--- a/spec/features/issues/issue_state_spec.rb
+++ b/spec/features/issues/issue_state_spec.rb
@@ -13,10 +13,13 @@ RSpec.describe 'issue state', :js do
shared_examples 'issue closed' do |selector|
it 'can close an issue' do
+ wait_for_requests
+
expect(find('.status-box')).to have_content 'Open'
within selector do
click_button 'Close issue'
+ wait_for_requests
end
expect(find('.status-box')).to have_content 'Closed'
@@ -25,17 +28,20 @@ RSpec.describe 'issue state', :js do
shared_examples 'issue reopened' do |selector|
it 'can reopen an issue' do
+ wait_for_requests
+
expect(find('.status-box')).to have_content 'Closed'
within selector do
click_button 'Reopen issue'
+ wait_for_requests
end
expect(find('.status-box')).to have_content 'Open'
end
end
- describe 'when open' do
+ describe 'when open', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297348' do
context 'when clicking the top `Close issue` button', :aggregate_failures do
let(:open_issue) { create(:issue, project: project) }
@@ -57,7 +63,7 @@ RSpec.describe 'issue state', :js do
end
end
- describe 'when closed' do
+ describe 'when closed', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297201' do
context 'when clicking the top `Reopen issue` button', :aggregate_failures do
let(:closed_issue) { create(:issue, project: project, state: 'closed') }
diff --git a/spec/features/issues/user_comments_on_issue_spec.rb b/spec/features/issues/user_comments_on_issue_spec.rb
index 005d45d9c92..24a261f592b 100644
--- a/spec/features/issues/user_comments_on_issue_spec.rb
+++ b/spec/features/issues/user_comments_on_issue_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe "User comments on issue", :js do
let(:user) { create(:user) }
before do
+ stub_feature_flags(tribute_autocomplete: false)
project.add_guest(user)
sign_in(user)
diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb
index 668b4265948..98f9ed6c6a2 100644
--- a/spec/features/issues/user_creates_issue_spec.rb
+++ b/spec/features/issues/user_creates_issue_spec.rb
@@ -223,8 +223,8 @@ RSpec.describe "User creates issue" do
expect(page).not_to have_selector('.epic-dropdown-container')
end
- it 'hides the milestone select' do
- expect(page).not_to have_selector('.qa-issuable-milestone-dropdown')
+ it 'shows the milestone select' do
+ expect(page).to have_selector('.qa-issuable-milestone-dropdown')
end
it 'hides the weight input' do
diff --git a/spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb b/spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb
index 6376f9ab5fd..2b94c072c8b 100644
--- a/spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb
+++ b/spec/features/merge_request/user_closes_reopens_merge_request_state_spec.rb
@@ -55,7 +55,7 @@ RSpec.describe 'User closes/reopens a merge request', :js do
end
end
- describe 'when closed' do
+ describe 'when closed', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297500' do
context 'when clicking the top `Reopen merge request` link', :aggregate_failures do
let(:closed_merge_request) { create(:merge_request, source_project: project, target_project: project, state: 'closed') }
diff --git a/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb b/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb
index 782a7e3bfb6..ac0c66524f0 100644
--- a/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb
+++ b/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb
@@ -69,7 +69,8 @@ RSpec.describe 'Batch diffs', :js do
end
context 'which is in at least page 2 of the batched pages of diffs' do
- it 'scrolls to the correct discussion' do
+ it 'scrolls to the correct discussion',
+ quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/293814' } do
page.within('.diff-file.file-holder:last-of-type') do
click_link('just now')
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 cb7c952dfe4..b86586d53e2 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
@@ -228,6 +228,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
page.find('.discussion-next-btn').click
end
+ expect(page).to have_button('Resolve thread', visible: true)
expect(page.evaluate_script("window.pageYOffset")).to be > 0
end
diff --git a/spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb b/spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb
index d9950f5504b..56517a97716 100644
--- a/spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb
+++ b/spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb
@@ -17,15 +17,16 @@ RSpec.describe 'Merge request > User scrolls to note on load', :js do
it 'scrolls note into view' do
visit "#{project_merge_request_path(project, merge_request)}#{fragment_id}"
- wait_for_requests
+ wait_for_all_requests
+
+ expect(page).to have_selector("#{fragment_id}")
- page_height = page.current_window.size[1]
page_scroll_y = page.evaluate_script("window.scrollY")
- fragment_position_top = page.evaluate_script("Math.round($('#{fragment_id}').offset().top)")
+ fragment_position_top = page.evaluate_script("Math.round(document.querySelector('#{fragment_id}').getBoundingClientRect().top + window.pageYOffset)")
expect(find(fragment_id).visible?).to eq true
expect(fragment_position_top).to be >= page_scroll_y
- expect(fragment_position_top).to be < (page_scroll_y + page_height)
+ expect(page.evaluate_script("window.pageYOffset")).to be > 0
end
it 'renders un-collapsed notes with diff' do
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 6647a4e9291..d9743f6f330 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
@@ -62,7 +62,7 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
it 'sees branch pipelines and detached merge request pipelines in correct order' do
page.within('.ci-table') do
expect(page).to have_selector('.ci-pending', count: 2)
- expect(first('.js-pipeline-url-link')).to have_content("##{detached_merge_request_pipeline.id}")
+ expect(first('[data-testid="pipeline-url-link"]')).to have_content("##{detached_merge_request_pipeline.id}")
end
end
@@ -97,16 +97,16 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
page.within('.ci-table') do
expect(page).to have_selector('.ci-pending', count: 4)
- expect(all('.js-pipeline-url-link')[0])
+ expect(all('[data-testid="pipeline-url-link"]')[0])
.to have_content("##{detached_merge_request_pipeline_2.id}")
- expect(all('.js-pipeline-url-link')[1])
+ expect(all('[data-testid="pipeline-url-link"]')[1])
.to have_content("##{detached_merge_request_pipeline.id}")
- expect(all('.js-pipeline-url-link')[2])
+ expect(all('[data-testid="pipeline-url-link"]')[2])
.to have_content("##{push_pipeline_2.id}")
- expect(all('.js-pipeline-url-link')[3])
+ expect(all('[data-testid="pipeline-url-link"]')[3])
.to have_content("##{push_pipeline.id}")
end
end
@@ -197,7 +197,7 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
it 'sees a branch pipeline in pipeline tab' do
page.within('.ci-table') do
expect(page).to have_selector('.ci-pending', count: 1)
- expect(first('.js-pipeline-url-link')).to have_content("##{push_pipeline.id}")
+ expect(first('[data-testid="pipeline-url-link"]')).to have_content("##{push_pipeline.id}")
end
end
@@ -246,7 +246,7 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
it 'sees branch pipelines and detached merge request pipelines in correct order' do
page.within('.ci-table') do
expect(page).to have_selector('.ci-pending', count: 2)
- expect(first('.js-pipeline-url-link')).to have_content("##{detached_merge_request_pipeline.id}")
+ expect(first('[data-testid="pipeline-url-link"]')).to have_content("##{detached_merge_request_pipeline.id}")
end
end
@@ -287,16 +287,16 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
page.within('.ci-table') do
expect(page).to have_selector('.ci-pending', count: 4)
- expect(all('.js-pipeline-url-link')[0])
+ expect(all('[data-testid="pipeline-url-link"]')[0])
.to have_content("##{detached_merge_request_pipeline_2.id}")
- expect(all('.js-pipeline-url-link')[1])
+ expect(all('[data-testid="pipeline-url-link"]')[1])
.to have_content("##{detached_merge_request_pipeline.id}")
- expect(all('.js-pipeline-url-link')[2])
+ expect(all('[data-testid="pipeline-url-link"]')[2])
.to have_content("##{push_pipeline_2.id}")
- expect(all('.js-pipeline-url-link')[3])
+ expect(all('[data-testid="pipeline-url-link"]')[3])
.to have_content("##{push_pipeline.id}")
end
end
diff --git a/spec/features/merge_request/user_sees_merge_widget_spec.rb b/spec/features/merge_request/user_sees_merge_widget_spec.rb
index 0e8012f161f..c2b2ada47be 100644
--- a/spec/features/merge_request/user_sees_merge_widget_spec.rb
+++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb
@@ -605,11 +605,14 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
within(".js-report-section-container") do
click_button 'addTest'
-
- expect(page).to have_content('6.66')
- expect(page).to have_content(sample_java_failed_message.gsub(/\s+/, ' ').strip)
end
end
+
+ within("#modal-mrwidget-reports") do
+ expect(page).to have_content('addTest')
+ expect(page).to have_content('6.66')
+ expect(page).to have_content(sample_java_failed_message.gsub(/\s+/, ' ').strip)
+ end
end
end
end
@@ -650,11 +653,14 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
within(".js-report-section-container") do
click_button 'Test#sum when a is 1 and b is 3 returns summary'
-
- expect(page).to have_content('2.22')
- expect(page).to have_content(sample_rspec_failed_message.gsub(/\s+/, ' ').strip)
end
end
+
+ within("#modal-mrwidget-reports") do
+ expect(page).to have_content('Test#sum when a is 1 and b is 3 returns summary')
+ expect(page).to have_content('2.22')
+ expect(page).to have_content(sample_rspec_failed_message.gsub(/\s+/, ' ').strip)
+ end
end
end
end
@@ -694,10 +700,13 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
within(".js-report-section-container") do
click_button 'addTest'
-
- expect(page).to have_content('5.55')
end
end
+
+ within("#modal-mrwidget-reports") do
+ expect(page).to have_content('addTest')
+ expect(page).to have_content('5.55')
+ end
end
end
end
@@ -738,10 +747,13 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
within(".js-report-section-container") do
click_button 'addTest'
-
- expect(page).to have_content('8.88')
end
end
+
+ within("#modal-mrwidget-reports") do
+ expect(page).to have_content('addTest')
+ expect(page).to have_content('8.88')
+ end
end
end
end
@@ -782,10 +794,13 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
within(".js-report-section-container") do
click_button 'Test#sum when a is 4 and b is 4 returns summary'
-
- expect(page).to have_content('4.44')
end
end
+
+ within("#modal-mrwidget-reports") do
+ expect(page).to have_content('Test#sum when a is 4 and b is 4 returns summary')
+ expect(page).to have_content('4.44')
+ end
end
end
end
@@ -825,10 +840,13 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
within(".js-report-section-container") do
click_button 'addTest'
-
- expect(page).to have_content('5.55')
end
end
+
+ within("#modal-mrwidget-reports") do
+ expect(page).to have_content('addTest')
+ expect(page).to have_content('5.55')
+ end
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 107fc002ebd..77d2cb77ae3 100644
--- a/spec/features/merge_request/user_sees_pipelines_spec.rb
+++ b/spec/features/merge_request/user_sees_pipelines_spec.rb
@@ -184,7 +184,7 @@ RSpec.describe 'Merge request > User sees pipelines', :js do
page.within(first('.commit')) do
page.within('.pipeline-tags') do
- expect(page.find('.js-pipeline-url-link')[:href]).to include(expected_project.full_path)
+ expect(page.find('[data-testid="pipeline-url-link"]')[:href]).to include(expected_project.full_path)
expect(page).to have_content('detached')
end
page.within('.pipeline-triggerer') do
@@ -238,11 +238,15 @@ RSpec.describe 'Merge request > User sees pipelines', :js do
threads = []
threads << Thread.new do
- @merge_request = MergeRequests::CreateService.new(project, user, merge_request_params).execute
+ Sidekiq::Worker.skipping_transaction_check do
+ @merge_request = MergeRequests::CreateService.new(project, user, merge_request_params).execute
+ end
end
threads << Thread.new do
- @pipeline = Ci::CreatePipelineService.new(project, user, build_push_data).execute(:push)
+ Sidekiq::Worker.skipping_transaction_check do
+ @pipeline = Ci::CreatePipelineService.new(project, user, build_push_data).execute(:push)
+ end
end
threads.each { |thr| thr.join }
diff --git a/spec/features/merge_request/user_sees_versions_spec.rb b/spec/features/merge_request/user_sees_versions_spec.rb
index 8930c55a28c..8999c4d6656 100644
--- a/spec/features/merge_request/user_sees_versions_spec.rb
+++ b/spec/features/merge_request/user_sees_versions_spec.rb
@@ -191,7 +191,7 @@ RSpec.describe 'Merge request > User sees versions', :js do
find('.btn-default').click
click_link 'version 1'
end
- expect(page).to have_content '0 files'
+ expect(page).to have_content 'No changes between version 1 and version 1'
end
end
@@ -217,7 +217,7 @@ RSpec.describe 'Merge request > User sees versions', :js do
expect(page).to have_content 'version 1'
end
- expect(page).to have_content '0 files'
+ expect(page).to have_content 'No changes between version 1 and version 1'
end
end
diff --git a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
index 1e1888cd826..a2ec34335ec 100644
--- a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
+++ b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
@@ -87,6 +87,7 @@ RSpec.describe 'User comments on a diff', :js do
expect(page).not_to have_content('Applied')
click_button('Apply suggestion')
+ click_button('Apply')
wait_for_requests
expect(page).to have_content('Applied')
@@ -338,6 +339,7 @@ RSpec.describe 'User comments on a diff', :js do
expect(page).not_to have_content('Applied')
click_button('Apply suggestion')
+ click_button('Apply')
wait_for_requests
expect(page).to have_content('Applied')
@@ -349,6 +351,7 @@ RSpec.describe 'User comments on a diff', :js do
expect(page).not_to have_content('Unresolve thread')
click_button('Apply suggestion')
+ click_button('Apply')
wait_for_requests
expect(page).to have_content('Unresolve thread')
diff --git a/spec/features/merge_request/user_uses_quick_actions_spec.rb b/spec/features/merge_request/user_uses_quick_actions_spec.rb
index 04a2e046f42..b48659353ec 100644
--- a/spec/features/merge_request/user_uses_quick_actions_spec.rb
+++ b/spec/features/merge_request/user_uses_quick_actions_spec.rb
@@ -41,5 +41,6 @@ RSpec.describe 'Merge request > User uses quick actions', :js do
end
it_behaves_like 'merge quick action'
+ it_behaves_like 'rebase quick action'
end
end
diff --git a/spec/features/projects/ci/lint_spec.rb b/spec/features/projects/ci/lint_spec.rb
index 466c7ba215e..ccffe25f45e 100644
--- a/spec/features/projects/ci/lint_spec.rb
+++ b/spec/features/projects/ci/lint_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe 'CI Lint', :js do
end
it 'parses Yaml and displays the jobs' do
- expect(page).to have_content('Status: syntax is correct')
+ expect(page).to have_content('Status: Syntax is correct')
within "table" do
aggregate_failures do
@@ -51,7 +51,7 @@ RSpec.describe 'CI Lint', :js do
let(:yaml_content) { 'value: cannot have :' }
it 'displays information about an error' do
- expect(page).to have_content('Status: syntax is incorrect')
+ expect(page).to have_content('Status: Syntax is incorrect')
expect(page).to have_selector(content_selector, text: yaml_content)
end
end
diff --git a/spec/features/projects/commit/user_reverts_commit_spec.rb b/spec/features/projects/commit/user_reverts_commit_spec.rb
index ca4e070703b..f3c364dab97 100644
--- a/spec/features/projects/commit/user_reverts_commit_spec.rb
+++ b/spec/features/projects/commit/user_reverts_commit_spec.rb
@@ -5,8 +5,8 @@ require 'spec_helper'
RSpec.describe 'User reverts a commit', :js do
include RepoHelpers
+ let_it_be(:user) { create(:user) }
let(:project) { create(:project, :repository, namespace: user.namespace) }
- let(:user) { create(:user) }
before do
sign_in(user)
@@ -14,49 +14,37 @@ RSpec.describe 'User reverts a commit', :js do
visit(project_commit_path(project, sample_commit.id))
end
- def click_revert
+ def revert_commit(create_merge_request: false)
find('.header-action-buttons .dropdown').click
- find('a[href="#modal-revert-commit"]').click
- end
+ find('[data-testid="revert-commit-link"]').click
- context 'without creating a new merge request' do
- before do
- click_revert
- page.within('#modal-revert-commit') do
- uncheck('create_merge_request')
- click_button('Revert')
- end
+ page.within('[data-testid="modal-commit"]') do
+ uncheck('create_merge_request') unless create_merge_request
+ click_button('Revert')
end
+ end
+ context 'without creating a new merge request' do
it 'reverts a commit' do
+ revert_commit
+
expect(page).to have_content('The commit has been successfully reverted.')
end
it 'does not revert a previously reverted commit' do
+ revert_commit
# Visit the comment again once it was reverted.
visit project_commit_path(project, sample_commit.id)
- find('.header-action-buttons .dropdown').click
- find('a[href="#modal-revert-commit"]').click
-
- page.within('#modal-revert-commit') do
- uncheck('create_merge_request')
- click_button('Revert')
- end
+ revert_commit
expect(page).to have_content('Sorry, we cannot revert this commit automatically.')
end
end
context 'with creating a new merge request' do
- before do
- click_revert
- end
-
it 'reverts a commit' do
- page.within('#modal-revert-commit') do
- click_button('Revert')
- end
+ revert_commit(create_merge_request: true)
expect(page).to have_content('The commit has been successfully reverted. You can now submit a merge request to get this change into the original branch.')
expect(page).to have_content("From revert-#{Commit.truncate_sha(sample_commit.id)} into master")
diff --git a/spec/features/projects/environments_pod_logs_spec.rb b/spec/features/projects/environments_pod_logs_spec.rb
index c491cd62d85..eaef3e6ca28 100644
--- a/spec/features/projects/environments_pod_logs_spec.rb
+++ b/spec/features/projects/environments_pod_logs_spec.rb
@@ -17,6 +17,8 @@ RSpec.describe 'Environment > Pod Logs', :js, :kubeclient do
stub_kubeclient_pods(environment.deployment_namespace)
stub_kubeclient_logs(pod_name, environment.deployment_namespace, container: 'container-0')
+ stub_kubeclient_deployments(environment.deployment_namespace)
+ stub_kubeclient_ingresses(environment.deployment_namespace)
stub_kubeclient_nodes_and_nodes_metrics(cluster.platform.api_url)
sign_in(project.owner)
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 750f4dc5ef4..f5941d0ff15 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
@@ -25,7 +25,6 @@ RSpec.describe 'User sees feature flag list', :js do
create_flag(project, 'mr_train', true).tap do |feature_flag|
create_scope(feature_flag, 'production', false)
end
- stub_feature_flags(feature_flags_legacy_read_only_override: false)
end
it 'user sees the first flag' do
@@ -79,41 +78,6 @@ RSpec.describe 'User sees feature flag list', :js do
expect_status_toggle_button_to_be_disabled
end
end
-
- context 'when legacy feature flags are not read-only' do
- before do
- stub_feature_flags(feature_flags_legacy_read_only: false)
- end
-
- it 'user updates the status toggle' do
- visit(project_feature_flags_path(project))
-
- within_feature_flag_row(1) do
- status_toggle_button.click
-
- expect_status_toggle_button_to_be_checked
- end
- end
- end
-
- context 'when legacy feature flags are read-only but the override is active for a project' do
- before do
- stub_feature_flags(
- feature_flags_legacy_read_only: true,
- feature_flags_legacy_read_only_override: project
- )
- end
-
- it 'user updates the status toggle' do
- visit(project_feature_flags_path(project))
-
- within_feature_flag_row(1) do
- status_toggle_button.click
-
- expect_status_toggle_button_to_be_checked
- end
- end
- end
end
context 'with new version flags' do
diff --git a/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb b/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb
index bc2d63e1953..a435e565ff1 100644
--- a/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb
+++ b/spec/features/projects/feature_flags/user_updates_feature_flag_spec.rb
@@ -14,8 +14,7 @@ RSpec.describe 'User updates feature flag', :js do
before do
stub_feature_flags(
- feature_flag_permissions: false,
- feature_flags_legacy_read_only_override: false
+ feature_flag_permissions: false
)
sign_in(user)
end
@@ -79,117 +78,11 @@ RSpec.describe 'User updates feature flag', :js do
let!(:scope) { create_scope(feature_flag, 'review/*', true) }
- context 'when legacy flags are editable' do
- before do
- stub_feature_flags(feature_flags_legacy_read_only: false)
-
- visit(edit_project_feature_flag_path(project, feature_flag))
- end
-
- it 'user sees persisted default scope' do
- within_scope_row(1) do
- within_environment_spec do
- expect(page).to have_content('* (All Environments)')
- end
-
- within_status do
- expect(find('.project-feature-toggle')['aria-label'])
- .to eq('Toggle Status: ON')
- end
- end
- end
-
- context 'when user updates the status of a scope' do
- before do
- within_scope_row(2) do
- within_status { find('.project-feature-toggle').click }
- end
-
- click_button 'Save changes'
- expect(page).to have_current_path(project_feature_flags_path(project))
- end
-
- it 'shows the updated feature flag' do
- within_feature_flag_row(1) do
- expect(page.find('.feature-flag-name')).to have_content('ci_live_trace')
- expect_status_toggle_button_to_be_checked
-
- within_feature_flag_scopes do
- expect(page.find('.badge:nth-child(1)')).to have_content('*')
- expect(page.find('.badge:nth-child(1)')['class']).to include('badge-info')
- expect(page.find('.badge:nth-child(2)')).to have_content('review/*')
- expect(page.find('.badge:nth-child(2)')['class']).to include('badge-muted')
- end
- end
- end
- end
-
- context 'when user adds a new scope' do
- before do
- within_scope_row(3) do
- within_environment_spec do
- find('.js-env-search > input').set('production')
- find('.js-create-button').click
- end
- end
-
- click_button 'Save changes'
- expect(page).to have_current_path(project_feature_flags_path(project))
- end
-
- it 'shows the newly created scope' do
- within_feature_flag_row(1) do
- within_feature_flag_scopes do
- expect(page.find('.badge:nth-child(3)')).to have_content('production')
- expect(page.find('.badge:nth-child(3)')['class']).to include('badge-muted')
- end
- end
- end
- end
-
- context 'when user deletes a scope' do
- before do
- within_scope_row(2) do
- within_delete { find('.js-delete-scope').click }
- end
-
- click_button 'Save changes'
- expect(page).to have_current_path(project_feature_flags_path(project))
- end
-
- it 'shows the updated feature flag' do
- within_feature_flag_row(1) do
- within_feature_flag_scopes do
- expect(page).to have_css('.badge:nth-child(1)')
- expect(page).not_to have_css('.badge:nth-child(2)')
- end
- end
- end
- end
- end
-
- context 'when legacy flags are read-only' do
- it 'the user cannot edit the flag' do
- visit(edit_project_feature_flag_path(project, feature_flag))
-
- expect(page).to have_text 'This feature flag is read-only, and it will be removed in 14.0.'
- expect(page).to have_css('button.js-ff-submit.disabled')
- end
- end
-
- context 'when legacy flags are read-only, but the override is active for one project' do
- it 'the user can edit the flag' do
- stub_feature_flags(feature_flags_legacy_read_only_override: project)
-
- visit(edit_project_feature_flag_path(project, feature_flag))
- status_toggle_button.click
- click_button 'Save changes'
+ it 'the user cannot edit the flag' do
+ visit(edit_project_feature_flag_path(project, feature_flag))
- expect(page).to have_current_path(project_feature_flags_path(project))
- within_feature_flag_row(1) do
- expect_status_toggle_button_not_to_be_checked
- end
- end
+ expect(page).to have_text 'This feature flag is read-only, and it will be removed in 14.0.'
+ expect(page).to have_css('button.js-ff-submit.disabled')
end
end
end
diff --git a/spec/features/projects/files/dockerfile_dropdown_spec.rb b/spec/features/projects/files/dockerfile_dropdown_spec.rb
index a99df8a79d8..17258f7042f 100644
--- a/spec/features/projects/files/dockerfile_dropdown_spec.rb
+++ b/spec/features/projects/files/dockerfile_dropdown_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Projects > Files > User wants to add a Dockerfile file' do
+RSpec.describe 'Projects > Files > User wants to add a Dockerfile file', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297400' do
before do
project = create(:project, :repository)
sign_in project.owner
diff --git a/spec/features/projects/files/gitlab_ci_syntax_yml_dropdown_spec.rb b/spec/features/projects/files/gitlab_ci_syntax_yml_dropdown_spec.rb
new file mode 100644
index 00000000000..6308acb41f5
--- /dev/null
+++ b/spec/features/projects/files/gitlab_ci_syntax_yml_dropdown_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Files > User wants to add a .gitlab-ci.yml file' do
+ before do
+ project = create(:project, :repository)
+ sign_in project.owner
+ stub_experiment(ci_syntax_templates: experiment_active)
+ stub_experiment_for_subject(ci_syntax_templates: in_experiment_group)
+
+ visit project_new_blob_path(project, 'master', file_name: '.gitlab-ci.yml')
+ end
+
+ context 'when experiment is not active' do
+ let(:experiment_active) { false }
+ let(:in_experiment_group) { false }
+
+ it 'does not show the "Learn CI/CD syntax" template dropdown' do
+ expect(page).not_to have_css('.gitlab-ci-syntax-yml-selector')
+ end
+ end
+
+ context 'when experiment is active and the user is in the control group' do
+ let(:experiment_active) { true }
+ let(:in_experiment_group) { false }
+
+ it 'does not show the "Learn CI/CD syntax" template dropdown' do
+ expect(page).not_to have_css('.gitlab-ci-syntax-yml-selector')
+ end
+ end
+
+ context 'when experiment is active and the user is in the experimental group' do
+ let(:experiment_active) { true }
+ let(:in_experiment_group) { true }
+
+ it 'allows the user to pick a "Learn CI/CD syntax" template from the dropdown', :js,
+ { quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297347' } } do
+ expect(page).to have_css('.gitlab-ci-syntax-yml-selector')
+
+ find('.js-gitlab-ci-syntax-yml-selector').click
+
+ wait_for_requests
+
+ within '.gitlab-ci-syntax-yml-selector' do
+ find('.dropdown-input-field').set('Artifacts example')
+ find('.dropdown-content .is-focused', text: 'Artifacts example').click
+ end
+
+ wait_for_requests
+
+ expect(page).to have_css('.gitlab-ci-syntax-yml-selector .dropdown-toggle-text', text: 'Learn CI/CD syntax')
+ expect(page).to have_content('You can use artifacts to pass data to jobs in later stages.')
+ end
+ end
+end
diff --git a/spec/features/projects/issues/design_management/user_uploads_designs_spec.rb b/spec/features/projects/issues/design_management/user_uploads_designs_spec.rb
index b5d5527bbfe..bfa7be5bb5c 100644
--- a/spec/features/projects/issues/design_management/user_uploads_designs_spec.rb
+++ b/spec/features/projects/issues/design_management/user_uploads_designs_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe 'User uploads new design', :js do
let(:feature_enabled) { false }
it 'shows the message about requirements' do
- expect(page).to have_content("To upload designs, you'll need to enable LFS and have admin enable hashed storage.")
+ expect(page).to have_content("To upload designs, you'll need to enable LFS and have an admin enable hashed storage.")
end
end
diff --git a/spec/features/projects/issues/email_participants_spec.rb b/spec/features/projects/issues/email_participants_spec.rb
new file mode 100644
index 00000000000..3ffe0a5ced8
--- /dev/null
+++ b/spec/features/projects/issues/email_participants_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'viewing an issue', :js do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:issue) { create(:issue, project: project) }
+ let_it_be(:note) { create(:note_on_issue, project: project, noteable: issue) }
+ let_it_be(:participants) { create_list(:issue_email_participant, 4, issue: issue) }
+
+ before do
+ sign_in(user)
+ visit project_issue_path(project, issue)
+ end
+
+ shared_examples 'email participants warning' do |selector|
+ it 'shows the correct message' do
+ expect(find(selector)).to have_content(", and 1 more will be notified of your comment")
+ end
+ end
+
+ context 'for a new note' do
+ it_behaves_like 'email participants warning', '.new-note'
+ end
+
+ context 'for a reply form' do
+ before do
+ find('.js-reply-button').click
+ end
+
+ it_behaves_like 'email participants warning', '.note-edit-form'
+ end
+end
diff --git a/spec/features/projects/jobs/permissions_spec.rb b/spec/features/projects/jobs/permissions_spec.rb
index b1e8127c54c..e87880d74b1 100644
--- a/spec/features/projects/jobs/permissions_spec.rb
+++ b/spec/features/projects/jobs/permissions_spec.rb
@@ -179,34 +179,6 @@ RSpec.describe 'Project Jobs Permissions' do
expect(status_code).to eq(expected_status_code)
end
end
-
- context 'when restrict_access_to_build_debug_mode feature not enabled' do
- where(:public_builds, :user_project_role, :ci_debug_trace, :expected_status_code) do
- true | 'developer' | true | 200
- true | 'guest' | true | 200
- true | 'developer' | false | 200
- true | 'guest' | false | 200
- false | 'developer' | true | 200
- false | 'guest' | true | 403
- false | 'developer' | false | 200
- false | 'guest' | false | 403
- end
-
- with_them do
- before do
- stub_feature_flags(restrict_access_to_build_debug_mode: false)
- ci_instance_variable.update!(value: ci_debug_trace)
- project.update!(public_builds: public_builds)
- project.add_role(user, user_project_role)
- end
-
- it 'renders trace to authorized users' do
- visit trace_project_job_path(project, job)
-
- expect(status_code).to eq(expected_status_code)
- end
- end
- end
end
describe 'raw page' do
@@ -237,35 +209,6 @@ RSpec.describe 'Project Jobs Permissions' do
expect(page).to have_content(expected_msg)
end
end
-
- context 'when restrict_access_to_build_debug_mode feature not enabled' do
- where(:public_builds, :user_project_role, :ci_debug_trace, :expected_status_code, :expected_msg) do
- true | 'developer' | true | 200 | nil
- true | 'guest' | true | 200 | nil
- true | 'developer' | false | 200 | nil
- true | 'guest' | false | 200 | nil
- false | 'developer' | true | 200 | nil
- false | 'guest' | true | 403 | 'The current user is not authorized to access the job log'
- false | 'developer' | false | 200 | nil
- false | 'guest' | false | 403 | 'The current user is not authorized to access the job log'
- end
-
- with_them do
- before do
- stub_feature_flags(restrict_access_to_build_debug_mode: false)
- ci_instance_variable.update!(value: ci_debug_trace)
- project.update!(public_builds: public_builds)
- project.add_role(user, user_project_role)
- end
-
- it 'renders raw trace to authorized users' do
- visit raw_project_job_path(project, job)
-
- expect(status_code).to eq(expected_status_code)
- expect(page).to have_content(expected_msg)
- end
- end
- end
end
end
end
diff --git a/spec/features/projects/jobs/user_browses_jobs_spec.rb b/spec/features/projects/jobs/user_browses_jobs_spec.rb
index c768b0e281c..5abebf2320e 100644
--- a/spec/features/projects/jobs/user_browses_jobs_spec.rb
+++ b/spec/features/projects/jobs/user_browses_jobs_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe 'User browses jobs' do
it 'shows the "CI Lint" button' do
page.within('.nav-controls') do
- ci_lint_tool_link = page.find_link('CI lint')
+ ci_lint_tool_link = page.find_link('CI Lint')
expect(ci_lint_tool_link[:href]).to end_with(project_ci_lint_path(project))
end
diff --git a/spec/features/projects/members/group_members_spec.rb b/spec/features/projects/members/group_members_spec.rb
index 3060d2c6a43..aa15f04bf24 100644
--- a/spec/features/projects/members/group_members_spec.rb
+++ b/spec/features/projects/members/group_members_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'Projects members' do
+RSpec.describe 'Projects members', :js do
let(:user) { create(:user) }
let(:developer) { create(:user) }
let(:group) { create(:group, :public) }
@@ -66,62 +66,61 @@ RSpec.describe 'Projects members' do
end
end
- context 'with a group and a project invitee' do
+ context 'with a group, a project invitee, and a project requester' do
before do
+ group.request_access(group_requester)
+ project.request_access(project_requester)
group_invitee
project_invitee
visit project_project_members_path(project)
end
- it 'shows the project invitee, the project developer, and the group owner' do
+ it 'shows the group owner' do
page.within first('.content-list') do
- expect(page).to have_content('test1@abc.com')
- expect(page).not_to have_content('test2@abc.com')
-
- # Project developer
- expect(page).to have_content(developer.name)
-
# Group owner
expect(page).to have_content(user.name)
expect(page).to have_content(group.name)
end
end
- end
- context 'with a group requester' do
- before do
- group.request_access(group_requester)
- visit project_project_members_path(project)
+ it 'shows the project developer' do
+ page.within first('.content-list') do
+ # Project developer
+ expect(page).to have_content(developer.name)
+ end
end
- it 'does not appear in the project members page' do
+ it 'shows the project invitee' do
+ click_link 'Invited'
+
page.within first('.content-list') do
+ expect(page).to have_content('test1@abc.com')
+ expect(page).not_to have_content('test2@abc.com')
+ end
+ end
+
+ it 'shows the project requester' do
+ click_link 'Access requests'
+
+ page.within first('.content-list') do
+ expect(page).to have_content(project_requester.name)
expect(page).not_to have_content(group_requester.name)
end
end
end
- context 'with a group and a project requesters' do
+ context 'with a group requester' do
before do
+ stub_feature_flags(invite_members_group_modal: false)
group.request_access(group_requester)
- project.request_access(project_requester)
visit project_project_members_path(project)
end
- it 'shows the project requester, the project developer, and the group owner' do
+ it 'does not appear in the project members page' do
+ expect(page).not_to have_link('Access requests')
page.within first('.content-list') do
- expect(page).to have_content(project_requester.name)
expect(page).not_to have_content(group_requester.name)
end
-
- page.within all('.content-list').last do
- # Project developer
- expect(page).to have_content(developer.name)
-
- # Group owner
- expect(page).to have_content(user.name)
- expect(page).to have_content(group.name)
- end
end
end
diff --git a/spec/features/projects/members/groups_with_access_list_spec.rb b/spec/features/projects/members/groups_with_access_list_spec.rb
index d59f8eb4b1d..686d86b1783 100644
--- a/spec/features/projects/members/groups_with_access_list_spec.rb
+++ b/spec/features/projects/members/groups_with_access_list_spec.rb
@@ -16,6 +16,7 @@ RSpec.describe 'Projects > Members > Groups with access list', :js do
project.add_maintainer(user)
sign_in(user)
visit project_project_members_path(project)
+ click_groups_tab
end
it 'updates group access level' do
@@ -29,6 +30,8 @@ RSpec.describe 'Projects > Members > Groups with access list', :js do
visit project_project_members_path(project)
+ click_groups_tab
+
expect(first('.group_member')).to have_content('Guest')
end
@@ -71,23 +74,31 @@ RSpec.describe 'Projects > Members > Groups with access list', :js do
expect(page).not_to have_selector('.group_member')
end
- context 'search in existing members (yes, this filters the groups list as well)' do
+ context 'search in existing members' do
it 'finds no results' do
page.within '.user-search-form' do
- fill_in 'search', with: 'testing 123'
+ fill_in 'search_groups', with: 'testing 123'
find('.user-search-btn').click
end
+ click_groups_tab
+
expect(page).not_to have_selector('.group_member')
end
it 'finds results' do
page.within '.user-search-form' do
- fill_in 'search', with: group.name
+ fill_in 'search_groups', with: group.name
find('.user-search-btn').click
end
+ click_groups_tab
+
expect(page).to have_selector('.group_member', count: 1)
end
end
+
+ def click_groups_tab
+ click_link 'Groups'
+ end
end
diff --git a/spec/features/projects/members/invite_group_spec.rb b/spec/features/projects/members/invite_group_spec.rb
index 30e32ad1366..bb56ae348fb 100644
--- a/spec/features/projects/members/invite_group_spec.rb
+++ b/spec/features/projects/members/invite_group_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe 'Project > Members > Invite group', :js do
it 'the project can be shared with another group' do
visit project_project_members_path(project)
- expect(page).not_to have_css('.project-members-groups')
+ expect(page).not_to have_link 'Groups'
click_on 'invite-group-tab'
@@ -47,7 +47,9 @@ RSpec.describe 'Project > Members > Invite group', :js do
page.find('body').click
find('.btn-success').click
- page.within('.project-members-groups') do
+ click_link 'Groups'
+
+ page.within('[data-testid="project-member-groups"]') do
expect(page).to have_content(group_to_share_with.name)
end
end
@@ -132,7 +134,9 @@ RSpec.describe 'Project > Members > Invite group', :js do
end
it 'the group link shows the expiration time with a warning class' do
- page.within('.project-members-groups') do
+ click_link 'Groups'
+
+ page.within('[data-testid="project-member-groups"]') do
# Using distance_of_time_in_words_to_now because it is not the same as
# subtraction, and this way avoids time zone issues as well
expires_in_text = distance_of_time_in_words_to_now(project.project_group_links.first.expires_at)
diff --git a/spec/features/projects/members/list_spec.rb b/spec/features/projects/members/list_spec.rb
index 36ff461aac2..62115f2dce6 100644
--- a/spec/features/projects/members/list_spec.rb
+++ b/spec/features/projects/members/list_spec.rb
@@ -12,6 +12,7 @@ RSpec.describe 'Project members list' do
let(:project) { create(:project, namespace: group) }
before do
+ stub_feature_flags(invite_members_group_modal: false)
sign_in(user1)
group.add_owner(user1)
end
@@ -82,7 +83,9 @@ RSpec.describe 'Project members list' do
add_user('test@example.com', 'Reporter')
- page.within(second_row) do
+ click_link 'Invited'
+
+ page.within(first_row) do
expect(page).to have_content('test@example.com')
expect(page).to have_content('Invited')
expect(page).to have_button('Reporter')
diff --git a/spec/features/projects/members/master_manages_access_requests_spec.rb b/spec/features/projects/members/master_manages_access_requests_spec.rb
index 2fdc75dca91..4c3eaa93352 100644
--- a/spec/features/projects/members/master_manages_access_requests_spec.rb
+++ b/spec/features/projects/members/master_manages_access_requests_spec.rb
@@ -4,7 +4,6 @@ require 'spec_helper'
RSpec.describe 'Projects > Members > Maintainer manages access requests' do
it_behaves_like 'Maintainer manages access requests' do
- let(:has_tabs) { false }
let(:entity) { create(:project, :public) }
let(:members_page_path) { project_project_members_path(entity) }
end
diff --git a/spec/features/projects/members/tabs_spec.rb b/spec/features/projects/members/tabs_spec.rb
new file mode 100644
index 00000000000..bdcf02c82a4
--- /dev/null
+++ b/spec/features/projects/members/tabs_spec.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Members > Tabs' do
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, creator: user, namespace: user.namespace) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project_members) { create_list(:project_member, 2, project: project) }
+ let_it_be(:access_requests) { create_list(:project_member, 2, :access_request, project: project) }
+ let_it_be(:invites) { create_list(:project_member, 2, :invited, project: project) }
+ let_it_be(:project_group_links) { create_list(:project_group_link, 2, project: project) }
+
+ shared_examples 'active "Members" tab' do
+ it 'displays "Members" tab' do
+ expect(page).to have_selector('.nav-link.active', text: 'Members')
+ end
+ end
+
+ before do
+ allow(Kaminari.config).to receive(:default_per_page).and_return(1)
+
+ sign_in(user)
+ visit project_project_members_path(project)
+ end
+
+ where(:tab, :count) do
+ 'Members' | 3
+ 'Invited' | 2
+ 'Groups' | 2
+ 'Access requests' | 2
+ end
+
+ with_them do
+ it "renders #{params[:tab]} tab" do
+ expect(page).to have_selector('.nav-link', text: "#{tab} #{count}")
+ end
+ end
+
+ context 'displays "Members" tab by default' do
+ it_behaves_like 'active "Members" tab'
+ end
+
+ context 'when searching "Groups"', :js do
+ before do
+ click_link 'Groups'
+
+ page.within '[data-testid="group-link-search-form"]' do
+ fill_in 'search_groups', with: 'group'
+ find('button[type="submit"]').click
+ end
+ end
+
+ it 'displays "Groups" tab' do
+ expect(page).to have_selector('.nav-link.active', text: 'Groups')
+ end
+
+ context 'and then searching "Members"' do
+ before do
+ click_link 'Members 3'
+
+ page.within '[data-testid="user-search-form"]' do
+ fill_in 'search', with: 'user'
+ find('button[type="submit"]').click
+ end
+ end
+
+ it_behaves_like 'active "Members" tab'
+ end
+ end
+end
diff --git a/spec/features/projects/releases/user_creates_release_spec.rb b/spec/features/projects/releases/user_creates_release_spec.rb
index 0a5f7cc7edd..2acdf983cf2 100644
--- a/spec/features/projects/releases/user_creates_release_spec.rb
+++ b/spec/features/projects/releases/user_creates_release_spec.rb
@@ -36,7 +36,7 @@ RSpec.describe 'User creates release', :js do
expect(page.find('.ref-selector button')).to have_content(project.default_branch)
end
- context 'when the "Save release" button is clicked' do
+ context 'when the "Save release" button is clicked', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297507' do
let(:tag_name) { 'v1.0' }
let(:release_title) { 'A most magnificent release' }
let(:release_notes) { 'Best. Release. **Ever.** :rocket:' }
diff --git a/spec/features/projects/services/user_activates_alerts_spec.rb b/spec/features/projects/services/user_activates_alerts_spec.rb
deleted file mode 100644
index 8b0acdf3618..00000000000
--- a/spec/features/projects/services/user_activates_alerts_spec.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'User activates Alerts', :js do
- let_it_be(:project) { create(:project) }
- let_it_be(:user) { create(:user) }
-
- let(:service_name) { 'alerts' }
- let(:service_title) { 'Alerts endpoint' }
-
- before do
- sign_in(user)
- project.add_maintainer(user)
- end
-
- context 'when service is deactivated' do
- it 'user cannot activate service' do
- visit_project_services
-
- expect(page).to have_link(service_title)
- click_link(service_title)
-
- expect(page).to have_callout_message
- expect(page).not_to have_active_service
- expect(page).to have_toggle_active_disabled
- end
- end
-
- context 'when service is activated' do
- let_it_be(:activated_alerts_service) do
- create(:alerts_service, :active, project: project)
- end
-
- before do
- visit_alerts_service
- end
-
- it 'user cannot change settings' do
- expect(page).to have_callout_message
- expect(page).to have_active_service
- expect(page).to have_toggle_active_disabled
- expect(page).to have_button_reset_key_disabled
- end
- end
-
- private
-
- def visit_project_services
- visit(project_settings_integrations_path(project))
- end
-
- def visit_alerts_service
- visit(edit_project_service_path(project, service_name))
- end
-
- def have_callout_message
- within('.gl-alert') do
- have_content('You can now manage alert endpoint configuration in the Alerts section on the Operations settings page.')
- end
- end
-
- def have_active_service
- have_selector('.js-service-active-status[data-value="true"]')
- end
-
- def have_toggle_active_disabled
- have_selector('#activated .project-feature-toggle.is-disabled')
- end
-
- def have_button_reset_key_disabled
- have_button('Reset key', disabled: true)
- end
-end
diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb
index ffc0ecc4966..c087237fd7c 100644
--- a/spec/features/projects/settings/pipelines_settings_spec.rb
+++ b/spec/features/projects/settings/pipelines_settings_spec.rb
@@ -183,7 +183,7 @@ RSpec.describe "Projects > Settings > Pipelines settings" do
let(:page_token) { find('#registration_token').text }
before do
- click_button 'Reset runners registration token'
+ click_button 'Reset registration token'
end
it 'changes registration token' do
diff --git a/spec/features/projects/settings/user_manages_project_members_spec.rb b/spec/features/projects/settings/user_manages_project_members_spec.rb
index 3836b95a28a..726b8fb6840 100644
--- a/spec/features/projects/settings/user_manages_project_members_spec.rb
+++ b/spec/features/projects/settings/user_manages_project_members_spec.rb
@@ -57,7 +57,7 @@ RSpec.describe 'Projects > Settings > User manages project members' do
end
end
- it 'shows all members of project shared group' do
+ it 'shows all members of project shared group', :js do
group.add_owner(user)
group.add_developer(user_dmitriy)
@@ -67,7 +67,9 @@ RSpec.describe 'Projects > Settings > User manages project members' do
visit(project_project_members_path(project))
- page.within('.project-members-groups') do
+ click_link 'Groups'
+
+ page.within('[data-testid="project-member-groups"]') do
expect(page).to have_content('OpenSource')
expect(first('.group_member')).to have_content('Maintainer')
end
diff --git a/spec/features/projects/snippets/user_deletes_snippet_spec.rb b/spec/features/projects/snippets/user_deletes_snippet_spec.rb
index 6d526e60512..ca49e6a36b7 100644
--- a/spec/features/projects/snippets/user_deletes_snippet_spec.rb
+++ b/spec/features/projects/snippets/user_deletes_snippet_spec.rb
@@ -21,6 +21,8 @@ RSpec.describe 'Projects > Snippets > User deletes a snippet', :js do
click_button('Delete snippet')
wait_for_requests
- expect(page).not_to have_content(snippet.title)
+ # This assertion also confirms we did not end up on an error page
+ expect(page).to have_selector('#new_snippet_link')
+ expect(project.snippets.length).to eq(0)
end
end
diff --git a/spec/features/promotion_spec.rb b/spec/features/promotion_spec.rb
index 9344f9b56b8..8692930376f 100644
--- a/spec/features/promotion_spec.rb
+++ b/spec/features/promotion_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe 'Promotions', :js do
it 'appears in project edit page' do
visit edit_project_path(project)
- expect(find('#promote_service_desk')).to have_content 'Improve customer support with GitLab Service Desk.'
+ expect(find('#promote_service_desk')).to have_content 'Improve customer support with Service Desk'
end
it 'does not show when cookie is set' do
diff --git a/spec/features/protected_tags_spec.rb b/spec/features/protected_tags_spec.rb
index 25447db3c8d..376f990f054 100644
--- a/spec/features/protected_tags_spec.rb
+++ b/spec/features/protected_tags_spec.rb
@@ -68,7 +68,7 @@ RSpec.describe 'Protected Tags', :js do
click_on "Protect"
within(".protected-tags-list") do
- expect(page).to have_content("Protected tag (2)")
+ expect(page).to have_content("Protected tags (2)")
expect(page).to have_content("2 matching tags")
end
end
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index 5cddad81927..cc024ab8f35 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe 'Runners' do
it 'user can see a button to install runners on kubernetes clusters' do
visit project_runners_path(project)
- expect(page).to have_link('Install Runner on Kubernetes', href: project_clusters_path(project))
+ expect(page).to have_link('Install GitLab Runner on Kubernetes', href: project_clusters_path(project))
end
end
@@ -69,7 +69,7 @@ RSpec.describe 'Runners' do
visit project_runners_path(project)
within '.activated-specific-runners' do
- click_on 'Remove Runner'
+ click_on 'Remove runner'
end
expect(page).not_to have_content(specific_runner.display_name)
@@ -226,10 +226,10 @@ RSpec.describe 'Runners' do
it 'group runners are not available' do
visit project_runners_path(project)
- expect(page).to have_content 'This group does not provide any group Runners yet'
+ expect(page).to have_content 'This group does not have any group runners yet.'
- expect(page).to have_content 'Group maintainers can register group runners in the Group CI/CD settings'
- expect(page).not_to have_content 'Ask your group maintainer to set up a group Runner'
+ expect(page).to have_content 'Group maintainers can register group runners in the group\'s CI/CD settings.'
+ expect(page).not_to have_content 'Ask your group maintainer to set up a group runner'
end
end
end
@@ -241,7 +241,7 @@ RSpec.describe 'Runners' do
it 'group runners are not available' do
visit project_runners_path(project)
- expect(page).to have_content 'This project does not belong to a group and can therefore not make use of group Runners.'
+ expect(page).to have_content 'This project does not belong to a group and cannot make use of group runners.'
end
end
@@ -252,10 +252,10 @@ RSpec.describe 'Runners' do
it 'group runners are not available' do
visit project_runners_path(project)
- expect(page).to have_content 'This group does not provide any group Runners yet.'
+ expect(page).to have_content 'This group does not have any group runners yet.'
- expect(page).not_to have_content 'Group maintainers can register group runners in the Group CI/CD settings'
- expect(page).to have_content 'Ask your group maintainer to set up a group Runner.'
+ expect(page).not_to have_content 'Group maintainers can register group runners in the group\'s CI/CD settings.'
+ expect(page).to have_content 'Ask your group maintainer to set up a group runner.'
end
end
@@ -267,21 +267,21 @@ RSpec.describe 'Runners' do
it 'group runners are available' do
visit project_runners_path(project)
- expect(page).to have_content 'Available group Runners: 1'
+ expect(page).to have_content 'Available group runners: 1'
expect(page).to have_content 'group-runner'
end
it 'group runners may be disabled for a project' do
visit project_runners_path(project)
- click_on 'Disable group Runners'
+ click_on 'Disable group runners'
- expect(page).to have_content 'Enable group Runners'
+ expect(page).to have_content 'Enable group runners'
expect(project.reload.group_runners_enabled).to be false
- click_on 'Enable group Runners'
+ click_on 'Enable group runners'
- expect(page).to have_content 'Disable group Runners'
+ expect(page).to have_content 'Disable group runners'
expect(project.reload.group_runners_enabled).to be true
end
end
@@ -305,7 +305,7 @@ RSpec.describe 'Runners' do
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 Runner on Kubernetes', href: group_clusters_path(group))
+ expect(page).to have_link('Install GitLab Runner on Kubernetes', href: group_clusters_path(group))
end
end
@@ -316,7 +316,7 @@ RSpec.describe 'Runners' do
visit group_settings_ci_cd_path(group)
expect(page).not_to have_content 'No runners found'
- expect(page).to have_content 'Available Runners: 1'
+ expect(page).to have_content 'Available runners: 1'
expect(page).to have_content 'group-runner'
end
@@ -396,7 +396,7 @@ RSpec.describe 'Runners' do
visit group_settings_ci_cd_path(group)
expect(page).not_to have_content 'No runners found'
- expect(page).to have_content 'Available Runners: 1'
+ expect(page).to have_content 'Available runners: 1'
expect(page).to have_content 'project-runner'
end
diff --git a/spec/features/security/dashboard_access_spec.rb b/spec/features/security/dashboard_access_spec.rb
index 5ac4a5c1840..5430329d47d 100644
--- a/spec/features/security/dashboard_access_spec.rb
+++ b/spec/features/security/dashboard_access_spec.rb
@@ -57,7 +57,7 @@ RSpec.describe "Dashboard access" do
it { expect(new_group_path).to be_denied_for :visitor }
end
- describe "GET /profile/groups" do
+ describe "GET /dashboard/groups" do
subject { dashboard_groups_path }
it { is_expected.to be_allowed_for :admin }
diff --git a/spec/features/security/profile_access_spec.rb b/spec/features/security/profile_access_spec.rb
index 3aa8278866c..301efd2d99b 100644
--- a/spec/features/security/profile_access_spec.rb
+++ b/spec/features/security/profile_access_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe "Profile access" do
include AccessMatchers
- describe "GET /profile/keys" do
+ describe "GET /-/profile/keys" do
subject { profile_keys_path }
it { is_expected.to be_allowed_for :admin }
@@ -13,7 +13,7 @@ RSpec.describe "Profile access" do
it { is_expected.to be_denied_for :visitor }
end
- describe "GET /profile" do
+ describe "GET /-/profile" do
subject { profile_path }
it { is_expected.to be_allowed_for :admin }
@@ -21,7 +21,7 @@ RSpec.describe "Profile access" do
it { is_expected.to be_denied_for :visitor }
end
- describe "GET /profile/account" do
+ describe "GET /-/profile/account" do
subject { profile_account_path }
it { is_expected.to be_allowed_for :admin }
@@ -29,7 +29,7 @@ RSpec.describe "Profile access" do
it { is_expected.to be_denied_for :visitor }
end
- describe "GET /profile/preferences" do
+ describe "GET /-/profile/preferences" do
subject { profile_preferences_path }
it { is_expected.to be_allowed_for :admin }
@@ -37,7 +37,7 @@ RSpec.describe "Profile access" do
it { is_expected.to be_denied_for :visitor }
end
- describe "GET /profile/audit_log" do
+ describe "GET /-/profile/audit_log" do
subject { audit_log_profile_path }
it { is_expected.to be_allowed_for :admin }
@@ -45,7 +45,7 @@ RSpec.describe "Profile access" do
it { is_expected.to be_denied_for :visitor }
end
- describe "GET /profile/notifications" do
+ describe "GET /-/profile/notifications" do
subject { profile_notifications_path }
it { is_expected.to be_allowed_for :admin }
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index e4a8d836413..5a537c1d4df 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -742,65 +742,30 @@ RSpec.describe 'Login' do
end
context 'when the user did not enable 2FA' do
- context 'when `vue_2fa_recovery_codes` feature flag is disabled' do
- before do
- stub_feature_flags(vue_2fa_recovery_codes: false)
- end
-
- it 'asks to set 2FA before asking to accept the terms' do
- expect(authentication_metrics)
- .to increment(:user_authenticated_counter)
-
- visit new_user_session_path
-
- fill_in 'user_login', with: user.email
- fill_in 'user_password', with: '12345678'
-
- click_button 'Sign in'
-
- expect_to_be_on_terms_page
- click_button 'Accept terms'
-
- expect(current_path).to eq(profile_two_factor_auth_path)
-
- fill_in 'pin_code', with: user.reload.current_otp
-
- click_button 'Register with two-factor app'
-
- expect(page).to have_content('Congratulations! You have enabled Two-factor Authentication!')
-
- click_link 'Proceed'
-
- expect(current_path).to eq(profile_account_path)
- end
- end
-
- context 'when `vue_2fa_recovery_codes` feature flag is enabled' do
- it 'asks to set 2FA before asking to accept the terms', :js do
- expect(authentication_metrics)
- .to increment(:user_authenticated_counter)
+ it 'asks to set 2FA before asking to accept the terms', :js do
+ expect(authentication_metrics)
+ .to increment(:user_authenticated_counter)
- visit new_user_session_path
+ visit new_user_session_path
- fill_in 'user_login', with: user.email
- fill_in 'user_password', with: '12345678'
+ fill_in 'user_login', with: user.email
+ fill_in 'user_password', with: '12345678'
- click_button 'Sign in'
+ click_button 'Sign in'
- expect_to_be_on_terms_page
- click_button 'Accept terms'
+ expect_to_be_on_terms_page
+ click_button 'Accept terms'
- expect(current_path).to eq(profile_two_factor_auth_path)
+ expect(current_path).to eq(profile_two_factor_auth_path)
- fill_in 'pin_code', with: user.reload.current_otp
+ fill_in 'pin_code', with: user.reload.current_otp
- click_button 'Register with two-factor app'
- click_button 'Copy codes'
- click_link 'Proceed'
+ click_button 'Register with two-factor app'
+ click_button 'Copy codes'
+ click_link 'Proceed'
- expect(current_path).to eq(profile_account_path)
- expect(page).to have_content('Congratulations! You have enabled Two-factor Authentication!')
- end
+ expect(current_path).to eq(profile_account_path)
+ expect(page).to have_content('Congratulations! You have enabled Two-factor Authentication!')
end
end
diff --git a/spec/features/users/signup_spec.rb b/spec/features/users/signup_spec.rb
index bfdd1e1bdb7..5f70517224e 100644
--- a/spec/features/users/signup_spec.rb
+++ b/spec/features/users/signup_spec.rb
@@ -294,17 +294,13 @@ RSpec.describe 'Signup' do
context 'when reCAPTCHA and invisible captcha are enabled' do
before do
- InvisibleCaptcha.timestamp_enabled = true
+ stub_application_setting(invisible_captcha_enabled: true)
stub_application_setting(recaptcha_enabled: true)
allow_next_instance_of(RegistrationsController) do |instance|
allow(instance).to receive(:verify_recaptcha).and_return(true)
end
end
- after do
- InvisibleCaptcha.timestamp_enabled = false
- end
-
context 'when reCAPTCHA detects malicious behaviour' do
before do
allow_next_instance_of(RegistrationsController) do |instance|