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:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-06-20 14:10:13 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-06-20 14:10:13 +0300
commit0ea3fcec397b69815975647f5e2aa5fe944a8486 (patch)
tree7979381b89d26011bcf9bdc989a40fcc2f1ed4ff /spec/features
parent72123183a20411a36d607d70b12d57c484394c8e (diff)
Add latest changes from gitlab-org/gitlab@15-1-stable-eev15.1.0-rc42
Diffstat (limited to 'spec/features')
-rw-r--r--spec/features/admin/admin_disables_two_factor_spec.rb7
-rw-r--r--spec/features/admin/admin_groups_spec.rb11
-rw-r--r--spec/features/admin/admin_hook_logs_spec.rb14
-rw-r--r--spec/features/admin/admin_hooks_spec.rb7
-rw-r--r--spec/features/admin/admin_labels_spec.rb9
-rw-r--r--spec/features/admin/admin_runners_spec.rb91
-rw-r--r--spec/features/admin/admin_settings_spec.rb14
-rw-r--r--spec/features/admin/admin_users_impersonation_tokens_spec.rb5
-rw-r--r--spec/features/admin/admin_uses_repository_checks_spec.rb6
-rw-r--r--spec/features/admin/users/user_spec.rb3
-rw-r--r--spec/features/admin/users/users_spec.rb10
-rw-r--r--spec/features/boards/boards_spec.rb1
-rw-r--r--spec/features/clusters/cluster_detail_page_spec.rb14
-rw-r--r--spec/features/clusters/create_agent_spec.rb1
-rw-r--r--spec/features/commits_spec.rb3
-rw-r--r--spec/features/dashboard/todos/todos_spec.rb3
-rw-r--r--spec/features/group_variables_spec.rb14
-rw-r--r--spec/features/groups/clusters/user_spec.rb4
-rw-r--r--spec/features/groups/empty_states_spec.rb2
-rw-r--r--spec/features/groups/group_runners_spec.rb52
-rw-r--r--spec/features/groups/import_export/connect_instance_spec.rb2
-rw-r--r--spec/features/groups/issues_spec.rb47
-rw-r--r--spec/features/groups/members/leave_group_spec.rb4
-rw-r--r--spec/features/groups/navbar_spec.rb9
-rw-r--r--spec/features/groups/settings/access_tokens_spec.rb3
-rw-r--r--spec/features/groups/show_spec.rb52
-rw-r--r--spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb47
-rw-r--r--spec/features/groups_spec.rb15
-rw-r--r--spec/features/incidents/incidents_list_spec.rb13
-rw-r--r--spec/features/issuables/issuable_list_spec.rb2
-rw-r--r--spec/features/issue_rebalancing_spec.rb4
-rw-r--r--spec/features/issues/filtered_search/dropdown_assignee_spec.rb4
-rw-r--r--spec/features/issues/filtered_search/dropdown_author_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_base_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_emoji_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_hint_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_label_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_milestone_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_release_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/filter_issues_spec.rb1
-rw-r--r--spec/features/issues/filtered_search/recent_searches_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/search_bar_spec.rb1
-rw-r--r--spec/features/issues/filtered_search/visual_tokens_spec.rb1
-rw-r--r--spec/features/issues/incident_issue_spec.rb62
-rw-r--r--spec/features/issues/issue_detail_spec.rb10
-rw-r--r--spec/features/issues/rss_spec.rb4
-rw-r--r--spec/features/issues/user_bulk_edits_issues_labels_spec.rb4
-rw-r--r--spec/features/issues/user_bulk_edits_issues_spec.rb4
-rw-r--r--spec/features/issues/user_comments_on_issue_spec.rb14
-rw-r--r--spec/features/issues/user_creates_issue_spec.rb4
-rw-r--r--spec/features/issues/user_filters_issues_spec.rb2
-rw-r--r--spec/features/issues/user_sees_breadcrumb_links_spec.rb2
-rw-r--r--spec/features/issues/user_sorts_issues_spec.rb2
-rw-r--r--spec/features/labels_hierarchy_spec.rb2
-rw-r--r--spec/features/markdown/math_spec.rb20
-rw-r--r--spec/features/markdown/mermaid_spec.rb361
-rw-r--r--spec/features/merge_request/batch_comments_spec.rb271
-rw-r--r--spec/features/merge_request/user_comments_on_diff_spec.rb1
-rw-r--r--spec/features/merge_request/user_creates_merge_request_spec.rb3
-rw-r--r--spec/features/merge_request/user_posts_diff_notes_spec.rb2
-rw-r--r--spec/features/merge_request/user_posts_notes_spec.rb3
-rw-r--r--spec/features/merge_request/user_resolves_conflicts_spec.rb17
-rw-r--r--spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb1
-rw-r--r--spec/features/merge_request/user_sees_deployment_widget_spec.rb6
-rw-r--r--spec/features/merge_request/user_sees_discussions_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_versions_spec.rb1
-rw-r--r--spec/features/merge_request/user_views_user_status_on_merge_request_spec.rb10
-rw-r--r--spec/features/merge_requests/user_sorts_merge_requests_spec.rb2
-rw-r--r--spec/features/milestone_spec.rb10
-rw-r--r--spec/features/nav/top_nav_responsive_spec.rb2
-rw-r--r--spec/features/nav/top_nav_tooltip_spec.rb24
-rw-r--r--spec/features/oauth_registration_spec.rb91
-rw-r--r--spec/features/profile_spec.rb19
-rw-r--r--spec/features/profiles/active_sessions_spec.rb10
-rw-r--r--spec/features/profiles/oauth_applications_spec.rb11
-rw-r--r--spec/features/profiles/personal_access_tokens_spec.rb44
-rw-r--r--spec/features/profiles/user_visits_profile_spec.rb4
-rw-r--r--spec/features/project_variables_spec.rb38
-rw-r--r--spec/features/projects/branches/user_deletes_branch_spec.rb6
-rw-r--r--spec/features/projects/ci/editor_spec.rb10
-rw-r--r--spec/features/projects/clusters/gcp_spec.rb4
-rw-r--r--spec/features/projects/clusters/user_spec.rb4
-rw-r--r--spec/features/projects/commit/comments/user_deletes_comments_spec.rb6
-rw-r--r--spec/features/projects/commit/user_comments_on_commit_spec.rb7
-rw-r--r--spec/features/projects/commits/multi_view_diff_spec.rb128
-rw-r--r--spec/features/projects/container_registry_spec.rb2
-rw-r--r--spec/features/projects/environments/environment_spec.rb10
-rw-r--r--spec/features/projects/environments/environments_spec.rb2
-rw-r--r--spec/features/projects/features_visibility_spec.rb2
-rw-r--r--spec/features/projects/hook_logs/user_reads_log_spec.rb73
-rw-r--r--spec/features/projects/integrations/user_activates_issue_tracker_spec.rb6
-rw-r--r--spec/features/projects/integrations/user_activates_jira_spec.rb8
-rw-r--r--spec/features/projects/integrations/user_activates_mattermost_slash_command_spec.rb2
-rw-r--r--spec/features/projects/integrations/user_activates_slack_notifications_spec.rb2
-rw-r--r--spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb12
-rw-r--r--spec/features/projects/integrations/user_uses_inherited_settings_spec.rb2
-rw-r--r--spec/features/projects/jobs/user_browses_job_spec.rb9
-rw-r--r--spec/features/projects/jobs_spec.rb8
-rw-r--r--spec/features/projects/members/manage_members_spec.rb50
-rw-r--r--spec/features/projects/members/member_leaves_project_spec.rb4
-rw-r--r--spec/features/projects/members/user_requests_access_spec.rb5
-rw-r--r--spec/features/projects/new_project_spec.rb33
-rw-r--r--spec/features/projects/pages/user_adds_domain_spec.rb7
-rw-r--r--spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb9
-rw-r--r--spec/features/projects/pages/user_edits_settings_spec.rb5
-rw-r--r--spec/features/projects/pipeline_schedules_spec.rb10
-rw-r--r--spec/features/projects/pipelines/legacy_pipeline_spec.rb198
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb58
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb1
-rw-r--r--spec/features/projects/releases/user_views_edit_release_spec.rb4
-rw-r--r--spec/features/projects/settings/access_tokens_spec.rb77
-rw-r--r--spec/features/projects/settings/branch_rules_settings_spec.rb47
-rw-r--r--spec/features/projects/settings/packages_settings_spec.rb24
-rw-r--r--spec/features/projects/settings/repository_settings_spec.rb16
-rw-r--r--spec/features/projects/settings/user_searches_in_settings_spec.rb1
-rw-r--r--spec/features/promotion_spec.rb2
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/user_replaces_files_spec.rb93
-rw-r--r--spec/features/snippets/notes_on_personal_snippets_spec.rb8
-rw-r--r--spec/features/snippets/user_creates_snippet_spec.rb1
-rw-r--r--spec/features/tags/developer_deletes_tag_spec.rb17
-rw-r--r--spec/features/tags/maintainer_deletes_protected_tag_spec.rb62
-rw-r--r--spec/features/triggers_spec.rb5
-rw-r--r--spec/features/user_sorts_things_spec.rb2
-rw-r--r--spec/features/users/signup_spec.rb1
-rw-r--r--spec/features/users/zuora_csp_spec.rb20
125 files changed, 1427 insertions, 1191 deletions
diff --git a/spec/features/admin/admin_disables_two_factor_spec.rb b/spec/features/admin/admin_disables_two_factor_spec.rb
index f65e85b4cb6..4463dbb1eb0 100644
--- a/spec/features/admin/admin_disables_two_factor_spec.rb
+++ b/spec/features/admin/admin_disables_two_factor_spec.rb
@@ -3,8 +3,9 @@
require 'spec_helper'
RSpec.describe 'Admin disables 2FA for a user' do
+ include Spec::Support::Helpers::ModalHelpers
+
it 'successfully', :js do
- stub_feature_flags(bootstrap_confirmation_modals: false)
admin = create(:admin)
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
@@ -12,9 +13,11 @@ RSpec.describe 'Admin disables 2FA for a user' do
edit_user(user)
page.within('.two-factor-status') do
- accept_confirm { click_link 'Disable' }
+ click_link 'Disable'
end
+ accept_gl_confirm(button_text: 'Disable')
+
page.within('.two-factor-status') do
expect(page).to have_content 'Disabled'
expect(page).not_to have_button 'Disable'
diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb
index 90dde7340d5..2d541a34f62 100644
--- a/spec/features/admin/admin_groups_spec.rb
+++ b/spec/features/admin/admin_groups_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'Admin Groups' do
end
end
- describe 'create a group' do
+ describe 'create a group', :js do
describe 'with expected fields' do
it 'renders from as expected', :aggregate_failures do
visit new_admin_group_path
@@ -60,8 +60,7 @@ RSpec.describe 'Admin Groups' do
expect(page).to have_current_path admin_group_path(Group.find_by(path: path_component)), ignore_query: true
content = page.find('#content-body')
- h3_texts = content.all('h3').collect(&:text).join("\n")
- expect(h3_texts).to match group_name
+ expect(page).to have_content group_name
li_texts = content.all('li').collect(&:text).join("\n")
expect(li_texts).to match group_name
expect(li_texts).to match path_component
@@ -76,7 +75,7 @@ RSpec.describe 'Admin Groups' do
expect_selected_visibility(internal)
end
- it 'when entered in group name, it auto filled the group path', :js do
+ it 'when entered in group name, it auto filled the group path' do
visit admin_groups_path
click_link "New group"
group_name = 'gitlab'
@@ -85,7 +84,7 @@ RSpec.describe 'Admin Groups' do
expect(path_field.value).to eq group_name
end
- it 'auto populates the group path with the group name', :js do
+ it 'auto populates the group path with the group name' do
visit admin_groups_path
click_link "New group"
group_name = 'my gitlab project'
@@ -94,7 +93,7 @@ RSpec.describe 'Admin Groups' do
expect(path_field.value).to eq 'my-gitlab-project'
end
- it 'when entering in group path, group name does not change anymore', :js do
+ it 'when entering in group path, group name does not change anymore' do
visit admin_groups_path
click_link "New group"
group_path = 'my-gitlab-project'
diff --git a/spec/features/admin/admin_hook_logs_spec.rb b/spec/features/admin/admin_hook_logs_spec.rb
index fd51fd71fea..6caf2b24555 100644
--- a/spec/features/admin/admin_hook_logs_spec.rb
+++ b/spec/features/admin/admin_hook_logs_spec.rb
@@ -41,4 +41,18 @@ RSpec.describe 'Admin::HookLogs' do
expect(page).to have_current_path(edit_admin_hook_path(system_hook), ignore_query: true)
end
+
+ context 'response data is too large' do
+ let(:hook_log) { create(:web_hook_log, web_hook: system_hook, request_data: WebHookLog::OVERSIZE_REQUEST_DATA) }
+
+ it 'shows request data as too large and disables retry function' do
+ visit(admin_hook_hook_log_path(system_hook, hook_log))
+
+ expect(page).to have_content('Request data is too large')
+ expect(page).not_to have_button(
+ _('Resent request'),
+ disabled: true, class: 'has-tooltip', title: _("Request data is too large")
+ )
+ end
+ end
end
diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb
index 388ab02d8e8..901315752d6 100644
--- a/spec/features/admin/admin_hooks_spec.rb
+++ b/spec/features/admin/admin_hooks_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Admin::Hooks' do
+ include Spec::Support::Helpers::ModalHelpers
+
let(:user) { create(:admin) }
before do
@@ -79,7 +81,6 @@ RSpec.describe 'Admin::Hooks' do
let(:hook_url) { generate(:url) }
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
create(:system_hook, url: hook_url)
end
@@ -87,7 +88,7 @@ RSpec.describe 'Admin::Hooks' do
it 'from hooks list page' do
visit admin_hooks_path
- accept_confirm { click_link 'Delete' }
+ accept_gl_confirm(button_text: 'Delete webhook') { click_link 'Delete' }
expect(page).not_to have_content(hook_url)
end
@@ -95,7 +96,7 @@ RSpec.describe 'Admin::Hooks' do
visit admin_hooks_path
click_link 'Edit'
- accept_confirm { click_link 'Delete' }
+ accept_gl_confirm(button_text: 'Delete webhook') { click_link 'Delete' }
expect(page).not_to have_content(hook_url)
end
end
diff --git a/spec/features/admin/admin_labels_spec.rb b/spec/features/admin/admin_labels_spec.rb
index ba0870a53ae..fa5c94aa66e 100644
--- a/spec/features/admin/admin_labels_spec.rb
+++ b/spec/features/admin/admin_labels_spec.rb
@@ -16,7 +16,6 @@ RSpec.describe 'admin issues labels' do
describe 'list' do
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
visit admin_labels_path
end
@@ -38,11 +37,9 @@ RSpec.describe 'admin issues labels' do
end
it 'deletes all labels', :js do
- page.within '.labels' do
- page.all('.js-remove-label').each do |remove|
- accept_confirm { remove.click }
- wait_for_requests
- end
+ page.all('.labels .js-remove-label').each do |remove|
+ accept_gl_confirm(button_text: 'Delete label') { remove.click }
+ wait_for_requests
end
wait_for_requests
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index e1a1e2bbb2d..d312965f6cf 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -115,13 +115,17 @@ RSpec.describe "Admin Runners" do
expect(page).not_to have_content("runner-bar")
end
- it 'shows no runner when description does not match' do
- input_filtered_search_keys('runner-baz')
+ context 'when description does not match' do
+ before do
+ input_filtered_search_keys('runner-baz')
+ end
- expect(page).to have_link('All 0')
- expect(page).to have_link('Instance 0')
+ it_behaves_like 'shows no runners found'
- expect(page).to have_text 'No runners found'
+ it 'shows no runner' do
+ expect(page).to have_link('All 0')
+ expect(page).to have_link('Instance 0')
+ end
end
end
@@ -190,14 +194,6 @@ RSpec.describe "Admin Runners" do
expect(page).not_to have_content 'runner-never-contacted'
end
- it 'shows no runner when status does not match' do
- input_filtered_search_filter_is_only('Status', 'Stale')
-
- expect(page).to have_link('All 0')
-
- expect(page).to have_text 'No runners found'
- end
-
it 'shows correct runner when status is selected and search term is entered' do
input_filtered_search_filter_is_only('Status', 'Online')
input_filtered_search_keys('runner-1')
@@ -225,6 +221,18 @@ RSpec.describe "Admin Runners" do
expect(page).to have_selector '.badge', text: 'never contacted'
end
end
+
+ context 'when status does not match' do
+ before do
+ input_filtered_search_filter_is_only('Status', 'Stale')
+ end
+
+ it_behaves_like 'shows no runners found'
+
+ it 'shows no runner' do
+ expect(page).to have_link('All 0')
+ end
+ end
end
describe 'filter by type' do
@@ -273,21 +281,6 @@ RSpec.describe "Admin Runners" do
end
end
- it 'shows no runner when type does not match' do
- visit admin_runners_path
-
- page.within('[data-testid="runner-type-tabs"]') do
- click_on 'Instance'
-
- expect(page).to have_link('Instance', class: 'active')
- end
-
- expect(page).not_to have_content 'runner-project'
- expect(page).not_to have_content 'runner-group'
-
- expect(page).to have_text 'No runners found'
- end
-
it 'shows correct runner when type is selected and search term is entered' do
create(:ci_runner, :project, description: 'runner-2-project', projects: [project])
@@ -327,6 +320,24 @@ RSpec.describe "Admin Runners" do
expect(page).not_to have_content 'runner-group'
expect(page).not_to have_content 'runner-paused-project'
end
+
+ context 'when type does not match' do
+ before do
+ visit admin_runners_path
+ page.within('[data-testid="runner-type-tabs"]') do
+ click_on 'Instance'
+
+ expect(page).to have_link('Instance', class: 'active')
+ end
+ end
+
+ it_behaves_like 'shows no runners found'
+
+ it 'shows no runner' do
+ expect(page).not_to have_content 'runner-project'
+ expect(page).not_to have_content 'runner-group'
+ end
+ end
end
describe 'filter by tag' do
@@ -358,15 +369,6 @@ RSpec.describe "Admin Runners" do
expect(page).not_to have_content 'runner-red'
end
- it 'shows no runner when tag does not match' do
- visit admin_runners_path
-
- input_filtered_search_filter_is_only('Tags', 'green')
-
- expect(page).not_to have_content 'runner-blue'
- expect(page).to have_text 'No runners found'
- end
-
it 'shows correct runner when tag is selected and search term is entered' do
create(:ci_runner, :instance, description: 'runner-2-blue', tag_list: ['blue'])
@@ -384,6 +386,19 @@ RSpec.describe "Admin Runners" do
expect(page).not_to have_content 'runner-blue'
expect(page).not_to have_content 'runner-red'
end
+
+ context 'when tag does not match' do
+ before do
+ visit admin_runners_path
+ input_filtered_search_filter_is_only('Tags', 'green')
+ end
+
+ it_behaves_like 'shows no runners found'
+
+ it 'shows no runner' do
+ expect(page).not_to have_content 'runner-blue'
+ end
+ end
end
it 'sorts by last contact date' do
@@ -419,7 +434,7 @@ RSpec.describe "Admin Runners" do
visit admin_runners_path
end
- it_behaves_like "shows no runners"
+ it_behaves_like 'shows no runners registered'
it 'shows tabs with total counts equal to 0' do
expect(page).to have_link('All 0')
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 79b3f049047..8843e13026b 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -61,7 +61,7 @@ RSpec.describe 'Admin updates settings' do
expect(current_settings.import_sources).to be_empty
page.within('.as-visibility-access') do
- check "Repo by URL"
+ check "Repository by URL"
click_button 'Save changes'
end
@@ -280,6 +280,18 @@ RSpec.describe 'Admin updates settings' do
expect(current_settings.gitpod_enabled).to be(true)
end
end
+
+ context 'GitLab for Jira App settings' do
+ it 'changes the setting' do
+ page.within('#js-jira_connect-settings') do
+ fill_in 'Jira Connect Application ID', with: '1234'
+ click_button 'Save changes'
+ end
+
+ expect(current_settings.jira_connect_application_key).to eq('1234')
+ expect(page).to have_content "Application settings saved successfully"
+ end
+ end
end
context 'Integrations page' do
diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
index 15bc2318022..7e57cffc791 100644
--- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb
+++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
+ include Spec::Support::Helpers::ModalHelpers
+
let(:admin) { create(:admin) }
let!(:user) { create(:user) }
@@ -74,10 +76,9 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
let!(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) }
it "allows revocation of an active impersonation token" do
- stub_feature_flags(bootstrap_confirmation_modals: false)
visit admin_user_impersonation_tokens_path(user_id: user.username)
- accept_confirm { click_on "Revoke" }
+ accept_gl_confirm(button_text: 'Revoke') { click_on "Revoke" }
expect(page).to have_selector(".settings-message")
expect(no_personal_access_tokens_message).to have_text("This user has no active impersonation tokens.")
diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb
index 4e6aae7c46f..2dffef93600 100644
--- a/spec/features/admin/admin_uses_repository_checks_spec.rb
+++ b/spec/features/admin/admin_uses_repository_checks_spec.rb
@@ -4,11 +4,11 @@ require 'spec_helper'
RSpec.describe 'Admin uses repository checks', :request_store do
include StubENV
+ include Spec::Support::Helpers::ModalHelpers
let(:admin) { create(:admin) }
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
sign_in(admin)
end
@@ -57,7 +57,9 @@ RSpec.describe 'Admin uses repository checks', :request_store do
expect(RepositoryCheck::ClearWorker).to receive(:perform_async)
- accept_confirm { find(:link, 'Clear all repository checks').send_keys(:return) }
+ accept_gl_confirm(button_text: 'Clear repository checks') do
+ find(:link, 'Clear all repository checks').send_keys(:return)
+ end
expect(page).to have_content('Started asynchronous removal of all repository check states.')
end
diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb
index 7e8dee9cc0b..18bb03f4617 100644
--- a/spec/features/admin/users/user_spec.rb
+++ b/spec/features/admin/users/user_spec.rb
@@ -10,7 +10,6 @@ RSpec.describe 'Admin::Users::User' do
let_it_be(:current_user) { create(:admin) }
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(current_user)
gitlab_enable_admin_mode_sign_in(current_user)
end
@@ -354,7 +353,7 @@ RSpec.describe 'Admin::Users::User' do
expect(page).to have_content("Secondary email: #{secondary_email.email}")
- accept_confirm { find("#remove_email_#{secondary_email.id}").click }
+ accept_gl_confirm { find("#remove_email_#{secondary_email.id}").click }
expect(page).not_to have_content(secondary_email.email)
end
diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb
index a05e1531949..e5df6cc0fd3 100644
--- a/spec/features/admin/users/users_spec.rb
+++ b/spec/features/admin/users/users_spec.rb
@@ -10,7 +10,6 @@ RSpec.describe 'Admin::Users' do
let_it_be(:current_user) { create(:admin) }
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(current_user)
gitlab_enable_admin_mode_sign_in(current_user)
end
@@ -492,9 +491,7 @@ RSpec.describe 'Admin::Users' do
within(:css, '.gl-mb-3 + .card') do
click_link group.name
end
- within(:css, 'h3.page-title') do
- expect(page).to have_content "Group: #{group.name}"
- end
+ expect(page).to have_content "Group: #{group.name}"
expect(page).to have_content project.name
end
@@ -506,8 +503,11 @@ RSpec.describe 'Admin::Users' do
it 'allows group membership to be revoked', :js do
page.within(first('.group_member')) do
- accept_confirm { find('.btn[data-testid="remove-user"]').click }
+ find('.btn[data-testid="remove-user"]').click
end
+
+ accept_gl_confirm(button_text: 'Remove')
+
wait_for_requests
expect(page).not_to have_selector('.group_member')
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index bf976168bbe..e8321adeb42 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -521,7 +521,6 @@ RSpec.describe 'Project issue boards', :js do
let_it_be(:user_guest) { create(:user) }
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
project.add_guest(user_guest)
sign_in(user_guest)
visit project_board_path(project, board)
diff --git a/spec/features/clusters/cluster_detail_page_spec.rb b/spec/features/clusters/cluster_detail_page_spec.rb
index 09e042b00cc..06e3e00db7d 100644
--- a/spec/features/clusters/cluster_detail_page_spec.rb
+++ b/spec/features/clusters/cluster_detail_page_spec.rb
@@ -36,20 +36,6 @@ RSpec.describe 'Clusterable > Show page' do
expect(page).not_to have_selector('[data-testid="cluster-environments-tab"]')
end
-
- context 'content-security policy' do
- it 'has AWS domains in the CSP' do
- visit cluster_path
-
- expect(response_headers['Content-Security-Policy']).to include(::Clusters::ClustersController::AWS_CSP_DOMAINS.join(' '))
- end
-
- it 'keeps existing connect-src in the CSP' do
- visit cluster_path
-
- expect(response_headers['Content-Security-Policy']).to include("connect-src #{Gitlab::ContentSecurityPolicy::Directives.connect_src}")
- end
- end
end
shared_examples 'editing a GCP cluster' do
diff --git a/spec/features/clusters/create_agent_spec.rb b/spec/features/clusters/create_agent_spec.rb
index c7326204bf6..b879ae645f7 100644
--- a/spec/features/clusters/create_agent_spec.rb
+++ b/spec/features/clusters/create_agent_spec.rb
@@ -35,6 +35,7 @@ RSpec.describe 'Cluster agent registration', :js do
expect(page).to have_content('You cannot see this token again after you close this window.')
expect(page).to have_content('example-agent-token')
expect(page).to have_content('helm upgrade --install')
+ expect(page).to have_content('example-agent-2')
within find('.modal-footer') do
click_button('Close')
diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb
index 4b38df175e2..db841ffc627 100644
--- a/spec/features/commits_spec.rb
+++ b/spec/features/commits_spec.rb
@@ -10,7 +10,6 @@ RSpec.describe 'Commits' do
before do
sign_in(user)
stub_ci_pipeline_to_return_yaml_file
- stub_feature_flags(pipeline_tabs_vue: false)
end
let(:creator) { create(:user, developer_projects: [project]) }
@@ -94,7 +93,6 @@ RSpec.describe 'Commits' do
context 'Download artifacts', :js do
before do
- stub_feature_flags(pipeline_tabs_vue: false)
create(:ci_job_artifact, :archive, file: artifacts_file, job: build)
end
@@ -124,7 +122,6 @@ RSpec.describe 'Commits' do
context "when logged as reporter", :js do
before do
- stub_feature_flags(pipeline_tabs_vue: false)
project.add_reporter(user)
create(:ci_job_artifact, :archive, file: artifacts_file, job: build)
visit builds_project_pipeline_path(project, pipeline)
diff --git a/spec/features/dashboard/todos/todos_spec.rb b/spec/features/dashboard/todos/todos_spec.rb
index 04e78b59ab4..adb43d60306 100644
--- a/spec/features/dashboard/todos/todos_spec.rb
+++ b/spec/features/dashboard/todos/todos_spec.rb
@@ -55,7 +55,8 @@ RSpec.describe 'Dashboard Todos' do
expect(link).not_to be_nil
expect(link['data-iid']).to eq(referenced_mr.iid.to_s)
expect(link['data-project-path']).to eq(referenced_mr.project.full_path)
- expect(link['data-mr-title']).to eq(referenced_mr.title)
+ expect(link['title']).to eq(referenced_mr.title)
+ expect(link['data-reference-type']).to eq('merge_request')
end
end
diff --git a/spec/features/group_variables_spec.rb b/spec/features/group_variables_spec.rb
index c7d37205b71..9af9baeb5bb 100644
--- a/spec/features/group_variables_spec.rb
+++ b/spec/features/group_variables_spec.rb
@@ -12,8 +12,18 @@ RSpec.describe 'Group variables', :js do
group.add_owner(user)
gitlab_sign_in(user)
wait_for_requests
- visit page_path
end
- it_behaves_like 'variable list'
+ context 'with disabled ff `ci_variable_settings_graphql' do
+ before do
+ stub_feature_flags(ci_variable_settings_graphql: false)
+ visit page_path
+ end
+
+ it_behaves_like 'variable list'
+ end
+
+ # TODO: Uncomment when the new graphQL app for variable settings
+ # is enabled.
+ # it_behaves_like 'variable list'
end
diff --git a/spec/features/groups/clusters/user_spec.rb b/spec/features/groups/clusters/user_spec.rb
index 74ea72b238f..6b512323d4d 100644
--- a/spec/features/groups/clusters/user_spec.rb
+++ b/spec/features/groups/clusters/user_spec.rb
@@ -112,9 +112,9 @@ RSpec.describe 'User Cluster', :js do
context 'when user destroys the cluster' do
before do
click_link 'Advanced Settings'
- click_button 'Remove integration and resources'
+ find('[data-testid="remove-integration-button"]').click
fill_in 'confirm_cluster_name_input', with: cluster.name
- click_button 'Remove integration'
+ find('[data-testid="remove-integration-modal-button"]').click
end
it 'user sees creation form with the successful message' do
diff --git a/spec/features/groups/empty_states_spec.rb b/spec/features/groups/empty_states_spec.rb
index 71f38401fa1..f11e5c56545 100644
--- a/spec/features/groups/empty_states_spec.rb
+++ b/spec/features/groups/empty_states_spec.rb
@@ -7,8 +7,6 @@ RSpec.describe 'Group empty states' do
let(:user) { create(:group_member, :developer, user: create(:user), group: group ).user }
before do
- stub_feature_flags(vue_issues_list: true)
-
sign_in(user)
end
diff --git a/spec/features/groups/group_runners_spec.rb b/spec/features/groups/group_runners_spec.rb
index 1d821edefa3..a60b8a60da0 100644
--- a/spec/features/groups/group_runners_spec.rb
+++ b/spec/features/groups/group_runners_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe "Group Runners" do
visit group_runners_path(group)
end
- it_behaves_like "shows no runners"
+ it_behaves_like 'shows no runners registered'
it 'shows tabs with total counts equal to 0' do
expect(page).to have_link('All 0')
@@ -70,6 +70,18 @@ RSpec.describe "Group Runners" do
expect(find_link('Edit')[:href]).to end_with(edit_group_runner_path(group, group_runner))
end
end
+
+ context 'when description does not match' do
+ before do
+ input_filtered_search_keys('runner-baz')
+ end
+
+ it_behaves_like 'shows no runners found'
+
+ it 'shows no runner' do
+ expect(page).not_to have_content 'runner-foo'
+ end
+ end
end
context "with an online project runner" do
@@ -137,31 +149,37 @@ RSpec.describe "Group Runners" do
create(:ci_runner, :group, groups: [group], description: 'runner-foo', contacted_at: Time.zone.now)
end
- it 'user edits the runner to be protected' do
- visit edit_group_runner_path(group, runner)
+ context 'when group_runner_view_ui is disabled' do
+ before do
+ stub_feature_flags(group_runner_view_ui: false)
+ end
- expect(page.find_field('runner[access_level]')).not_to be_checked
+ it 'user edits the runner to be protected' do
+ visit edit_group_runner_path(group, runner)
- check 'runner_access_level'
- click_button 'Save changes'
+ expect(page.find_field('runner[access_level]')).not_to be_checked
- expect(page).to have_content 'Protected Yes'
- end
+ check 'runner_access_level'
+ click_button 'Save changes'
- context 'when a runner has a tag' do
- before do
- runner.update!(tag_list: ['tag'])
+ expect(page).to have_content 'Protected Yes'
end
- it 'user edits runner not to run untagged jobs' do
- visit edit_group_runner_path(group, runner)
+ context 'when a runner has a tag' do
+ before do
+ runner.update!(tag_list: ['tag'])
+ end
- expect(page.find_field('runner[run_untagged]')).to be_checked
+ it 'user edits runner not to run untagged jobs' do
+ visit edit_group_runner_path(group, runner)
- uncheck 'runner_run_untagged'
- click_button 'Save changes'
+ expect(page.find_field('runner[run_untagged]')).to be_checked
- expect(page).to have_content 'Can run untagged jobs No'
+ uncheck 'runner_run_untagged'
+ click_button 'Save changes'
+
+ expect(page).to have_content 'Can run untagged jobs No'
+ end
end
end
end
diff --git a/spec/features/groups/import_export/connect_instance_spec.rb b/spec/features/groups/import_export/connect_instance_spec.rb
index 552b599a3f3..ae03e64cf59 100644
--- a/spec/features/groups/import_export/connect_instance_spec.rb
+++ b/spec/features/groups/import_export/connect_instance_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do
click_on 'Connect instance'
- expect(page).to have_content 'Showing 1-1 of 42 groups from %{url}' % { url: source_url }
+ expect(page).to have_content 'Showing 1-1 of 42 groups that you own from %{url}' % { url: source_url }
expect(page).to have_content 'stub-group'
visit '/'
diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb
index ef3346b9763..c86705832b1 100644
--- a/spec/features/groups/issues_spec.rb
+++ b/spec/features/groups/issues_spec.rb
@@ -11,10 +11,6 @@ RSpec.describe 'Group issues page' do
let(:project_with_issues_disabled) { create(:project, :issues_disabled, group: group) }
let(:path) { issues_group_path(group) }
- before do
- stub_feature_flags(vue_issues_list: true)
- end
-
context 'with shared examples', :js do
let(:issuable) { create(:issue, project: project, title: "this is my created issuable")}
@@ -140,8 +136,6 @@ RSpec.describe 'Group issues page' do
let!(:issue3) { create(:issue, project: project, title: 'Issue #3', relative_position: 3) }
before do
- stub_feature_flags(vue_issues_list: false)
-
sign_in(user_in_group)
end
@@ -164,45 +158,36 @@ RSpec.describe 'Group issues page' do
end
it 'issues should be draggable and persist order' do
- visit issues_group_path(group, sort: 'relative_position')
-
- wait_for_requests
+ visit issues_group_path(group)
+ select_manual_sort
- drag_to(selector: '.manual-ordering',
- from_index: 0,
- to_index: 2)
+ drag_to(selector: '.manual-ordering', from_index: 0, to_index: 2)
- wait_for_requests
+ expect_issue_order
- check_issue_order
-
- visit issues_group_path(group, sort: 'relative_position')
+ visit issues_group_path(group)
- check_issue_order
+ expect_issue_order
end
it 'issues should not be draggable when user is not logged in' do
sign_out(user_in_group)
-
- visit issues_group_path(group, sort: 'relative_position')
-
wait_for_requests
+ visit issues_group_path(group)
+ select_manual_sort
- drag_to(selector: '.manual-ordering',
- from_index: 0,
- to_index: 2)
+ drag_to(selector: '.manual-ordering', from_index: 0, to_index: 2)
- wait_for_requests
+ expect(page).to have_text 'An error occurred while reordering issues.'
+ end
- # Issue order should remain the same
- page.within('.manual-ordering') do
- expect(find('.issue:nth-child(1) .title')).to have_content('Issue #1')
- expect(find('.issue:nth-child(2) .title')).to have_content('Issue #2')
- expect(find('.issue:nth-child(3) .title')).to have_content('Issue #3')
- end
+ def select_manual_sort
+ click_button 'Created date'
+ click_button 'Manual'
+ wait_for_requests
end
- def check_issue_order
+ def expect_issue_order
expect(page).to have_css('.issue:nth-child(1) .title', text: 'Issue #2')
expect(page).to have_css('.issue:nth-child(2) .title', text: 'Issue #3')
expect(page).to have_css('.issue:nth-child(3) .title', text: 'Issue #1')
diff --git a/spec/features/groups/members/leave_group_spec.rb b/spec/features/groups/members/leave_group_spec.rb
index 50d5db46cee..66f251c859a 100644
--- a/spec/features/groups/members/leave_group_spec.rb
+++ b/spec/features/groups/members/leave_group_spec.rb
@@ -4,13 +4,13 @@ require 'spec_helper'
RSpec.describe 'Groups > Members > Leave group' do
include Spec::Support::Helpers::Features::MembersHelpers
+ include Spec::Support::Helpers::ModalHelpers
let(:user) { create(:user) }
let(:other_user) { create(:user) }
let(:group) { create(:group) }
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
end
@@ -32,7 +32,7 @@ RSpec.describe 'Groups > Members > Leave group' do
visit group_path(group, leave: 1)
- page.accept_confirm
+ accept_gl_confirm(button_text: 'Leave group')
wait_for_all_requests
expect(page).to have_current_path(dashboard_groups_path, ignore_query: true)
diff --git a/spec/features/groups/navbar_spec.rb b/spec/features/groups/navbar_spec.rb
index e4b44d65438..b4faa3ce0dd 100644
--- a/spec/features/groups/navbar_spec.rb
+++ b/spec/features/groups/navbar_spec.rb
@@ -15,7 +15,6 @@ RSpec.describe 'Group navbar' do
before do
insert_package_nav(_('Kubernetes'))
- stub_feature_flags(customer_relations: false)
stub_config(dependency_proxy: { enabled: false })
stub_config(registry: { enabled: false })
stub_feature_flags(harbor_registry_integration: false)
@@ -42,12 +41,10 @@ RSpec.describe 'Group navbar' do
it_behaves_like 'verified navigation bar'
end
- context 'when customer_relations feature and flag is enabled' do
+ context 'when customer_relations feature is enabled' do
let(:group) { create(:group, :crm_enabled) }
before do
- stub_feature_flags(customer_relations: true)
-
if Gitlab.ee?
insert_customer_relations_nav(_('Analytics'))
else
@@ -60,12 +57,10 @@ RSpec.describe 'Group navbar' do
it_behaves_like 'verified navigation bar'
end
- context 'when customer_relations feature and flag is enabled but subgroup' do
+ context 'when customer_relations feature is enabled but subgroup' do
let(:group) { create(:group, :crm_enabled, parent: create(:group)) }
before do
- stub_feature_flags(customer_relations: true)
-
visit group_path(group)
end
diff --git a/spec/features/groups/settings/access_tokens_spec.rb b/spec/features/groups/settings/access_tokens_spec.rb
index 20787c4c2f5..198d3a40df2 100644
--- a/spec/features/groups/settings/access_tokens_spec.rb
+++ b/spec/features/groups/settings/access_tokens_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Group > Settings > Access Tokens', :js do
+ include Spec::Support::Helpers::ModalHelpers
+
let_it_be(:user) { create(:user) }
let_it_be(:bot_user) { create(:user, :project_bot) }
let_it_be(:group) { create(:group) }
@@ -13,7 +15,6 @@ RSpec.describe 'Group > Settings > Access Tokens', :js do
end
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
end
diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb
index eb62b6fa8ee..fa8db1befb5 100644
--- a/spec/features/groups/show_spec.rb
+++ b/spec/features/groups/show_spec.rb
@@ -72,6 +72,58 @@ RSpec.describe 'Group show page' do
end
end
end
+
+ context 'subgroups and projects empty state', :js do
+ context 'when user has permissions to create new subgroups or projects' do
+ before do
+ group.add_owner(user)
+ sign_in(user)
+ visit path
+ end
+
+ it 'shows `Create new subgroup` link' do
+ expect(page).to have_link(
+ s_('GroupsEmptyState|Create new subgroup'),
+ href: new_group_path(parent_id: group.id)
+ )
+ end
+
+ it 'shows `Create new project` link' do
+ expect(page).to have_link(
+ s_('GroupsEmptyState|Create new project'),
+ href: new_project_path(namespace_id: group.id)
+ )
+ end
+ end
+ end
+
+ context 'when user does not have permissions to create new subgroups or projects', :js do
+ before do
+ group.add_reporter(user)
+ sign_in(user)
+ visit path
+ end
+
+ it 'does not show `Create new subgroup` link' do
+ expect(page).not_to have_link(
+ s_('GroupsEmptyState|Create new subgroup'),
+ href: new_group_path(parent_id: group.id)
+ )
+ end
+
+ it 'does not show `Create new project` link' do
+ expect(page).not_to have_link(
+ s_('GroupsEmptyState|Create new project'),
+ href: new_project_path(namespace_id: group.id)
+ )
+ end
+
+ it 'shows empty state' do
+ expect(page).to have_content(s_('GroupsEmptyState|No subgroups or projects.'))
+ expect(page).to have_content(s_('GroupsEmptyState|You do not have necessary permissions to create a subgroup' \
+ ' or project in this group. Please contact an owner of this group to create a new subgroup or project.'))
+ end
+ end
end
context 'when signed out' do
diff --git a/spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb b/spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb
index 9fe11070187..4e4c0e509b0 100644
--- a/spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb
+++ b/spec/features/groups/user_sees_users_dropdowns_in_issuables_list_spec.rb
@@ -2,23 +2,50 @@
require 'spec_helper'
-RSpec.describe 'Groups > User sees users dropdowns in issuables list' do
- let(:entity) { create(:group) }
+RSpec.describe 'Groups > User sees users dropdowns in issuables list', :js do
+ include FilteredSearchHelpers
+
+ let(:group) { create(:group) }
let(:user_in_dropdown) { create(:user) }
let!(:user_not_in_dropdown) { create(:user) }
- let!(:project) { create(:project, group: entity) }
+ let!(:project) { create(:project, group: group) }
before do
- entity.add_developer(user_in_dropdown)
+ group.add_developer(user_in_dropdown)
+ sign_in(user_in_dropdown)
end
- it_behaves_like 'issuable user dropdown behaviors' do
- let(:issuable) { create(:issue, project: project) }
- let(:issuables_path) { issues_group_path(entity) }
+ describe 'issues' do
+ let!(:issuable) { create(:issue, project: project) }
+
+ %w[Author Assignee].each do |dropdown|
+ describe "#{dropdown} dropdown" do
+ it 'only includes members of the project/group' do
+ visit issues_group_path(group)
+
+ select_tokens dropdown, '=', submit: false
+
+ expect_suggestion(user_in_dropdown.name)
+ expect_no_suggestion(user_not_in_dropdown.name)
+ end
+ end
+ end
end
- it_behaves_like 'issuable user dropdown behaviors' do
- let(:issuable) { create(:merge_request, source_project: project) }
- let(:issuables_path) { merge_requests_group_path(entity) }
+ describe 'merge requests' do
+ let!(:issuable) { create(:merge_request, source_project: project) }
+
+ %w[author assignee].each do |dropdown|
+ describe "#{dropdown} dropdown" do
+ it 'only includes members of the project/group' do
+ visit merge_requests_group_path(group)
+
+ filtered_search.set("#{dropdown}:=")
+
+ expect(find("#js-dropdown-#{dropdown} .filter-dropdown")).to have_content(user_in_dropdown.name)
+ expect(find("#js-dropdown-#{dropdown} .filter-dropdown")).not_to have_content(user_not_in_dropdown.name)
+ end
+ end
+ end
end
end
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index ceb4af03f89..31390b110e7 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -22,7 +22,7 @@ RSpec.describe 'Group' do
end
describe 'as a non-admin' do
- it 'creates a group and persists visibility radio selection', :js do
+ it 'creates a group and persists visibility radio selection', :js, :saas do
stub_application_setting(default_group_visibility: :private)
fill_in 'Group name', with: 'test-group'
@@ -127,7 +127,7 @@ RSpec.describe 'Group' do
describe 'Mattermost team creation' do
before do
- stub_mattermost_setting(enabled: mattermost_enabled)
+ stub_mattermost_setting(enabled: mattermost_enabled, host: 'https://mattermost.test')
visit new_group_path
click_link 'Create group'
@@ -145,13 +145,14 @@ RSpec.describe 'Group' do
end
it 'updates the team URL on graph path update', :js do
- out_span = find('span[data-bind-out="create_chat_team"]', visible: false)
+ label = find('#group_create_chat_team ~ label[for=group_create_chat_team]')
+ url = 'https://mattermost.test/test-group'
- expect(out_span.text).to be_empty
+ expect(label.text).not_to match(url)
fill_in('group_path', with: 'test-group')
- expect(out_span.text).to eq('test-group')
+ expect(label.text).to match(url)
end
end
@@ -497,7 +498,9 @@ RSpec.describe 'Group' do
let_it_be(:group) { create(:group) }
let_it_be_with_refind(:user) { create(:user) }
- before_all do
+ before do
+ stub_feature_flags(namespace_storage_limit_bypass_date_check: false)
+
group.add_owner(user)
sign_in(user)
end
diff --git a/spec/features/incidents/incidents_list_spec.rb b/spec/features/incidents/incidents_list_spec.rb
index 789cc89e083..3241e71f537 100644
--- a/spec/features/incidents/incidents_list_spec.rb
+++ b/spec/features/incidents/incidents_list_spec.rb
@@ -44,18 +44,5 @@ RSpec.describe 'Incident Management index', :js do
expect(table).to have_content('Date created')
expect(table).to have_content('Assignees')
end
-
- context 'when :incident_escalations feature is disabled' do
- before do
- stub_feature_flags(incident_escalations: false)
- end
-
- it 'does not include the Status columns' do
- visit project_incidents_path(project)
- wait_for_requests
-
- expect(page.find('.gl-table')).not_to have_content('Status')
- end
- end
end
end
diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb
index 7edf5fdc5ff..0fa2d238b0a 100644
--- a/spec/features/issuables/issuable_list_spec.rb
+++ b/spec/features/issuables/issuable_list_spec.rb
@@ -9,8 +9,6 @@ RSpec.describe 'issuable list', :js do
issuable_types = [:issue, :merge_request]
before do
- stub_feature_flags(vue_issues_list: true)
-
project.add_user(user, :developer)
sign_in(user)
issuable_types.each { |type| create_issuables(type) }
diff --git a/spec/features/issue_rebalancing_spec.rb b/spec/features/issue_rebalancing_spec.rb
index 8a05aeec7ec..686aa5eb1b6 100644
--- a/spec/features/issue_rebalancing_spec.rb
+++ b/spec/features/issue_rebalancing_spec.rb
@@ -15,10 +15,6 @@ RSpec.describe 'Issue rebalancing' do
group.add_developer(user)
end
- before do
- stub_feature_flags(vue_issues_list: true)
- end
-
context 'when issue rebalancing is in progress' do
before do
sign_in(user)
diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
index 18b70c9622a..05eb656461e 100644
--- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
@@ -9,10 +9,6 @@ RSpec.describe 'Dropdown assignee', :js do
let_it_be(:user) { create(:user) }
let_it_be(:issue) { create(:issue, project: project) }
- before do
- stub_feature_flags(vue_issues_list: true)
- end
-
describe 'behavior' do
before do
project.add_maintainer(user)
diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb
index 07e2bd3b7e4..36a8f1f3902 100644
--- a/spec/features/issues/filtered_search/dropdown_author_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb
@@ -10,8 +10,6 @@ RSpec.describe 'Dropdown author', :js do
let_it_be(:issue) { create(:issue, project: project) }
before do
- stub_feature_flags(vue_issues_list: true)
-
project.add_maintainer(user)
sign_in(user)
diff --git a/spec/features/issues/filtered_search/dropdown_base_spec.rb b/spec/features/issues/filtered_search/dropdown_base_spec.rb
index 5fdab288b2d..9e3e3d394cd 100644
--- a/spec/features/issues/filtered_search/dropdown_base_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_base_spec.rb
@@ -10,8 +10,6 @@ RSpec.describe 'Dropdown base', :js do
let_it_be(:issue) { create(:issue, project: project) }
before do
- stub_feature_flags(vue_issues_list: true)
-
project.add_maintainer(user)
sign_in(user)
diff --git a/spec/features/issues/filtered_search/dropdown_emoji_spec.rb b/spec/features/issues/filtered_search/dropdown_emoji_spec.rb
index d6d59b89a8c..78450a9c3f7 100644
--- a/spec/features/issues/filtered_search/dropdown_emoji_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_emoji_spec.rb
@@ -11,8 +11,6 @@ RSpec.describe 'Dropdown emoji', :js do
let_it_be(:award_emoji_star) { create(:award_emoji, name: 'star', user: user, awardable: issue) }
before do
- stub_feature_flags(vue_issues_list: true)
-
project.add_maintainer(user)
create_list(:award_emoji, 2, user: user, name: 'thumbsup')
create_list(:award_emoji, 1, user: user, name: 'thumbsdown')
diff --git a/spec/features/issues/filtered_search/dropdown_hint_spec.rb b/spec/features/issues/filtered_search/dropdown_hint_spec.rb
index c64247b2b15..dcbab308efa 100644
--- a/spec/features/issues/filtered_search/dropdown_hint_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_hint_spec.rb
@@ -10,8 +10,6 @@ RSpec.describe 'Dropdown hint', :js do
let_it_be(:issue) { create(:issue, project: project) }
before do
- stub_feature_flags(vue_issues_list: true)
-
project.add_maintainer(user)
end
diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb
index 67e3792a04c..0ff56909ad1 100644
--- a/spec/features/issues/filtered_search/dropdown_label_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb
@@ -11,8 +11,6 @@ RSpec.describe 'Dropdown label', :js do
let_it_be(:label) { create(:label, project: project, title: 'bug-label') }
before do
- stub_feature_flags(vue_issues_list: true)
-
project.add_maintainer(user)
sign_in(user)
diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
index 19a4c8853f1..37d604106f1 100644
--- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
@@ -12,8 +12,6 @@ RSpec.describe 'Dropdown milestone', :js do
let_it_be(:issue) { create(:issue, project: project) }
before do
- stub_feature_flags(vue_issues_list: true)
-
project.add_maintainer(user)
sign_in(user)
diff --git a/spec/features/issues/filtered_search/dropdown_release_spec.rb b/spec/features/issues/filtered_search/dropdown_release_spec.rb
index 50ac9068b26..08e20563c8e 100644
--- a/spec/features/issues/filtered_search/dropdown_release_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_release_spec.rb
@@ -12,8 +12,6 @@ RSpec.describe 'Dropdown release', :js do
let_it_be(:issue) { create(:issue, project: project) }
before do
- stub_feature_flags(vue_issues_list: true)
-
project.add_maintainer(user)
sign_in(user)
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index 13bce49e6d1..8d96bbc38cb 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -19,7 +19,6 @@ RSpec.describe 'Filter issues', :js do
end
before do
- stub_feature_flags(vue_issues_list: true)
project.add_maintainer(user)
create(:issue, project: project, author: user2, title: "Bug report 1")
diff --git a/spec/features/issues/filtered_search/recent_searches_spec.rb b/spec/features/issues/filtered_search/recent_searches_spec.rb
index bb5964258be..cb17349dd43 100644
--- a/spec/features/issues/filtered_search/recent_searches_spec.rb
+++ b/spec/features/issues/filtered_search/recent_searches_spec.rb
@@ -13,8 +13,6 @@ RSpec.describe 'Recent searches', :js do
let(:project_1_local_storage_key) { "#{project_1.full_path}-issue-recent-searches" }
before do
- stub_feature_flags(vue_issues_list: true)
-
# Visit any fast-loading page so we can clear local storage without a DOM exception
visit '/404'
remove_recent_searches
diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb
index 8639ec2a227..e075547e326 100644
--- a/spec/features/issues/filtered_search/search_bar_spec.rb
+++ b/spec/features/issues/filtered_search/search_bar_spec.rb
@@ -10,7 +10,6 @@ RSpec.describe 'Search bar', :js do
let_it_be(:issue) { create(:issue, project: project) }
before do
- stub_feature_flags(vue_issues_list: true)
project.add_maintainer(user)
sign_in(user)
diff --git a/spec/features/issues/filtered_search/visual_tokens_spec.rb b/spec/features/issues/filtered_search/visual_tokens_spec.rb
index 9fb6a4cc2af..7a367723609 100644
--- a/spec/features/issues/filtered_search/visual_tokens_spec.rb
+++ b/spec/features/issues/filtered_search/visual_tokens_spec.rb
@@ -15,7 +15,6 @@ RSpec.describe 'Visual tokens', :js do
let_it_be(:issue) { create(:issue, project: project) }
before do
- stub_feature_flags(vue_issues_list: true)
project.add_user(user, :maintainer)
project.add_user(user_rock, :maintainer)
sign_in(user)
diff --git a/spec/features/issues/incident_issue_spec.rb b/spec/features/issues/incident_issue_spec.rb
index a2519a44604..d6ec7f1c539 100644
--- a/spec/features/issues/incident_issue_spec.rb
+++ b/spec/features/issues/incident_issue_spec.rb
@@ -26,6 +26,7 @@ RSpec.describe 'Incident Detail', :js do
context 'when user displays the incident' do
before do
+ stub_feature_flags(incident_timeline: project)
project.add_developer(user)
sign_in(user)
@@ -72,6 +73,12 @@ RSpec.describe 'Incident Detail', :js do
expect(hidden_items).to all(be_visible)
end
end
+
+ it 'shows the edit title and description button' do
+ edit_button = find_all('[aria-label="Edit title and description"]')
+
+ expect(edit_button).to all(be_visible)
+ end
end
context 'when on alert details tab' do
@@ -87,6 +94,61 @@ RSpec.describe 'Incident Detail', :js do
expect(hidden_items.count).to eq(0)
end
end
+
+ it 'does not show the edit title and description button' do
+ edit_button = find_all('[aria-label="Edit title and description"]')
+
+ expect(edit_button.count).to eq(0)
+ end
+ end
+
+ context 'when on timeline events tab from incident route' do
+ before do
+ visit project_issues_incident_path(project, incident)
+ wait_for_requests
+ click_link 'Timeline'
+ end
+
+ it 'does not show the linked issues and notes/comment components' do
+ page.within('.issuable-details') do
+ hidden_items = find_all('.js-issue-widgets')
+
+ # Linked Issues/MRs and comment box are hidden on page
+ expect(hidden_items.count).to eq(0)
+ end
+ end
+ end
+
+ context 'when on timeline events tab from issue route' do
+ before do
+ visit project_issue_path(project, incident)
+ wait_for_requests
+ click_link 'Timeline'
+ end
+
+ it 'does not show the linked issues and notes/comment commponents' do
+ page.within('.issuable-details') do
+ hidden_items = find_all('.js-issue-widgets')
+
+ # Linked Issues/MRs and comment box are hidden on page
+ expect(hidden_items.count).to eq(0)
+ end
+ end
+ end
+
+ context 'when incident_timeline feature flag is disabled' do
+ before do
+ stub_feature_flags(incident_timeline: false)
+
+ visit project_issue_path(project, incident)
+ wait_for_requests
+ end
+
+ it 'does not show Timeline tab' do
+ tabs = find('[data-testid="incident-tabs"]')
+
+ expect(tabs).not_to have_content('Timeline')
+ end
end
end
end
diff --git a/spec/features/issues/issue_detail_spec.rb b/spec/features/issues/issue_detail_spec.rb
index 88709d66887..2af54e51bb7 100644
--- a/spec/features/issues/issue_detail_spec.rb
+++ b/spec/features/issues/issue_detail_spec.rb
@@ -140,13 +140,9 @@ RSpec.describe 'Issue Detail', :js do
end
context 'by non-member author' do
- it 'routes the user to the issue details page when the `issue_type` is set to issue' do
- open_issue_edit_form
-
- page.within('[data-testid="issuable-form"]') do
- update_type_select('Incident', 'Issue')
-
- expect(page).to have_current_path(project_issue_path(project, incident))
+ it 'cannot edit issuable' do
+ page.within('.content') do
+ expect(page).to have_no_button('Edit title and description')
end
end
end
diff --git a/spec/features/issues/rss_spec.rb b/spec/features/issues/rss_spec.rb
index bdc5f282875..e3faed81c73 100644
--- a/spec/features/issues/rss_spec.rb
+++ b/spec/features/issues/rss_spec.rb
@@ -13,10 +13,6 @@ RSpec.describe 'Project Issues RSS', :js do
group.add_developer(user)
end
- before do
- stub_feature_flags(vue_issues_list: true)
- end
-
context 'when signed in' do
let_it_be(:user) { create(:user) }
diff --git a/spec/features/issues/user_bulk_edits_issues_labels_spec.rb b/spec/features/issues/user_bulk_edits_issues_labels_spec.rb
index 27377f6e1fd..4837d13574c 100644
--- a/spec/features/issues/user_bulk_edits_issues_labels_spec.rb
+++ b/spec/features/issues/user_bulk_edits_issues_labels_spec.rb
@@ -15,10 +15,6 @@ RSpec.describe 'Issues > Labels bulk assignment' do
let(:issue_1_selector) { "#issuable_#{issue1.id}" }
let(:issue_2_selector) { "#issuable_#{issue2.id}" }
- before do
- stub_feature_flags(vue_issues_list: true)
- end
-
context 'as an allowed user', :js do
before do
project.add_maintainer(user)
diff --git a/spec/features/issues/user_bulk_edits_issues_spec.rb b/spec/features/issues/user_bulk_edits_issues_spec.rb
index 625303f89e4..0533f1688e2 100644
--- a/spec/features/issues/user_bulk_edits_issues_spec.rb
+++ b/spec/features/issues/user_bulk_edits_issues_spec.rb
@@ -107,10 +107,6 @@ RSpec.describe 'Multiple issue updating from issues#index', :js do
describe 'select all issues' do
let!(:issue_2) { create(:issue, project: project) }
- before do
- stub_feature_flags(vue_issues_list: true)
- end
-
it 'after selecting all issues, unchecking one issue only unselects that one issue' do
visit project_issues_path(project)
diff --git a/spec/features/issues/user_comments_on_issue_spec.rb b/spec/features/issues/user_comments_on_issue_spec.rb
index a719263f092..a1e7c007b90 100644
--- a/spec/features/issues/user_comments_on_issue_spec.rb
+++ b/spec/features/issues/user_comments_on_issue_spec.rb
@@ -10,7 +10,6 @@ RSpec.describe "User comments on issue", :js do
let(:user) { create(:user) }
before do
- stub_feature_flags(sandboxed_mermaid: false)
project.add_guest(user)
sign_in(user)
@@ -42,17 +41,6 @@ RSpec.describe "User comments on issue", :js do
expect(page.find('pre code').text).to eq code_block_content
end
- it "renders HTML content as text in Mermaid" do
- html_content = "<img onerror=location=`javascript\\u003aalert\\u0028document.domain\\u0029` src=x>"
- mermaid_content = "graph LR\n B-->D(#{html_content});"
- comment = "```mermaid\n#{mermaid_content}\n```"
-
- add_note(comment)
-
- expect(page.find('svg.mermaid')).not_to have_content 'javascript'
- within('svg.mermaid') { expect(page).not_to have_selector('img') }
- end
-
it 'opens autocomplete menu for quick actions and have `/label` first choice' do
project.add_maintainer(user)
create(:label, project: project, title: 'label')
@@ -67,7 +55,7 @@ RSpec.describe "User comments on issue", :js do
it "edits comment" do
add_note("# Comment with a header")
- page.within(".note-body > .note-text") do
+ page.within(".note-body .note-text") do
expect(page).to have_content("Comment with a header").and have_no_css("#comment-with-a-header")
end
diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb
index 3bba041dab7..151d3c60fa2 100644
--- a/spec/features/issues/user_creates_issue_spec.rb
+++ b/spec/features/issues/user_creates_issue_spec.rb
@@ -8,10 +8,6 @@ RSpec.describe "User creates issue" do
let_it_be(:project) { create(:project_empty_repo, :public) }
let_it_be(:user) { create(:user) }
- before do
- stub_feature_flags(vue_issues_list: true)
- end
-
context "when unauthenticated" do
before do
sign_out(:user)
diff --git a/spec/features/issues/user_filters_issues_spec.rb b/spec/features/issues/user_filters_issues_spec.rb
index 42c2b5d32c1..2941ea6ec36 100644
--- a/spec/features/issues/user_filters_issues_spec.rb
+++ b/spec/features/issues/user_filters_issues_spec.rb
@@ -7,8 +7,6 @@ RSpec.describe 'User filters issues', :js do
let_it_be(:project) { create(:project_empty_repo, :public) }
before do
- stub_feature_flags(vue_issues_list: true)
-
%w[foobar barbaz].each do |title|
create(:issue,
author: user,
diff --git a/spec/features/issues/user_sees_breadcrumb_links_spec.rb b/spec/features/issues/user_sees_breadcrumb_links_spec.rb
index 1577d7d5ce8..4ec13533a8d 100644
--- a/spec/features/issues/user_sees_breadcrumb_links_spec.rb
+++ b/spec/features/issues/user_sees_breadcrumb_links_spec.rb
@@ -8,8 +8,6 @@ RSpec.describe 'New issue breadcrumb' do
let(:user) { project.creator }
before do
- stub_feature_flags(vue_issues_list: true)
-
sign_in(user)
visit(new_project_issue_path(project))
end
diff --git a/spec/features/issues/user_sorts_issues_spec.rb b/spec/features/issues/user_sorts_issues_spec.rb
index 4af313576ed..7add6c782f7 100644
--- a/spec/features/issues/user_sorts_issues_spec.rb
+++ b/spec/features/issues/user_sorts_issues_spec.rb
@@ -16,8 +16,6 @@ RSpec.describe "User sorts issues" do
let_it_be(:later_due_milestone) { create(:milestone, project: project, due_date: '2013-12-12') }
before do
- stub_feature_flags(vue_issues_list: true)
-
create_list(:award_emoji, 2, :upvote, awardable: issue1)
create_list(:award_emoji, 2, :downvote, awardable: issue2)
create(:award_emoji, :downvote, awardable: issue1)
diff --git a/spec/features/labels_hierarchy_spec.rb b/spec/features/labels_hierarchy_spec.rb
index ea888d4b254..2f22ac8b395 100644
--- a/spec/features/labels_hierarchy_spec.rb
+++ b/spec/features/labels_hierarchy_spec.rb
@@ -17,8 +17,6 @@ RSpec.describe 'Labels Hierarchy', :js do
let!(:project_label_1) { create(:label, project: project_1, title: 'Label_4') }
before do
- stub_feature_flags(vue_issues_list: true)
-
grandparent.add_owner(user)
sign_in(user)
diff --git a/spec/features/markdown/math_spec.rb b/spec/features/markdown/math_spec.rb
index fa23fac2f96..1f219886818 100644
--- a/spec/features/markdown/math_spec.rb
+++ b/spec/features/markdown/math_spec.rb
@@ -67,4 +67,24 @@ RSpec.describe 'Math rendering', :js do
expect(page).to have_selector('.js-lazy-render-math')
end
end
+
+ it 'renders without any limits on wiki page', :js do
+ description = <<~MATH
+ ```math
+ \Huge \sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{\sqrt{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
+ ```
+ MATH
+
+ wiki_page = build(:wiki_page, { container: project, content: description })
+ wiki_page.create message: 'math test commit' # rubocop:disable Rails/SaveBang
+ wiki_page = project.wiki.find_page(wiki_page.slug)
+
+ visit project_wiki_path(project, wiki_page)
+
+ wait_for_requests
+
+ page.within '.js-wiki-page-content' do
+ expect(page).not_to have_selector('.js-lazy-render-math')
+ end
+ end
end
diff --git a/spec/features/markdown/mermaid_spec.rb b/spec/features/markdown/mermaid_spec.rb
deleted file mode 100644
index 322b5306a00..00000000000
--- a/spec/features/markdown/mermaid_spec.rb
+++ /dev/null
@@ -1,361 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'Mermaid rendering', :js do
- let_it_be(:project) { create(:project, :public) }
-
- let(:is_mac) { page.evaluate_script('navigator.platform').include?('Mac') }
- let(:modifier_key) { is_mac ? :command : :control }
-
- before do
- stub_feature_flags(sandboxed_mermaid: false)
- end
-
- it 'renders Mermaid diagrams correctly' do
- description = <<~MERMAID
- ```mermaid
- graph TD;
- A-->B;
- A-->C;
- B-->D;
- C-->D;
- ```
- MERMAID
-
- issue = create(:issue, project: project, description: description)
-
- visit project_issue_path(project, issue)
-
- wait_for_requests
- wait_for_mermaid
-
- %w[A B C D].each do |label|
- expect(page).to have_selector('svg text', text: label)
- end
- end
-
- it 'renders linebreaks in Mermaid diagrams' do
- description = <<~MERMAID
- ```mermaid
- graph TD;
- A(Line 1<br>Line 2)-->B(Line 1<br/>Line 2);
- C(Line 1<br />Line 2)-->D(Line 1<br />Line 2);
- ```
- MERMAID
-
- issue = create(:issue, project: project, description: description)
-
- visit project_issue_path(project, issue)
-
- wait_for_requests
- wait_for_mermaid
-
- # From # From https://github.com/mermaid-js/mermaid/blob/170ed89e9ef3e33dc84f8656eed1725379d505df/src/dagre-wrapper/createLabel.js#L39-L42
- expected = %(<div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">Line 1<br>Line 2</div>)
- expect(page.html.scan(expected).count).to be(4)
- end
-
- it 'does not allow XSS in HTML labels' do
- description = <<~MERMAID
- ```mermaid
- graph LR;
- A-->CLICK_HERE_AND_GET_BONUS;
- click A alert "aaa"
- click CLICK_HERE_AND_GET_BONUS "javascript:alert%28%64%6f%63%75%6d%65%6e%74%2e%64%6f%6d%61%69%6e%29" "Here is the XSS"
- ```
- MERMAID
-
- issue = create(:issue, project: project, description: description)
-
- visit project_issue_path(project, issue)
-
- wait_for_requests
- wait_for_mermaid
-
- # From https://github.com/mermaid-js/mermaid/blob/170ed89e9ef3e33dc84f8656eed1725379d505df/src/dagre-wrapper/createLabel.js#L39-L42
- expected = %(<div style="display: inline-block; white-space: nowrap;" xmlns="http://www.w3.org/1999/xhtml">CLICK_HERE_AND_GET_BONUS</div>)
- expect(page.html).to include(expected)
- end
-
- it 'renders only 2 Mermaid blocks and', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/234081' do
- description = <<~MERMAID
- ```mermaid
- graph LR
- A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;
- ```
- ```mermaid
- graph LR
- A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;
- ```
- ```mermaid
- graph LR
- A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;B-->A;A-->B;
- ```
- MERMAID
-
- issue = create(:issue, project: project, description: description)
-
- visit project_issue_path(project, issue)
-
- wait_for_requests
- wait_for_mermaid
-
- page.within('.description') do
- expect(page).to have_selector('svg')
- expect(page).to have_selector('pre.mermaid')
- end
- end
-
- it 'correctly sizes mermaid diagram inside <details> block' do
- description = <<~MERMAID
- <details>
- <summary>Click to show diagram</summary>
-
- ```mermaid
- graph TD;
- A-->B;
- A-->C;
- B-->D;
- C-->D;
- ```
-
- </details>
- MERMAID
-
- issue = create(:issue, project: project, description: description)
-
- visit project_issue_path(project, issue)
-
- wait_for_requests
- wait_for_mermaid
-
- page.within('.description') do
- page.find('summary').click
- svg = page.find('svg.mermaid')
-
- expect(svg[:style]).to match(/max-width/)
- expect(svg[:width].to_i).to eq(100)
- expect(svg[:height].to_i).to be_within(5).of(236)
- end
- end
-
- it 'renders V2 state diagrams' do
- description = <<~MERMAID
- ```mermaid
- stateDiagram-v2
- [*] --> Idle
- Idle --> Active : CONTINUE
- state Active {
- [*] --> Run
- Run--> Stop: CONTINUE
- Stop--> Run: CONTINUE
-
- Run: Run
- Run: entry/start
- Run: check
- }
- ```
- MERMAID
-
- issue = create(:issue, project: project, description: description)
-
- visit project_issue_path(project, issue)
-
- wait_for_requests
- wait_for_mermaid
-
- page.within('.description') do
- expect(page).to have_selector('svg')
- end
- end
-
- it 'correctly sizes mermaid diagram block' do
- description = <<~MERMAID
- ```mermaid
- graph TD;
- A-->B;
- A-->C;
- B-->D;
- C-->D;
- ```
- MERMAID
-
- issue = create(:issue, project: project, description: description)
-
- visit project_issue_path(project, issue)
-
- wait_for_requests
- wait_for_mermaid
-
- expect(page).to have_css('svg.mermaid[style*="max-width"][width="100%"]')
- end
-
- it 'display button when diagram exceeds length', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/287806' do
- graph_edges = "A-->B;B-->A;" * 420
-
- description = <<~MERMAID
- ```mermaid
- graph LR
- #{graph_edges}
- ```
- MERMAID
-
- issue = create(:issue, project: project, description: description)
-
- visit project_issue_path(project, issue)
-
- page.within('.description') do
- expect(page).not_to have_selector('svg')
-
- expect(page).to have_selector('pre.mermaid')
-
- expect(page).to have_selector('.lazy-alert-shown')
-
- expect(page).to have_selector('.js-lazy-render-mermaid-container')
- end
-
- wait_for_requests
- wait_for_mermaid
-
- find('.js-lazy-render-mermaid').click
-
- page.within('.description') do
- expect(page).to have_selector('svg')
-
- expect(page).not_to have_selector('.js-lazy-render-mermaid-container')
- end
- end
-
- it 'does not render more than 50 mermaid blocks', :js, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/234081' } do
- graph_edges = "A-->B;B-->A;"
-
- description = <<~MERMAID
- ```mermaid
- graph LR
- #{graph_edges}
- ```
- MERMAID
-
- description *= 51
-
- issue = create(:issue, project: project, description: description)
-
- visit project_issue_path(project, issue)
-
- wait_for_requests
- wait_for_mermaid
-
- page.within('.description') do
- expect(page).to have_selector('svg')
-
- expect(page).to have_selector('.lazy-alert-shown')
-
- expect(page).to have_selector('.js-lazy-render-mermaid-container')
- end
- end
-
- it 'renders without any limits on wiki page', :js do
- graph_edges = "A-->B;B-->A;"
-
- description = <<~MERMAID
- ```mermaid
- graph LR
- #{graph_edges}
- ```
- MERMAID
-
- description *= 51
-
- wiki_page = build(:wiki_page, { container: project, content: description })
- wiki_page.create message: 'mermaid test commit' # rubocop:disable Rails/SaveBang
- wiki_page = project.wiki.find_page(wiki_page.slug)
-
- visit project_wiki_path(project, wiki_page)
-
- wait_for_requests
- wait_for_mermaid
-
- page.within('.js-wiki-page-content') do
- expect(page).not_to have_selector('.lazy-alert-shown')
-
- expect(page).not_to have_selector('.js-lazy-render-mermaid-container')
- end
- end
-
- it 'does not allow HTML injection' do
- description = <<~MERMAID
- ```mermaid
- %%{init: {"flowchart": {"htmlLabels": "false"}} }%%
- flowchart
- A["<iframe></iframe>"]
- ```
- MERMAID
-
- issue = create(:issue, project: project, description: description)
-
- visit project_issue_path(project, issue)
-
- wait_for_requests
- wait_for_mermaid
-
- page.within('.description') do
- expect(page).not_to have_xpath("//iframe")
- end
- end
-
- it 'correctly copies and pastes to/from the clipboard' do
- stub_feature_flags(sandboxed_mermaid: true)
-
- description = <<~MERMAID
- ```mermaid
- graph TD;
- A-->B;
- A-->C;
- ```
- MERMAID
-
- issue = create(:issue, project: project, description: description)
-
- user = create(:user)
- sign_in(user)
- visit project_issue_path(project, issue)
-
- wait_for_requests
- wait_for_mermaid
-
- find('pre.language-mermaid').hover
- find('copy-code button').click
-
- sleep 2
-
- find('#note-body').send_keys [modifier_key, 'v']
-
- wait_for_requests
-
- # The codefences do actually get included, but we can't get spec to pass
- # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83202#note_880621264
- expect(find('#note-body').value.strip).to eq("graph TD;\n A-->B;\n A-->C;")
- end
-end
-
-def wait_for_mermaid
- run_idle_callback = <<~RUN_IDLE_CALLBACK
- window.requestIdleCallback(() => {
- window.__CAPYBARA_IDLE_CALLBACK_EXEC__ = 1;
- })
- RUN_IDLE_CALLBACK
-
- page.evaluate_script(run_idle_callback)
-
- Timeout.timeout(Capybara.default_max_wait_time) do
- loop until finished_rendering?
- end
-end
-
-def finished_rendering?
- check_idle_callback = <<~CHECK_IDLE_CALLBACK
- window.__CAPYBARA_IDLE_CALLBACK_EXEC__
- CHECK_IDLE_CALLBACK
- page.evaluate_script(check_idle_callback) == 1
-end
diff --git a/spec/features/merge_request/batch_comments_spec.rb b/spec/features/merge_request/batch_comments_spec.rb
index 9b54d95be6b..f03c812ebb5 100644
--- a/spec/features/merge_request/batch_comments_spec.rb
+++ b/spec/features/merge_request/batch_comments_spec.rb
@@ -13,224 +13,221 @@ RSpec.describe 'Merge request > Batch comments', :js do
end
before do
- stub_feature_flags(paginated_notes: false)
-
project.add_maintainer(user)
sign_in(user)
+
+ visit_diffs
end
- context 'Feature is enabled' do
- before do
- visit_diffs
- end
+ it 'adds draft note' do
+ write_diff_comment
- it 'adds draft note' do
- write_diff_comment
+ expect(find('.draft-note-component')).to have_content('Line is wrong')
- expect(find('.draft-note-component')).to have_content('Line is wrong')
+ expect(page).to have_selector('[data-testid="review_bar_component"]')
- expect(page).to have_selector('[data-testid="review_bar_component"]')
+ expect(find('[data-testid="review_bar_component"] .gl-badge')).to have_content('1')
+ end
+
+ it 'publishes review' do
+ write_diff_comment
- expect(find('[data-testid="review_bar_component"] .btn-confirm')).to have_content('1')
+ page.within('.review-bar-content') do
+ click_button 'Finish review'
+ click_button 'Submit review'
end
- it 'publishes review' do
- write_diff_comment
+ wait_for_requests
- page.within('.review-bar-content') do
- click_button 'Submit review'
- end
+ expect(page).not_to have_selector('.draft-note-component', text: 'Line is wrong')
- wait_for_requests
+ expect(page).to have_selector('.note:not(.draft-note)', text: 'Line is wrong')
+ end
- expect(page).not_to have_selector('.draft-note-component', text: 'Line is wrong')
+ it 'publishes single comment' do
+ write_diff_comment
- expect(page).to have_selector('.note:not(.draft-note)', text: 'Line is wrong')
- end
+ click_button 'Add comment now'
- it 'publishes single comment' do
- write_diff_comment
+ wait_for_requests
- click_button 'Add comment now'
+ expect(page).not_to have_selector('.draft-note-component', text: 'Line is wrong')
- wait_for_requests
+ expect(page).to have_selector('.note:not(.draft-note)', text: 'Line is wrong')
+ end
+
+ it 'deletes draft note' do
+ write_diff_comment
- expect(page).not_to have_selector('.draft-note-component', text: 'Line is wrong')
+ find('.js-note-delete').click
- expect(page).to have_selector('.note:not(.draft-note)', text: 'Line is wrong')
+ page.within('.modal') do
+ click_button('Delete Comment', match: :first)
end
- it 'deletes draft note' do
- write_diff_comment
+ wait_for_requests
- find('.js-note-delete').click
+ expect(page).not_to have_selector('.draft-note-component', text: 'Line is wrong')
+ end
- page.within('.modal') do
- click_button('Delete Comment', match: :first)
- end
+ it 'edits draft note' do
+ write_diff_comment
- wait_for_requests
+ find('.js-note-edit').click
- expect(page).not_to have_selector('.draft-note-component', text: 'Line is wrong')
- end
+ # make sure comment form is in view
+ execute_script("window.scrollBy(0, 200)")
- it 'edits draft note' do
- write_diff_comment
+ write_comment(text: 'Testing update', button_text: 'Save comment')
- find('.js-note-edit').click
+ expect(page).to have_selector('.draft-note-component', text: 'Testing update')
+ end
- # make sure comment form is in view
- execute_script("window.scrollBy(0, 200)")
+ context 'with image and file draft note' do
+ let(:merge_request) { create(:merge_request_with_diffs, :with_image_diffs, source_project: project) }
+ let!(:draft_on_text) { create(:draft_note_on_text_diff, merge_request: merge_request, author: user, path: 'README.md', note: 'Lorem ipsum on text...') }
+ let!(:draft_on_image) { create(:draft_note_on_image_diff, merge_request: merge_request, author: user, path: 'files/images/ee_repo_logo.png', note: 'Lorem ipsum on an image...') }
- write_comment(text: 'Testing update', button_text: 'Save comment')
+ it 'does not show in overview' do
+ visit_overview
- expect(page).to have_selector('.draft-note-component', text: 'Testing update')
+ expect(page).to have_no_text(draft_on_text.note)
+ expect(page).to have_no_text(draft_on_image.note)
end
+ end
- context 'with image and file draft note' do
- let(:merge_request) { create(:merge_request_with_diffs, :with_image_diffs, source_project: project) }
- let!(:draft_on_text) { create(:draft_note_on_text_diff, merge_request: merge_request, author: user, path: 'README.md', note: 'Lorem ipsum on text...') }
- let!(:draft_on_image) { create(:draft_note_on_image_diff, merge_request: merge_request, author: user, path: 'files/images/ee_repo_logo.png', note: 'Lorem ipsum on an image...') }
-
- it 'does not show in overview' do
- visit_overview
+ context 'adding single comment to review' do
+ before do
+ visit_overview
+ end
- expect(page).to have_no_text(draft_on_text.note)
- expect(page).to have_no_text(draft_on_image.note)
- end
+ it 'at first does not show `Add to review` and `Add comment now` buttons' do
+ expect(page).to have_no_button('Add to review')
+ expect(page).to have_no_button('Add comment now')
end
- context 'adding single comment to review' do
+ context 'when review has started' do
before do
- visit_overview
- end
-
- it 'at first does not show `Add to review` and `Add comment now` buttons' do
- expect(page).to have_no_button('Add to review')
- expect(page).to have_no_button('Add comment now')
- end
-
- context 'when review has started' do
- before do
- visit_diffs
+ visit_diffs
- write_diff_comment
+ write_diff_comment
- visit_overview
- end
+ visit_overview
+ end
- it 'can add comment to review' do
- write_comment(selector: '.js-main-target-form', field: 'note-body', text: 'Its a draft comment', button_text: 'Add to review')
+ it 'can add comment to review' do
+ write_comment(selector: '.js-main-target-form', field: 'note-body', text: 'Its a draft comment', button_text: 'Add to review')
- expect(page).to have_selector('.draft-note-component', text: 'Its a draft comment')
+ expect(page).to have_selector('.draft-note-component', text: 'Its a draft comment')
- click_button('Pending comments')
+ click_button('Pending comments')
- expect(page).to have_text('2 pending comments')
- end
+ expect(page).to have_text('2 pending comments')
+ end
- it 'can add comment right away' do
- write_comment(selector: '.js-main-target-form', field: 'note-body', text: 'Its a regular comment', button_text: 'Add comment now')
+ it 'can add comment right away' do
+ write_comment(selector: '.js-main-target-form', field: 'note-body', text: 'Its a regular comment', button_text: 'Add comment now')
- expect(page).to have_selector('.note:not(.draft-note)', text: 'Its a regular comment')
+ expect(page).to have_selector('.note:not(.draft-note)', text: 'Its a regular comment')
- click_button('Pending comments')
+ click_button('Pending comments')
- expect(page).to have_text('1 pending comment')
- end
+ expect(page).to have_text('1 pending comment')
end
end
+ end
- context 'in parallel diff' do
- before do
- find('.js-show-diff-settings').click
- click_button 'Side-by-side'
- find('.js-show-diff-settings').click
- end
+ context 'in parallel diff' do
+ before do
+ find('.js-show-diff-settings').click
+ click_button 'Side-by-side'
+ find('.js-show-diff-settings').click
+ end
- it 'adds draft comments to both sides' do
- write_parallel_comment('2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9')
- write_parallel_comment('2f6fcd96b88b36ce98c38da085c795a27d92a3dd_9_9', button_text: 'Add to review', text: 'Another wrong line')
+ it 'adds draft comments to both sides' do
+ write_parallel_comment('2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9')
+ write_parallel_comment('2f6fcd96b88b36ce98c38da085c795a27d92a3dd_9_9', button_text: 'Add to review', text: 'Another wrong line')
- expect(find('.new .draft-note-component')).to have_content('Line is wrong')
- expect(find('.old .draft-note-component')).to have_content('Another wrong line')
+ expect(find('.new .draft-note-component')).to have_content('Line is wrong')
+ expect(find('.old .draft-note-component')).to have_content('Another wrong line')
- expect(find('.review-bar-content .btn-confirm')).to have_content('2')
- end
+ expect(find('.review-bar-content .gl-badge')).to have_content('2')
end
+ end
- context 'thread is unresolved' do
- let!(:active_discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion }
+ context 'thread is unresolved' do
+ let!(:active_discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion }
- before do
- visit_diffs
- end
+ before do
+ visit_diffs
+ end
- it 'publishes comment right away and resolves the thread' do
- expect(active_discussion.resolved?).to eq(false)
+ it 'publishes comment right away and resolves the thread' do
+ expect(active_discussion.resolved?).to eq(false)
- write_reply_to_discussion(button_text: 'Add comment now', resolve: true)
+ write_reply_to_discussion(button_text: 'Add comment now', resolve: true)
- page.within '.discussions-counter' do
- expect(page).to have_content('All threads resolved')
- end
+ page.within '.discussions-counter' do
+ expect(page).to have_content('All threads resolved')
end
+ end
- it 'publishes review and resolves the thread' do
- expect(active_discussion.resolved?).to eq(false)
+ it 'publishes review and resolves the thread' do
+ expect(active_discussion.resolved?).to eq(false)
- write_reply_to_discussion(resolve: true)
+ write_reply_to_discussion(resolve: true)
- page.within('.review-bar-content') do
- click_button 'Submit review'
- end
+ page.within('.review-bar-content') do
+ click_button 'Finish review'
+ click_button 'Submit review'
+ end
- wait_for_requests
+ wait_for_requests
- page.within '.discussions-counter' do
- expect(page).to have_content('All threads resolved')
- end
+ page.within '.discussions-counter' do
+ expect(page).to have_content('All threads resolved')
end
end
+ end
- context 'thread is resolved' do
- let!(:active_discussion) { create(:diff_note_on_merge_request, :resolved, noteable: merge_request, project: project).to_discussion }
+ context 'thread is resolved' do
+ let!(:active_discussion) { create(:diff_note_on_merge_request, :resolved, noteable: merge_request, project: project).to_discussion }
- before do
- active_discussion.resolve!(@current_user)
+ before do
+ active_discussion.resolve!(@current_user)
- visit_diffs
+ visit_diffs
- page.find('.js-diff-comment-avatar').click
- end
+ page.find('.js-diff-comment-avatar').click
+ end
- it 'publishes comment right away and unresolves the thread' do
- expect(active_discussion.resolved?).to eq(true)
+ it 'publishes comment right away and unresolves the thread' do
+ expect(active_discussion.resolved?).to eq(true)
- write_reply_to_discussion(button_text: 'Add comment now', unresolve: true)
+ write_reply_to_discussion(button_text: 'Add comment now', unresolve: true)
- page.within '.discussions-counter' do
- expect(page).to have_content('1 unresolved thread')
- end
+ page.within '.discussions-counter' do
+ expect(page).to have_content('1 unresolved thread')
end
+ end
- it 'publishes review and unresolves the thread' do
- expect(active_discussion.resolved?).to eq(true)
+ it 'publishes review and unresolves the thread' do
+ expect(active_discussion.resolved?).to eq(true)
- wait_for_requests
+ wait_for_requests
- write_reply_to_discussion(button_text: 'Start a review', unresolve: true)
+ write_reply_to_discussion(button_text: 'Start a review', unresolve: true)
- page.within('.review-bar-content') do
- click_button 'Submit review'
- end
+ page.within('.review-bar-content') do
+ click_button 'Finish review'
+ click_button 'Submit review'
+ end
- wait_for_requests
+ wait_for_requests
- page.within '.discussions-counter' do
- expect(page).to have_content('1 unresolved thread')
- end
+ page.within '.discussions-counter' do
+ expect(page).to have_content('1 unresolved thread')
end
end
end
diff --git a/spec/features/merge_request/user_comments_on_diff_spec.rb b/spec/features/merge_request/user_comments_on_diff_spec.rb
index 99756da51e4..06b29969775 100644
--- a/spec/features/merge_request/user_comments_on_diff_spec.rb
+++ b/spec/features/merge_request/user_comments_on_diff_spec.rb
@@ -14,7 +14,6 @@ RSpec.describe 'User comments on a diff', :js do
let(:user) { create(:user) }
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
project.add_maintainer(user)
sign_in(user)
diff --git a/spec/features/merge_request/user_creates_merge_request_spec.rb b/spec/features/merge_request/user_creates_merge_request_spec.rb
index a3dc3079374..2bf8e9ba6a4 100644
--- a/spec/features/merge_request/user_creates_merge_request_spec.rb
+++ b/spec/features/merge_request/user_creates_merge_request_spec.rb
@@ -30,7 +30,6 @@ RSpec.describe "User creates a merge request", :js do
it "shows merge request form" do
page.within('.merge-request-form') do
- expect(page.find('#merge_request_title')['placeholder']).to eq 'Title'
expect(page.find('#merge_request_description')['placeholder']).to eq 'Describe the goal of the changes and what reviewers should be aware of.'
end
end
@@ -100,7 +99,7 @@ RSpec.describe "User creates a merge request", :js do
click_button("Compare branches and continue")
- expect(page).to have_css("h3.page-title", text: "New merge request")
+ expect(page).to have_text _('New merge request')
page.within("form#new_merge_request") do
fill_in("Title", with: title)
diff --git a/spec/features/merge_request/user_posts_diff_notes_spec.rb b/spec/features/merge_request/user_posts_diff_notes_spec.rb
index 64715f9234a..8a310aba77b 100644
--- a/spec/features/merge_request/user_posts_diff_notes_spec.rb
+++ b/spec/features/merge_request/user_posts_diff_notes_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe 'Merge request > User posts diff notes', :js do
project.add_developer(user)
sign_in(user)
- stub_feature_flags(bootstrap_confirmation_modals: false)
+ stub_const('Gitlab::QueryLimiting::Transaction::THRESHOLD', 104)
end
context 'when hovering over a parallel view diff file' do
diff --git a/spec/features/merge_request/user_posts_notes_spec.rb b/spec/features/merge_request/user_posts_notes_spec.rb
index ad602afe68a..844ef6133c8 100644
--- a/spec/features/merge_request/user_posts_notes_spec.rb
+++ b/spec/features/merge_request/user_posts_notes_spec.rb
@@ -18,7 +18,6 @@ RSpec.describe 'Merge request > User posts notes', :js do
end
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
project.add_maintainer(user)
sign_in(user)
@@ -158,7 +157,7 @@ RSpec.describe 'Merge request > User posts notes', :js do
page.within("#note_#{note.id}") do
expect(find('.current-note-edit-form', visible: true)).to be_visible
expect(find('.note-edit-form', visible: true)).to be_visible
- expect(find(:css, '.note-body > .note-text', visible: false)).not_to be_visible
+ expect(find(:css, '.note-body .note-text', visible: false)).not_to be_visible
end
end
diff --git a/spec/features/merge_request/user_resolves_conflicts_spec.rb b/spec/features/merge_request/user_resolves_conflicts_spec.rb
index 982e75760d7..a04ca4e789c 100644
--- a/spec/features/merge_request/user_resolves_conflicts_spec.rb
+++ b/spec/features/merge_request/user_resolves_conflicts_spec.rb
@@ -178,23 +178,6 @@ RSpec.describe 'Merge request > User resolves conflicts', :js do
end
end
- context 'sidebar' do
- let(:merge_request) { create_merge_request('conflict-resolvable') }
-
- before do
- project.add_developer(user)
- sign_in(user)
-
- visit conflicts_project_merge_request_path(project, merge_request)
- end
-
- it 'displays reviewers' do
- page.within '.issuable-sidebar' do
- expect(page).to have_selector('[data-testid="reviewer"]', count: 1)
- end
- end
- end
-
unresolvable_conflicts = {
'conflict-too-large' => 'when the conflicts contain a large file',
'conflict-binary-file' => 'when the conflicts contain a binary file',
diff --git a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb
index fca40dc7edc..0e9ff98c3e1 100644
--- a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb
+++ b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb
@@ -83,7 +83,6 @@ RSpec.describe 'Merge request > User sees avatars on diff notes', :js do
%w(parallel).each do |view|
context "#{view} view" do
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
visit diffs_project_merge_request_path(project, merge_request, view: view)
wait_for_requests
diff --git a/spec/features/merge_request/user_sees_deployment_widget_spec.rb b/spec/features/merge_request/user_sees_deployment_widget_spec.rb
index 01cc58777ba..81034caaee2 100644
--- a/spec/features/merge_request/user_sees_deployment_widget_spec.rb
+++ b/spec/features/merge_request/user_sees_deployment_widget_spec.rb
@@ -109,10 +109,12 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
end
context 'with stop action' do
- let(:manual) { create(:ci_build, :manual, pipeline: pipeline, name: 'close_app') }
+ let(:manual) do
+ create(:ci_build, :manual, pipeline: pipeline,
+ name: 'close_app', environment: environment.name)
+ end
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
build.success!
deployment.update!(on_stop: manual.name)
visit project_merge_request_path(project, merge_request)
diff --git a/spec/features/merge_request/user_sees_discussions_spec.rb b/spec/features/merge_request/user_sees_discussions_spec.rb
index d79763ba5e0..cc477e363a4 100644
--- a/spec/features/merge_request/user_sees_discussions_spec.rb
+++ b/spec/features/merge_request/user_sees_discussions_spec.rb
@@ -62,7 +62,7 @@ RSpec.describe 'Merge request > User sees threads', :js do
within(".discussion[data-discussion-id='#{discussion_id}']") do
find_field('Reply…').click
fill_in 'note[note]', with: 'Test!'
- click_button 'Comment'
+ click_button 'Reply'
expect(page).to have_css('.note', count: 2)
end
diff --git a/spec/features/merge_request/user_sees_versions_spec.rb b/spec/features/merge_request/user_sees_versions_spec.rb
index 2b856811e02..4465d7e29be 100644
--- a/spec/features/merge_request/user_sees_versions_spec.rb
+++ b/spec/features/merge_request/user_sees_versions_spec.rb
@@ -101,6 +101,7 @@ RSpec.describe 'Merge request > User sees versions', :js do
outdated_diff_note.save!
refresh
+ wait_for_requests
expect(page).to have_css(".diffs .notes[data-discussion-id='#{outdated_diff_note.discussion_id}']")
end
diff --git a/spec/features/merge_request/user_views_user_status_on_merge_request_spec.rb b/spec/features/merge_request/user_views_user_status_on_merge_request_spec.rb
index f637186ec67..b214486b3c1 100644
--- a/spec/features/merge_request/user_views_user_status_on_merge_request_spec.rb
+++ b/spec/features/merge_request/user_views_user_status_on_merge_request_spec.rb
@@ -10,16 +10,6 @@ RSpec.describe 'Project > Merge request > View user status' do
subject { visit merge_request_path(merge_request) }
- describe 'the status of the merge request author' do
- before do
- stub_feature_flags(updated_mr_header: false)
- end
-
- it_behaves_like 'showing user status' do
- let(:user_with_status) { merge_request.author }
- end
- end
-
context 'for notes', :js do
describe 'the status of the author of a note on a merge request' do
let(:note) { create(:note, noteable: merge_request, project: project, author: create(:user)) }
diff --git a/spec/features/merge_requests/user_sorts_merge_requests_spec.rb b/spec/features/merge_requests/user_sorts_merge_requests_spec.rb
index 459145d3ef0..4a124299c61 100644
--- a/spec/features/merge_requests/user_sorts_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_sorts_merge_requests_spec.rb
@@ -17,8 +17,6 @@ RSpec.describe 'User sorts merge requests', :js do
let_it_be(:project) { create(:project, :public, group: group) }
before do
- stub_feature_flags(vue_issues_list: true)
-
sign_in(user)
visit(project_merge_requests_path(project))
diff --git a/spec/features/milestone_spec.rb b/spec/features/milestone_spec.rb
index b9594293996..5bbd89f1b88 100644
--- a/spec/features/milestone_spec.rb
+++ b/spec/features/milestone_spec.rb
@@ -64,7 +64,7 @@ RSpec.describe 'Milestone' do
end
find('input[name="commit"]').click
- expect(find('.alert-danger')).to have_content('already being used for another group or project milestone.')
+ expect(find('.gl-alert-danger')).to have_content('already being used for another group or project milestone.')
end
end
@@ -122,8 +122,8 @@ RSpec.describe 'Milestone' do
click_link 'Reopen Milestone'
- expect(page).not_to have_selector('.status-box-closed')
- expect(page).to have_selector('.status-box-open')
+ expect(page).not_to have_selector('.gl-bg-red-500')
+ expect(page).to have_selector('.gl-bg-green-500')
end
end
@@ -133,8 +133,8 @@ RSpec.describe 'Milestone' do
click_link 'Reopen Milestone'
- expect(page).not_to have_selector('.status-box-closed')
- expect(page).to have_selector('.status-box-open')
+ expect(page).not_to have_selector('.gl-bg-red-500')
+ expect(page).to have_selector('.gl-bg-green-500')
end
end
end
diff --git a/spec/features/nav/top_nav_responsive_spec.rb b/spec/features/nav/top_nav_responsive_spec.rb
index 5c6a12a37a3..d571327e4b5 100644
--- a/spec/features/nav/top_nav_responsive_spec.rb
+++ b/spec/features/nav/top_nav_responsive_spec.rb
@@ -41,7 +41,7 @@ RSpec.describe 'top nav responsive', :js do
end
it 'has new dropdown', :aggregate_failures do
- click_button('New...')
+ click_button('Create new')
expect(page).to have_link('New project', href: new_project_path)
expect(page).to have_link('New group', href: new_group_path)
diff --git a/spec/features/nav/top_nav_tooltip_spec.rb b/spec/features/nav/top_nav_tooltip_spec.rb
new file mode 100644
index 00000000000..58bfe1caf65
--- /dev/null
+++ b/spec/features/nav/top_nav_tooltip_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'top nav tooltips', :js do
+ let_it_be(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+ visit explore_projects_path
+ end
+
+ it 'clicking new dropdown hides tooltip', :aggregate_failures do
+ btn = '#js-onboarding-new-project-link'
+
+ page.find(btn).hover
+
+ expect(page).to have_content('Create new')
+
+ page.find(btn).click
+
+ expect(page).not_to have_content('Create new')
+ end
+end
diff --git a/spec/features/oauth_registration_spec.rb b/spec/features/oauth_registration_spec.rb
new file mode 100644
index 00000000000..18dd10755b1
--- /dev/null
+++ b/spec/features/oauth_registration_spec.rb
@@ -0,0 +1,91 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'OAuth Registration', :js, :allow_forgery_protection do
+ include DeviseHelpers
+ include LoginHelpers
+ include TermsHelper
+ using RSpec::Parameterized::TableSyntax
+
+ around do |example|
+ with_omniauth_full_host { example.run }
+ end
+
+ context 'when the user registers using single-sign on provider' do
+ let(:uid) { 'my-uid' }
+ let(:email) { 'user@example.com' }
+
+ where(:provider, :additional_info) do
+ :github | {}
+ :twitter | {}
+ :bitbucket | {}
+ :gitlab | {}
+ :google_oauth2 | {}
+ :facebook | {}
+ :cas3 | {}
+ :auth0 | {}
+ :authentiq | {}
+ :salesforce | { extra: { email_verified: true } }
+ :dingtalk | {}
+ :alicloud | {}
+ end
+
+ with_them do
+ before do
+ stub_omniauth_provider(provider)
+ stub_feature_flags(update_oauth_registration_flow: true)
+ end
+
+ context 'when block_auto_created_users is true' do
+ before do
+ stub_omniauth_setting(block_auto_created_users: true)
+ end
+
+ it 'redirects back to the sign-in page' do
+ register_via(provider, uid, email, additional_info: additional_info)
+
+ expect(page).to have_current_path new_user_session_path
+ expect(page).to have_content('Your account is pending approval')
+ end
+ end
+
+ context 'when block_auto_created_users is false' do
+ before do
+ stub_omniauth_setting(block_auto_created_users: false)
+ end
+
+ it 'redirects to the initial welcome path' do
+ register_via(provider, uid, email, additional_info: additional_info)
+
+ expect(page).to have_current_path users_sign_up_welcome_path
+ expect(page).to have_content('Welcome to GitLab, mockuser!')
+ end
+
+ context 'when terms are enforced' do
+ before do
+ enforce_terms
+ end
+
+ it 'auto accepts terms and redirects to the initial welcome path' do
+ register_via(provider, uid, email, additional_info: additional_info)
+
+ expect(page).to have_current_path users_sign_up_welcome_path
+ expect(page).to have_content('Welcome to GitLab, mockuser!')
+ end
+ end
+
+ context 'when provider does not send a verified email address' do
+ let(:email) { 'temp-email-for-oauth@email.com' }
+
+ it 'redirects to the profile path' do
+ register_via(provider, uid, email, additional_info: additional_info)
+
+ expect(page).to have_current_path profile_path
+ expect(page).to have_content('Please complete your profile with email address')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb
index 36657406303..1013937ebb9 100644
--- a/spec/features/profile_spec.rb
+++ b/spec/features/profile_spec.rb
@@ -3,10 +3,11 @@
require 'spec_helper'
RSpec.describe 'Profile account page', :js do
+ include Spec::Support::Helpers::ModalHelpers
+
let(:user) { create(:user) }
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
end
@@ -65,11 +66,17 @@ RSpec.describe 'Profile account page', :js do
it 'allows resetting of feed token' do
visit profile_personal_access_tokens_path
+ previous_token = ''
+
within('[data-testid="feed-token-container"]') do
previous_token = find_field('Feed token').value
- accept_confirm { click_link('reset this token') }
+ click_link('reset this token')
+ end
+ accept_gl_confirm
+
+ within('[data-testid="feed-token-container"]') do
click_button('Click to reveal')
expect(find_field('Feed token').value).not_to eq(previous_token)
@@ -81,11 +88,17 @@ RSpec.describe 'Profile account page', :js do
visit profile_personal_access_tokens_path
+ previous_token = ''
+
within('[data-testid="incoming-email-token-container"]') do
previous_token = find_field('Incoming email token').value
- accept_confirm { click_link('reset this token') }
+ click_link('reset this token')
+ end
+
+ accept_gl_confirm
+ within('[data-testid="incoming-email-token-container"]') do
click_button('Click to reveal')
expect(find_field('Incoming email token').value).not_to eq(previous_token)
diff --git a/spec/features/profiles/active_sessions_spec.rb b/spec/features/profiles/active_sessions_spec.rb
index a515c7b1c1f..24c9225532b 100644
--- a/spec/features/profiles/active_sessions_spec.rb
+++ b/spec/features/profiles/active_sessions_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
+ include Spec::Support::Helpers::ModalHelpers
+
let(:user) do
create(:user).tap do |user|
user.current_sign_in_at = Time.current
@@ -11,10 +13,6 @@ RSpec.describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
let(:admin) { create(:admin) }
- before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
- end
-
it 'user sees their active sessions' do
travel_to(Time.zone.parse('2018-03-12 09:06')) do
Capybara::Session.new(:session1)
@@ -101,7 +99,9 @@ RSpec.describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
expect(page).to have_link('Revoke', count: 1)
- accept_confirm { click_on 'Revoke' }
+ accept_gl_confirm(button_text: 'Revoke') do
+ click_on 'Revoke'
+ end
expect(page).not_to have_link('Revoke')
end
diff --git a/spec/features/profiles/oauth_applications_spec.rb b/spec/features/profiles/oauth_applications_spec.rb
index 9d79041dc9d..ee1daf69f62 100644
--- a/spec/features/profiles/oauth_applications_spec.rb
+++ b/spec/features/profiles/oauth_applications_spec.rb
@@ -3,11 +3,12 @@
require 'spec_helper'
RSpec.describe 'Profile > Applications' do
+ include Spec::Support::Helpers::ModalHelpers
+
let(:user) { create(:user) }
let(:application) { create(:oauth_application, owner: user) }
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
end
@@ -25,9 +26,11 @@ RSpec.describe 'Profile > Applications' do
page.within('.oauth-applications') do
expect(page).to have_content('Your applications (1)')
- accept_confirm { click_button 'Destroy' }
+ click_button 'Destroy'
end
+ accept_gl_confirm(button_text: 'Destroy')
+
expect(page).to have_content('The application was deleted successfully')
expect(page).to have_content('Your applications (0)')
expect(page).to have_content('Authorized applications (0)')
@@ -39,9 +42,11 @@ RSpec.describe 'Profile > Applications' do
page.within('.oauth-authorized-applications') do
expect(page).to have_content('Authorized applications (1)')
- accept_confirm { click_button 'Revoke' }
+ click_button 'Revoke'
end
+ accept_gl_confirm(button_text: 'Revoke application')
+
expect(page).to have_content('The application was revoked access.')
expect(page).to have_content('Your applications (0)')
expect(page).to have_content('Authorized applications (0)')
diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb
index 8cbc0491441..bca1bc4df4d 100644
--- a/spec/features/profiles/personal_access_tokens_spec.rb
+++ b/spec/features/profiles/personal_access_tokens_spec.rb
@@ -3,34 +3,24 @@
require 'spec_helper'
RSpec.describe 'Profile > Personal Access Tokens', :js do
+ include Spec::Support::Helpers::ModalHelpers
+
let(:user) { create(:user) }
let(:pat_create_service) { double('PersonalAccessTokens::CreateService', execute: ServiceResponse.error(message: 'error', payload: { personal_access_token: PersonalAccessToken.new })) }
def active_personal_access_tokens
- find(".table.active-tokens")
- end
-
- def no_personal_access_tokens_message
- find(".settings-message")
+ find("[data-testid='active-tokens']")
end
def created_personal_access_token
- find("#created-personal-access-token").value
+ find_field('new-access-token').value
end
def feed_token_description
"Your feed token authenticates you when your RSS reader loads a personalized RSS feed or when your calendar application loads a personalized calendar. It is visible in those feed URLs."
end
- def disallow_personal_access_token_saves!
- allow(PersonalAccessTokens::CreateService).to receive(:new).and_return(pat_create_service)
-
- errors = ActiveModel::Errors.new(PersonalAccessToken.new).tap { |e| e.add(:name, "cannot be nil") }
- allow_any_instance_of(PersonalAccessToken).to receive(:errors).and_return(errors)
- end
-
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
end
@@ -51,6 +41,7 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
check "read_user"
click_on "Create personal access token"
+ wait_for_all_requests
expect(active_personal_access_tokens).to have_text(name)
expect(active_personal_access_tokens).to have_text('in')
@@ -61,13 +52,16 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
context "when creation fails" do
it "displays an error message" do
- disallow_personal_access_token_saves!
+ number_tokens_before = PersonalAccessToken.count
visit profile_personal_access_tokens_path
fill_in "Token name", with: 'My PAT'
- expect { click_on "Create personal access token" }.not_to change { PersonalAccessToken.count }
- expect(page).to have_content("Name cannot be nil")
- expect(page).not_to have_selector("#created-personal-access-token")
+ click_on "Create personal access token"
+ wait_for_all_requests
+
+ expect(number_tokens_before).to equal(PersonalAccessToken.count)
+ expect(page).to have_content(_("Scopes can't be blank"))
+ expect(page).not_to have_selector("[data-testid='new-access-tokens']")
end
end
end
@@ -101,31 +95,27 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
it "allows revocation of an active token" do
visit profile_personal_access_tokens_path
- accept_confirm { click_on "Revoke" }
+ accept_gl_confirm(button_text: 'Revoke') { click_on "Revoke" }
- expect(page).to have_selector(".settings-message")
- expect(no_personal_access_tokens_message).to have_text("This user has no active personal access tokens.")
+ expect(active_personal_access_tokens).to have_text("This user has no active personal access tokens.")
end
it "removes expired tokens from 'active' section" do
personal_access_token.update!(expires_at: 5.days.ago)
visit profile_personal_access_tokens_path
- expect(page).to have_selector(".settings-message")
- expect(no_personal_access_tokens_message).to have_text("This user has no active personal access tokens.")
+ expect(active_personal_access_tokens).to have_text("This user has no active personal access tokens.")
end
context "when revocation fails" do
it "displays an error message" do
- visit profile_personal_access_tokens_path
-
allow_next_instance_of(PersonalAccessTokens::RevokeService) do |instance|
allow(instance).to receive(:revocation_permitted?).and_return(false)
end
+ visit profile_personal_access_tokens_path
- accept_confirm { click_on "Revoke" }
+ accept_gl_confirm(button_text: "Revoke") { click_on "Revoke" }
expect(active_personal_access_tokens).to have_text(personal_access_token.name)
- expect(page).to have_content("Not permitted to revoke")
end
end
end
diff --git a/spec/features/profiles/user_visits_profile_spec.rb b/spec/features/profiles/user_visits_profile_spec.rb
index 7d545711997..8b1af283765 100644
--- a/spec/features/profiles/user_visits_profile_spec.rb
+++ b/spec/features/profiles/user_visits_profile_spec.rb
@@ -89,6 +89,10 @@ RSpec.describe 'User visits their profile' do
end
describe 'storage_enforcement_banner', :js do
+ before do
+ stub_feature_flags(namespace_storage_limit_bypass_date_check: false)
+ end
+
context 'with storage_enforcement_date set' do
let_it_be(:storage_enforcement_date) { Date.today + 30 }
diff --git a/spec/features/project_variables_spec.rb b/spec/features/project_variables_spec.rb
index cc59fea173b..89dbd1afc6b 100644
--- a/spec/features/project_variables_spec.rb
+++ b/spec/features/project_variables_spec.rb
@@ -12,28 +12,36 @@ RSpec.describe 'Project variables', :js do
sign_in(user)
project.add_maintainer(user)
project.variables << variable
- visit page_path
end
- it_behaves_like 'variable list'
-
- it 'adds a new variable with an environment scope' do
- click_button('Add variable')
+ # TODO: Add same tests but with FF enabled context when
+ # the new graphQL app for variable settings is enabled.
+ context 'with disabled ff `ci_variable_settings_graphql' do
+ before do
+ stub_feature_flags(ci_variable_settings_graphql: false)
+ visit page_path
+ end
- page.within('#add-ci-variable') do
- fill_in 'Key', with: 'akey'
- find('#ci-variable-value').set('akey_value')
- find('[data-testid="environment-scope"]').click
- find('[data-testid="ci-environment-search"]').set('review/*')
- find('[data-testid="create-wildcard-button"]').click
+ it_behaves_like 'variable list'
+ it 'adds a new variable with an environment scope' do
click_button('Add variable')
- end
- wait_for_requests
+ page.within('#add-ci-variable') do
+ fill_in 'Key', with: 'akey'
+ find('#ci-variable-value').set('akey_value')
+ find('[data-testid="environment-scope"]').click
+ find('[data-testid="ci-environment-search"]').set('review/*')
+ find('[data-testid="create-wildcard-button"]').click
+
+ click_button('Add variable')
+ end
+
+ wait_for_requests
- page.within('[data-testid="ci-variable-table"]') do
- expect(find('.js-ci-variable-row:first-child [data-label="Environments"]').text).to eq('review/*')
+ page.within('[data-testid="ci-variable-table"]') do
+ expect(find('.js-ci-variable-row:first-child [data-label="Environments"]').text).to eq('review/*')
+ end
end
end
end
diff --git a/spec/features/projects/branches/user_deletes_branch_spec.rb b/spec/features/projects/branches/user_deletes_branch_spec.rb
index 0d08e7ea10d..a89fed3a78a 100644
--- a/spec/features/projects/branches/user_deletes_branch_spec.rb
+++ b/spec/features/projects/branches/user_deletes_branch_spec.rb
@@ -3,6 +3,8 @@
require "spec_helper"
RSpec.describe "User deletes branch", :js do
+ include Spec::Support::Helpers::ModalHelpers
+
let_it_be(:user) { create(:user) }
let(:project) { create(:project, :repository) }
@@ -24,9 +26,7 @@ RSpec.describe "User deletes branch", :js do
find('.js-delete-branch-button').click
end
- page.within '.modal-footer' do
- click_button 'Yes, delete branch'
- end
+ accept_gl_confirm(button_text: 'Yes, delete branch')
wait_for_requests
diff --git a/spec/features/projects/ci/editor_spec.rb b/spec/features/projects/ci/editor_spec.rb
index 2f960c09936..8197fe46c7b 100644
--- a/spec/features/projects/ci/editor_spec.rb
+++ b/spec/features/projects/ci/editor_spec.rb
@@ -12,8 +12,6 @@ RSpec.describe 'Pipeline Editor', :js do
let(:other_branch) { 'test' }
before do
- stub_feature_flags(pipeline_editor_file_tree: false)
-
sign_in(user)
project.add_developer(user)
@@ -70,14 +68,8 @@ RSpec.describe 'Pipeline Editor', :js do
expect(page).to have_content('Pipeline Editor')
end
- describe 'Branch Switcher (pipeline_editor_file_tree disabled)' do
- it_behaves_like 'default branch switcher behavior'
- end
-
- describe 'Branch Switcher (pipeline_editor_file_tree enabled)' do
+ describe 'Branch Switcher' do
before do
- stub_feature_flags(pipeline_editor_file_tree: true)
-
visit project_ci_pipeline_editor_path(project)
wait_for_requests
diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb
index a8a23ba1c85..5c54b7fda7c 100644
--- a/spec/features/projects/clusters/gcp_spec.rb
+++ b/spec/features/projects/clusters/gcp_spec.rb
@@ -66,9 +66,9 @@ RSpec.describe 'Gcp Cluster', :js do
context 'when user destroys the cluster' do
before do
click_link 'Advanced Settings'
- click_button 'Remove integration and resources'
+ find('[data-testid="remove-integration-button"]').click
fill_in 'confirm_cluster_name_input', with: cluster.name
- click_button 'Remove integration'
+ find('[data-testid="remove-integration-modal-button"]').click
click_link 'Certificate'
end
diff --git a/spec/features/projects/clusters/user_spec.rb b/spec/features/projects/clusters/user_spec.rb
index b6bfaa3a9b9..527d038f975 100644
--- a/spec/features/projects/clusters/user_spec.rb
+++ b/spec/features/projects/clusters/user_spec.rb
@@ -100,9 +100,9 @@ RSpec.describe 'User Cluster', :js do
context 'when user destroys the cluster' do
before do
click_link 'Advanced Settings'
- click_button 'Remove integration and resources'
+ find('[data-testid="remove-integration-button"]').click
fill_in 'confirm_cluster_name_input', with: cluster.name
- click_button 'Remove integration'
+ find('[data-testid="remove-integration-modal-button"]').click
click_link 'Certificate'
end
diff --git a/spec/features/projects/commit/comments/user_deletes_comments_spec.rb b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb
index 67d3276fc14..9059f9e4857 100644
--- a/spec/features/projects/commit/comments/user_deletes_comments_spec.rb
+++ b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb
@@ -4,6 +4,7 @@ require "spec_helper"
RSpec.describe "User deletes comments on a commit", :js do
include Spec::Support::Helpers::Features::NotesHelpers
+ include Spec::Support::Helpers::ModalHelpers
include RepoHelpers
let(:comment_text) { "XML attached" }
@@ -11,7 +12,6 @@ RSpec.describe "User deletes comments on a commit", :js do
let(:user) { create(:user) }
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
project.add_developer(user)
@@ -32,9 +32,11 @@ RSpec.describe "User deletes comments on a commit", :js do
find(".more-actions").click
find(".more-actions .dropdown-menu li", match: :first)
- accept_confirm { find(".js-note-delete").click }
+ find(".js-note-delete").click
end
+ accept_gl_confirm(button_text: 'Delete comment')
+
expect(page).not_to have_css(".note")
end
end
diff --git a/spec/features/projects/commit/user_comments_on_commit_spec.rb b/spec/features/projects/commit/user_comments_on_commit_spec.rb
index b0be6edb245..a7f23f093a3 100644
--- a/spec/features/projects/commit/user_comments_on_commit_spec.rb
+++ b/spec/features/projects/commit/user_comments_on_commit_spec.rb
@@ -4,6 +4,7 @@ require "spec_helper"
RSpec.describe "User comments on commit", :js do
include Spec::Support::Helpers::Features::NotesHelpers
+ include Spec::Support::Helpers::ModalHelpers
include RepoHelpers
let_it_be(:project) { create(:project, :repository) }
@@ -93,8 +94,6 @@ RSpec.describe "User comments on commit", :js do
context "when deleting comment" do
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
-
visit(project_commit_path(project, sample_commit.id))
add_note(comment_text)
@@ -112,9 +111,11 @@ RSpec.describe "User comments on commit", :js do
find(".more-actions").click
find(".more-actions .dropdown-menu li", match: :first)
- accept_confirm { find(".js-note-delete").click }
+ find(".js-note-delete").click
end
+ accept_gl_confirm(button_text: 'Delete comment')
+
expect(page).not_to have_css(".note")
end
end
diff --git a/spec/features/projects/commits/multi_view_diff_spec.rb b/spec/features/projects/commits/multi_view_diff_spec.rb
index 009dd05c6d1..282112a3767 100644
--- a/spec/features/projects/commits/multi_view_diff_spec.rb
+++ b/spec/features/projects/commits/multi_view_diff_spec.rb
@@ -18,71 +18,77 @@ RSpec.describe 'Multiple view Diffs', :js do
let(:feature_flag_on) { false }
before do
- stub_feature_flags(rendered_diffs_viewer: feature_flag_on ? project : false)
-
visit path
wait_for_all_requests
end
- context 'when :rendered_diffs_viewer is off' do
- context 'and diff does not have ipynb' do
- it_behaves_like "no multiple viewers", 'ddd0f15ae83993f5cb66a927a28673882e99100b'
+ context 'diff does not include ipynb' do
+ it_behaves_like "no multiple viewers", 'ddd0f15ae83993f5cb66a927a28673882e99100b'
+
+ context 'and in inline diff' do
+ let(:ref) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' }
+
+ it 'does not change display for non-ipynb' do
+ expect(page).to have_selector line_with_content('new', 1)
+ end
end
- context 'and diff has ipynb' do
- it_behaves_like "no multiple viewers", '5d6ed1503801ca9dc28e95eeb85a7cf863527aee'
+ context 'and in parallel diff' do
+ let(:ref) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' }
+
+ it 'does not change display for non-ipynb' do
+ page.find('#parallel-diff-btn').click
+
+ expect(page).to have_selector line_with_content('new', 1)
+ end
end
end
- context 'when :rendered_diffs_viewer is on' do
- let(:feature_flag_on) { true }
+ context 'opening a diff with ipynb' do
+ it 'loads the rendered diff as hidden' do
+ diff = page.find('.diff-file, .file-holder', match: :first)
- context 'and diff does not include ipynb' do
- it_behaves_like "no multiple viewers", 'ddd0f15ae83993f5cb66a927a28673882e99100b'
+ expect(diff).not_to have_selector '[data-diff-toggle-entity="toHide"]'
+ expect(diff).to have_selector '[data-diff-toggle-entity="toShow"]'
- context 'and in inline diff' do
- let(:ref) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' }
+ expect(classes_for_element(diff, 'toHide', visible: false)).to include('hidden')
+ expect(classes_for_element(diff, 'toShow')).not_to include('hidden')
- it 'does not change display for non-ipynb' do
- expect(page).to have_selector line_with_content('new', 1)
- end
- end
+ expect(classes_for_element(diff, 'toShowBtn')).to include('selected')
+ expect(classes_for_element(diff, 'toHideBtn')).not_to include('selected')
+ end
- context 'and in parallel diff' do
- let(:ref) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' }
+ it 'displays the rendered diff and hides after selection changes' do
+ diff = page.find('.diff-file, .file-holder', match: :first)
+ diff.find('[data-diff-toggle-entity="toShowBtn"]').click
- it 'does not change display for non-ipynb' do
- page.find('#parallel-diff-btn').click
+ expect(diff).to have_selector '[data-diff-toggle-entity="toShow"]'
+ expect(diff).not_to have_selector '[data-diff-toggle-entity="toHide"]'
- expect(page).to have_selector line_with_content('new', 1)
- end
- end
+ expect(classes_for_element(diff, 'toHideBtn')).not_to include('selected')
+ expect(classes_for_element(diff, 'toShowBtn')).to include('selected')
end
- context 'and opening a diff with ipynb' do
- it 'loads the rendered diff as hidden' do
- diff = page.find('.diff-file, .file-holder', match: :first)
-
- expect(diff).not_to have_selector '[data-diff-toggle-entity="toHide"]'
- expect(diff).to have_selector '[data-diff-toggle-entity="toShow"]'
+ it 'transforms the diff' do
+ diff = page.find('.diff-file, .file-holder', match: :first)
- expect(classes_for_element(diff, 'toHide', visible: false)).to include('hidden')
- expect(classes_for_element(diff, 'toShow')).not_to include('hidden')
+ expect(diff['innerHTML']).to include('%% Cell type:markdown id:0aac5da7-745c-4eda-847a-3d0d07a1bb9b tags:')
+ end
- expect(classes_for_element(diff, 'toShowBtn')).to include('selected')
- expect(classes_for_element(diff, 'toHideBtn')).not_to include('selected')
+ context 'on parallel view' do
+ before do
+ page.find('#parallel-diff-btn').click
end
- it 'displays the rendered diff and hides after selection changes' do
- diff = page.find('.diff-file, .file-holder', match: :first)
- diff.find('[data-diff-toggle-entity="toShowBtn"]').click
-
- expect(diff).to have_selector '[data-diff-toggle-entity="toShow"]'
- expect(diff).not_to have_selector '[data-diff-toggle-entity="toHide"]'
+ it 'lines without mapping cannot receive comments' do
+ expect(page).not_to have_selector('td.line_content.nomappinginraw ~ td.diff-line-num > .add-diff-note')
+ expect(page).to have_selector('td.line_content:not(.nomappinginraw) ~ td.diff-line-num > .add-diff-note')
+ end
- expect(classes_for_element(diff, 'toHideBtn')).not_to include('selected')
- expect(classes_for_element(diff, 'toShowBtn')).to include('selected')
+ it 'lines numbers without mapping are empty' do
+ expect(page).not_to have_selector('td.nomappinginraw + td.diff-line-num')
+ expect(page).to have_selector('td.nomappinginraw + td.diff-line-num', visible: false)
end
it 'transforms the diff' do
@@ -90,40 +96,18 @@ RSpec.describe 'Multiple view Diffs', :js do
expect(diff['innerHTML']).to include('%% Cell type:markdown id:0aac5da7-745c-4eda-847a-3d0d07a1bb9b tags:')
end
+ end
- context 'on parallel view' do
- before do
- page.find('#parallel-diff-btn').click
- end
-
- it 'lines without mapping cannot receive comments' do
- expect(page).not_to have_selector('td.line_content.nomappinginraw ~ td.diff-line-num > .add-diff-note')
- expect(page).to have_selector('td.line_content:not(.nomappinginraw) ~ td.diff-line-num > .add-diff-note')
- end
-
- it 'lines numbers without mapping are empty' do
- expect(page).not_to have_selector('td.nomappinginraw + td.diff-line-num')
- expect(page).to have_selector('td.nomappinginraw + td.diff-line-num', visible: false)
- end
-
- it 'transforms the diff' do
- diff = page.find('.diff-file, .file-holder', match: :first)
-
- expect(diff['innerHTML']).to include('%% Cell type:markdown id:0aac5da7-745c-4eda-847a-3d0d07a1bb9b tags:')
- end
+ context 'on inline view' do
+ it 'lines without mapping cannot receive comments' do
+ expect(page).not_to have_selector('tr.line_holder[class$="nomappinginraw"] > td.diff-line-num > .add-diff-note')
+ expect(page).to have_selector('tr.line_holder:not([class$="nomappinginraw"]) > td.diff-line-num > .add-diff-note')
end
- context 'on inline view' do
- it 'lines without mapping cannot receive comments' do
- expect(page).not_to have_selector('tr.line_holder[class$="nomappinginraw"] > td.diff-line-num > .add-diff-note')
- expect(page).to have_selector('tr.line_holder:not([class$="nomappinginraw"]) > td.diff-line-num > .add-diff-note')
- end
-
- it 'lines numbers without mapping are empty' do
- elements = page.all('tr.line_holder[class$="nomappinginraw"] > td.diff-line-num').map { |e| e.text(:all) }
+ it 'lines numbers without mapping are empty' do
+ elements = page.all('tr.line_holder[class$="nomappinginraw"] > td.diff-line-num').map { |e| e.text(:all) }
- expect(elements).to all(be == "")
- end
+ expect(elements).to all(be == "")
end
end
end
diff --git a/spec/features/projects/container_registry_spec.rb b/spec/features/projects/container_registry_spec.rb
index 17eb421191f..54685441300 100644
--- a/spec/features/projects/container_registry_spec.rb
+++ b/spec/features/projects/container_registry_spec.rb
@@ -122,7 +122,7 @@ RSpec.describe 'Container Registry', :js do
it 'renders the tags list correctly' do
expect(page).to have_content('latest')
expect(page).to have_content('stable')
- expect(page).to have_content('Digest: N/A')
+ expect(page).to have_content('Digest: Not applicable.')
end
end
diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb
index bfd54b9c6da..951b24eafac 100644
--- a/spec/features/projects/environments/environment_spec.rb
+++ b/spec/features/projects/environments/environment_spec.rb
@@ -157,7 +157,7 @@ RSpec.describe 'Environment' do
context 'with related deployable present' do
let(:pipeline) { create(:ci_pipeline, project: project) }
- let(:build) { create(:ci_build, pipeline: pipeline) }
+ let(:build) { create(:ci_build, pipeline: pipeline, environment: environment.name) }
let(:deployment) do
create(:deployment, :success, environment: environment, deployable: build)
@@ -261,9 +261,12 @@ RSpec.describe 'Environment' do
context 'when environment is available' do
context 'with stop action' do
+ let(:build) { create(:ci_build, :success, pipeline: pipeline, environment: environment.name) }
+
let(:action) do
create(:ci_build, :manual, pipeline: pipeline,
- name: 'close_app')
+ name: 'close_app',
+ environment: environment.name)
end
let(:deployment) do
@@ -283,7 +286,6 @@ RSpec.describe 'Environment' do
click_button('Stop')
click_button('Stop environment') # confirm modal
wait_for_all_requests
- expect(page).to have_button('Delete')
end
end
@@ -361,8 +363,6 @@ RSpec.describe 'Environment' do
end
visit_environment(environment)
-
- expect(page).not_to have_button('Stop')
end
##
diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb
index 6cf59394af7..9ec41cd8f8d 100644
--- a/spec/features/projects/environments/environments_spec.rb
+++ b/spec/features/projects/environments/environments_spec.rb
@@ -132,8 +132,6 @@ RSpec.describe 'Environments page', :js do
create(:environment, project: project, state: :available)
end
- stub_feature_flags(bootstrap_confirmation_modals: false)
-
context 'when there are no deployments' do
before do
visit_environments(project)
diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb
index 23fcc1fe444..649c21d4459 100644
--- a/spec/features/projects/features_visibility_spec.rb
+++ b/spec/features/projects/features_visibility_spec.rb
@@ -189,7 +189,7 @@ RSpec.describe 'Edit Project Settings' do
click_button "Save changes"
end
- expect(find(".sharing-permissions")).to have_selector(".gl-toggle.is-disabled", minimum: 4)
+ expect(find(".sharing-permissions")).to have_selector(".gl-toggle.is-disabled", minimum: 3)
end
it "shows empty features project homepage" do
diff --git a/spec/features/projects/hook_logs/user_reads_log_spec.rb b/spec/features/projects/hook_logs/user_reads_log_spec.rb
index 8513a9374d1..9b7ec14c36f 100644
--- a/spec/features/projects/hook_logs/user_reads_log_spec.rb
+++ b/spec/features/projects/hook_logs/user_reads_log_spec.rb
@@ -3,21 +3,80 @@
require 'spec_helper'
RSpec.describe 'Hook logs' do
- let(:web_hook_log) { create(:web_hook_log, response_body: '<script>') }
- let(:project) { web_hook_log.web_hook.project }
+ let(:project) { create(:project) }
+ let(:project_hook) { create(:project_hook, project: project) }
+ let(:web_hook_log) { create(:web_hook_log, web_hook: project_hook, response_body: 'Hello World') }
let(:user) { create(:user) }
before do
+ web_hook_log
project.add_maintainer(user)
sign_in(user)
end
- it 'user reads log without getting XSS' do
- visit(
- project_hook_hook_log_path(
- project, web_hook_log.web_hook, web_hook_log))
+ it 'shows list of hook logs' do
+ visit edit_project_hook_path(project, project_hook)
- expect(page).to have_content('<script>')
+ expect(page).to have_content('Recent events')
+ expect(page).to have_link('View details', href: project_hook_hook_log_path(project, project_hook, web_hook_log))
+ end
+
+ it 'shows hook log details' do
+ visit edit_project_hook_path(project, project_hook)
+ click_link 'View details'
+
+ expect(page).to have_content("POST #{web_hook_log.url}")
+ expect(page).to have_content(web_hook_log.response_body)
+ expect(page).to have_content('Resend Request')
+ end
+
+ it 'retries hook log' do
+ WebMock.stub_request(:post, project_hook.url)
+
+ visit edit_project_hook_path(project, project_hook)
+ click_link 'View details'
+ click_link 'Resend Request'
+
+ expect(page).to have_current_path(edit_project_hook_path(project, project_hook), ignore_query: true)
+ end
+
+ context 'request gets internal error' do
+ let(:web_hook_log) { create(:web_hook_log, web_hook: project_hook, internal_error_message: 'Some error') }
+
+ it 'shows hook log details with internal error message' do
+ visit edit_project_hook_path(project, project_hook)
+ click_link 'View details'
+
+ expect(page).to have_content("POST #{web_hook_log.url}")
+ expect(page).to have_content(web_hook_log.internal_error_message)
+ expect(page).to have_content('Resend Request')
+ end
+ end
+
+ context 'response body contains XSS string' do
+ let(:web_hook_log) { create(:web_hook_log, web_hook: project_hook, response_body: '<script>') }
+
+ it 'displays log without getting XSS' do
+ visit(project_hook_hook_log_path(project, project_hook, web_hook_log))
+
+ expect(page).to have_content('<script>')
+ end
+ end
+
+ context 'response data is too large' do
+ let(:web_hook_log) do
+ create(:web_hook_log, web_hook: project_hook, request_data: WebHookLog::OVERSIZE_REQUEST_DATA)
+ end
+
+ it 'shows request data as too large and disables retry function' do
+ visit(project_hook_hook_log_path(project, project_hook, web_hook_log))
+
+ expect(page).to have_content('Request data is too large')
+ expect(page).not_to have_button(
+ _('Resent request'),
+ disabled: true, class: 'has-tooltip', title: _("Request data is too large")
+ )
+ end
end
end
diff --git a/spec/features/projects/integrations/user_activates_issue_tracker_spec.rb b/spec/features/projects/integrations/user_activates_issue_tracker_spec.rb
index 2821f35f6a6..e7d4ed58549 100644
--- a/spec/features/projects/integrations/user_activates_issue_tracker_spec.rb
+++ b/spec/features/projects/integrations/user_activates_issue_tracker_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe 'User activates issue tracker', :js do
it 'activates the integration' do
expect(page).to have_content("#{tracker} settings saved and active.")
- expect(page).to have_current_path(edit_project_integration_path(project, tracker.parameterize(separator: '_')), ignore_query: true)
+ expect(page).to have_current_path(edit_project_settings_integration_path(project, tracker.parameterize(separator: '_')), ignore_query: true)
end
it 'shows the link in the menu' do
@@ -58,7 +58,7 @@ RSpec.describe 'User activates issue tracker', :js do
end
expect(page).to have_content("#{tracker} settings saved and active.")
- expect(page).to have_current_path(edit_project_integration_path(project, tracker.parameterize(separator: '_')), ignore_query: true)
+ expect(page).to have_current_path(edit_project_settings_integration_path(project, tracker.parameterize(separator: '_')), ignore_query: true)
end
end
end
@@ -73,7 +73,7 @@ RSpec.describe 'User activates issue tracker', :js do
it 'saves but does not activate the integration' do
expect(page).to have_content("#{tracker} settings saved, but not active.")
- expect(page).to have_current_path(edit_project_integration_path(project, tracker.parameterize(separator: '_')), ignore_query: true)
+ expect(page).to have_current_path(edit_project_settings_integration_path(project, tracker.parameterize(separator: '_')), ignore_query: true)
end
it 'does not show the external tracker link in the menu' do
diff --git a/spec/features/projects/integrations/user_activates_jira_spec.rb b/spec/features/projects/integrations/user_activates_jira_spec.rb
index f855d6befe7..dad201ffbb6 100644
--- a/spec/features/projects/integrations/user_activates_jira_spec.rb
+++ b/spec/features/projects/integrations/user_activates_jira_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe 'User activates Jira', :js do
it 'activates the Jira integration' do
expect(page).to have_content('Jira settings saved and active.')
- expect(page).to have_current_path(edit_project_integration_path(project, :jira), ignore_query: true)
+ expect(page).to have_current_path(edit_project_settings_integration_path(project, :jira), ignore_query: true)
end
unless Gitlab.ee?
@@ -55,13 +55,13 @@ RSpec.describe 'User activates Jira', :js do
click_test_then_save_integration
expect(page).to have_content('Jira settings saved and active.')
- expect(page).to have_current_path(edit_project_integration_path(project, :jira), ignore_query: true)
+ expect(page).to have_current_path(edit_project_settings_integration_path(project, :jira), ignore_query: true)
end
end
end
describe 'user disables the Jira integration' do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
before do
stub_jira_integration_test
@@ -72,7 +72,7 @@ RSpec.describe 'User activates Jira', :js do
it 'saves but does not activate the Jira integration' do
expect(page).to have_content('Jira settings saved, but not active.')
- expect(page).to have_current_path(edit_project_integration_path(project, :jira), ignore_query: true)
+ expect(page).to have_current_path(edit_project_settings_integration_path(project, :jira), ignore_query: true)
end
it 'does not show the Jira link in the menu' do
diff --git a/spec/features/projects/integrations/user_activates_mattermost_slash_command_spec.rb b/spec/features/projects/integrations/user_activates_mattermost_slash_command_spec.rb
index ed0877ab0e9..54c9ec0f62e 100644
--- a/spec/features/projects/integrations/user_activates_mattermost_slash_command_spec.rb
+++ b/spec/features/projects/integrations/user_activates_mattermost_slash_command_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe 'Set up Mattermost slash commands', :js do
let(:mattermost_enabled) { true }
describe 'activation' do
- let(:edit_path) { edit_project_integration_path(project, :mattermost_slash_commands) }
+ let(:edit_path) { edit_project_settings_integration_path(project, :mattermost_slash_commands) }
include_examples 'user activates the Mattermost Slash Command integration'
end
diff --git a/spec/features/projects/integrations/user_activates_slack_notifications_spec.rb b/spec/features/projects/integrations/user_activates_slack_notifications_spec.rb
index 616469c5df8..e89f6e309ea 100644
--- a/spec/features/projects/integrations/user_activates_slack_notifications_spec.rb
+++ b/spec/features/projects/integrations/user_activates_slack_notifications_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe 'User activates Slack notifications', :js do
pipeline_channel: 6,
wiki_page_channel: 7)
- visit(edit_project_integration_path(project, integration))
+ visit(edit_project_settings_integration_path(project, integration))
end
it 'filters events by channel' do
diff --git a/spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb b/spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb
index 0b4c9620bdf..df8cd84ffdb 100644
--- a/spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb
+++ b/spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb
@@ -24,7 +24,11 @@ RSpec.describe 'Slack slash commands', :js do
click_active_checkbox
click_on 'Save'
- expect(page).to have_current_path(edit_project_integration_path(project, :slack_slash_commands), ignore_query: true)
+ expect(page).to have_current_path(
+ edit_project_settings_integration_path(project, :slack_slash_commands),
+ ignore_query: true
+ )
+
expect(page).to have_content('Slack slash commands settings saved, but not active.')
end
@@ -32,7 +36,11 @@ RSpec.describe 'Slack slash commands', :js do
fill_in 'Token', with: 'token'
click_on 'Save'
- expect(page).to have_current_path(edit_project_integration_path(project, :slack_slash_commands), ignore_query: true)
+ expect(page).to have_current_path(
+ edit_project_settings_integration_path(project, :slack_slash_commands),
+ ignore_query: true
+ )
+
expect(page).to have_content('Slack slash commands settings saved and active.')
end
diff --git a/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb b/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb
index fcb04c338a9..8a2881c95dc 100644
--- a/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb
+++ b/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe 'User uses inherited settings', :js do
- include JiraServiceHelper
+ include JiraIntegrationHelpers
include_context 'project integration activation'
diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb
index e2dc760beda..6a2d2c36521 100644
--- a/spec/features/projects/jobs/user_browses_job_spec.rb
+++ b/spec/features/projects/jobs/user_browses_job_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'User browses a job', :js do
+ include Spec::Support::Helpers::ModalHelpers
+
let(:user) { create(:user) }
let(:user_access_level) { :developer }
let(:project) { create(:project, :repository, namespace: user.namespace) }
@@ -12,7 +14,6 @@ RSpec.describe 'User browses a job', :js do
before do
project.add_maintainer(user)
project.enable_ci
- stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
end
@@ -26,7 +27,11 @@ RSpec.describe 'User browses a job', :js do
# scroll to the top of the page first
execute_script "window.scrollTo(0,0)"
- accept_confirm { find('[data-testid="job-log-erase-link"]').click }
+ accept_gl_confirm(button_text: 'Erase job log') do
+ find('[data-testid="job-log-erase-link"]').click
+ end
+
+ wait_for_requests
expect(page).to have_no_css('.artifacts')
expect(build).not_to have_trace
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index befaf85fc1e..f0d41c1dd11 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -987,7 +987,9 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
it 'renders message about job being stuck because of no runners with the specified tags' do
expect(page).to have_selector('[data-testid="job-stuck-with-tags"')
- expect(page).to have_content("This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:")
+ expect(page).to have_content("This job is stuck because of one of the following problems. There are no active runners online, no runners for the ")
+ expect(page).to have_content("protected branch")
+ expect(page).to have_content(", or no runners that match all of the job's tags:")
end
end
@@ -997,7 +999,9 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
it 'renders message about job being stuck because of no runners with the specified tags' do
expect(page).to have_selector('[data-testid="job-stuck-with-tags"')
- expect(page).to have_content("This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:")
+ expect(page).to have_content("This job is stuck because of one of the following problems. There are no active runners online, no runners for the ")
+ expect(page).to have_content("protected branch")
+ expect(page).to have_content(", or no runners that match all of the job's tags:")
end
end
diff --git a/spec/features/projects/members/manage_members_spec.rb b/spec/features/projects/members/manage_members_spec.rb
index 0f4120e88e0..8d229530ef5 100644
--- a/spec/features/projects/members/manage_members_spec.rb
+++ b/spec/features/projects/members/manage_members_spec.rb
@@ -48,20 +48,48 @@ RSpec.describe 'Projects > Members > Manage members', :js do
end
end
- it 'uses ProjectMember access_level_roles for the invite members modal access option', :aggregate_failures do
- visit_members_page
+ context 'when owner' do
+ it 'uses ProjectMember access_level_roles for the invite members modal access option', :aggregate_failures do
+ visit_members_page
- click_on 'Invite members'
+ click_on 'Invite members'
- click_on 'Guest'
- wait_for_requests
+ click_on 'Guest'
+ wait_for_requests
- page.within '.dropdown-menu' do
- expect(page).to have_button('Guest')
- expect(page).to have_button('Reporter')
- expect(page).to have_button('Developer')
- expect(page).to have_button('Maintainer')
- expect(page).not_to have_button('Owner')
+ page.within '.dropdown-menu' do
+ expect(page).to have_button('Guest')
+ expect(page).to have_button('Reporter')
+ expect(page).to have_button('Developer')
+ expect(page).to have_button('Maintainer')
+ expect(page).to have_button('Owner')
+ end
+ end
+ end
+
+ context 'when maintainer' do
+ let(:maintainer) { create(:user) }
+
+ before do
+ project.add_maintainer(maintainer)
+ sign_in(maintainer)
+ end
+
+ it 'uses ProjectMember access_level_roles for the invite members modal access option', :aggregate_failures do
+ visit_members_page
+
+ click_on 'Invite members'
+
+ click_on 'Guest'
+ wait_for_requests
+
+ page.within '.dropdown-menu' do
+ expect(page).to have_button('Guest')
+ expect(page).to have_button('Reporter')
+ expect(page).to have_button('Developer')
+ expect(page).to have_button('Maintainer')
+ expect(page).not_to have_button('Owner')
+ end
end
end
diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb
index 67c40c1dbee..db227f3701d 100644
--- a/spec/features/projects/members/member_leaves_project_spec.rb
+++ b/spec/features/projects/members/member_leaves_project_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe 'Projects > Members > Member leaves project' do
include Spec::Support::Helpers::Features::MembersHelpers
+ include Spec::Support::Helpers::ModalHelpers
let(:user) { create(:user) }
let(:project) { create(:project, :repository, :with_namespace_settings) }
@@ -11,7 +12,6 @@ RSpec.describe 'Projects > Members > Member leaves project' do
before do
project.add_developer(user)
sign_in(user)
- stub_feature_flags(bootstrap_confirmation_modals: false)
end
it 'user leaves project' do
@@ -26,7 +26,7 @@ RSpec.describe 'Projects > Members > Member leaves project' do
it 'user leaves project by url param', :js do
visit project_path(project, leave: 1)
- page.accept_confirm
+ accept_gl_confirm(button_text: 'Leave project')
wait_for_all_requests
expect(page).to have_current_path(dashboard_projects_path, ignore_query: true)
diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb
index 370d7b49832..be124502c32 100644
--- a/spec/features/projects/members/user_requests_access_spec.rb
+++ b/spec/features/projects/members/user_requests_access_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Projects > Members > User requests access', :js do
+ include Spec::Support::Helpers::ModalHelpers
+
let_it_be(:user) { create(:user) }
let_it_be(:maintainer) { create(:user) }
let_it_be(:project) { create(:project, :public, :repository) }
@@ -13,7 +15,6 @@ RSpec.describe 'Projects > Members > User requests access', :js do
sign_in(user)
project.add_maintainer(maintainer)
visit project_path(project)
- stub_feature_flags(bootstrap_confirmation_modals: false)
end
it 'request access feature is disabled' do
@@ -67,7 +68,7 @@ RSpec.describe 'Projects > Members > User requests access', :js do
expect(project.requesters.exists?(user_id: user)).to be_truthy
- accept_confirm { click_link 'Withdraw Access Request' }
+ accept_gl_confirm { click_link 'Withdraw Access Request' }
expect(page).not_to have_content 'Withdraw Access Request'
expect(page).to have_content 'Request Access'
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index 0046dfe436f..c323e60bb71 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -57,10 +57,37 @@ RSpec.describe 'New project', :js do
expect(page).to have_link('GitHub')
expect(page).to have_link('Bitbucket')
expect(page).to have_link('GitLab.com')
- expect(page).to have_button('Repo by URL')
+ expect(page).to have_button('Repository by URL')
expect(page).to have_link('GitLab export')
end
+ describe 'github import option' do
+ context 'with user namespace' do
+ before do
+ visit new_project_path
+ click_link 'Import project'
+ end
+
+ it 'renders link to github importer' do
+ expect(page).to have_link(href: new_import_github_path)
+ end
+ end
+
+ context 'with group namespace' do
+ let(:group) { create(:group, :private) }
+
+ before do
+ group.add_owner(user)
+ visit new_project_path(namespace_id: group.id)
+ click_link 'Import project'
+ end
+
+ it 'renders link to github importer including namespace id' do
+ expect(page).to have_link(href: new_import_github_path(namespace_id: group.id))
+ end
+ end
+ end
+
describe 'manifest import option' do
before do
visit new_project_path
@@ -175,7 +202,7 @@ RSpec.describe 'New project', :js do
it 'does not show the initialize with Readme checkbox on "Import project" tab' do
visit new_project_path
click_link 'Import project'
- click_button 'Repo by URL'
+ click_button 'Repository by URL'
page.within '#import-project-pane' do
expect(page).not_to have_css('input#project_initialize_with_readme')
@@ -277,7 +304,7 @@ RSpec.describe 'New project', :js do
click_link 'Import project'
end
- context 'from git repository url, "Repo by URL"' do
+ context 'from git repository url, "Repository by URL"' do
before do
first('.js-import-git-toggle-button').click
end
diff --git a/spec/features/projects/pages/user_adds_domain_spec.rb b/spec/features/projects/pages/user_adds_domain_spec.rb
index 71bf1c24655..afa3f29ce0d 100644
--- a/spec/features/projects/pages/user_adds_domain_spec.rb
+++ b/spec/features/projects/pages/user_adds_domain_spec.rb
@@ -3,6 +3,7 @@ require 'spec_helper'
RSpec.describe 'User adds pages domain', :js do
include LetsEncryptHelpers
+ include Spec::Support::Helpers::ModalHelpers
let_it_be(:project) { create(:project, pages_https_only: false) }
@@ -14,8 +15,6 @@ RSpec.describe 'User adds pages domain', :js do
project.add_maintainer(user)
sign_in(user)
-
- stub_feature_flags(bootstrap_confirmation_modals: false)
end
context 'when pages are exposed on external HTTP address', :http_pages_enabled do
@@ -95,7 +94,7 @@ RSpec.describe 'User adds pages domain', :js do
fill_in 'Domain', with: 'my.test.domain.com'
- find('.js-auto-ssl-toggle-container .js-project-feature-toggle').click
+ find('.js-auto-ssl-toggle-container .js-project-feature-toggle button').click
fill_in 'Certificate (PEM)', with: certificate_pem
fill_in 'Key (PEM)', with: certificate_key
@@ -168,7 +167,7 @@ RSpec.describe 'User adds pages domain', :js do
within('#content-body') { click_link 'Edit' }
- accept_confirm { click_link 'Remove' }
+ accept_gl_confirm(button_text: 'Remove certificate') { click_link 'Remove' }
expect(page).to have_field('Certificate (PEM)', with: '')
expect(page).to have_field('Key (PEM)', with: '')
diff --git a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb
index bdf280f4fe4..4c633bea64e 100644
--- a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb
+++ b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb
@@ -3,6 +3,7 @@ require 'spec_helper'
RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do
include LetsEncryptHelpers
+ include Spec::Support::Helpers::ModalHelpers
let(:project) { create(:project, pages_https_only: false) }
let(:user) { create(:user) }
@@ -14,7 +15,6 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do
before do
allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
stub_lets_encrypt_settings
- stub_feature_flags(bootstrap_confirmation_modals: false)
project.add_role(user, role)
sign_in(user)
@@ -50,7 +50,7 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do
expect(page).to have_selector '.card-header', text: 'Certificate'
expect(page).to have_text domain.subject
- find('.js-auto-ssl-toggle-container .js-project-feature-toggle').click
+ find('.js-auto-ssl-toggle-container .js-project-feature-toggle button').click
expect(find("#pages_domain_auto_ssl_enabled", visible: false).value).to eq 'true'
expect(page).not_to have_selector '.card-header', text: 'Certificate'
@@ -74,7 +74,7 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do
expect(page).not_to have_field 'Certificate (PEM)', type: 'textarea'
expect(page).not_to have_field 'Key (PEM)', type: 'textarea'
- find('.js-auto-ssl-toggle-container .js-project-feature-toggle').click
+ find('.js-auto-ssl-toggle-container .js-project-feature-toggle button').click
expect(find("#pages_domain_auto_ssl_enabled", visible: false).value).to eq 'false'
expect(page).to have_field 'Certificate (PEM)', type: 'textarea'
@@ -139,7 +139,8 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do
expect(page).to have_selector '.card-header', text: 'Certificate'
expect(page).to have_text domain.subject
- within('.card') { accept_confirm { click_on 'Remove' } }
+ within('.card') { click_on 'Remove' }
+ accept_gl_confirm(button_text: 'Remove certificate')
expect(page).to have_field 'Certificate (PEM)', with: ''
expect(page).to have_field 'Key (PEM)', with: ''
end
diff --git a/spec/features/projects/pages/user_edits_settings_spec.rb b/spec/features/projects/pages/user_edits_settings_spec.rb
index 1226e1dc2ed..bd163f4a109 100644
--- a/spec/features/projects/pages/user_edits_settings_spec.rb
+++ b/spec/features/projects/pages/user_edits_settings_spec.rb
@@ -2,6 +2,8 @@
require 'spec_helper'
RSpec.describe 'Pages edits pages settings', :js do
+ include Spec::Support::Helpers::ModalHelpers
+
let(:project) { create(:project, pages_https_only: false) }
let(:user) { create(:user) }
@@ -176,7 +178,6 @@ RSpec.describe 'Pages edits pages settings', :js do
describe 'Remove page' do
context 'when pages are deployed' do
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
project.mark_pages_as_deployed
end
@@ -185,7 +186,7 @@ RSpec.describe 'Pages edits pages settings', :js do
expect(page).to have_link('Remove pages')
- accept_confirm { click_link 'Remove pages' }
+ accept_gl_confirm(button_text: 'Remove pages') { click_link 'Remove pages' }
expect(page).to have_content('Pages were scheduled for removal')
expect(project.reload.pages_deployed?).to be_falsey
diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb
index 7cb14feabd2..8cf6d5bd29b 100644
--- a/spec/features/projects/pipeline_schedules_spec.rb
+++ b/spec/features/projects/pipeline_schedules_spec.rb
@@ -3,15 +3,16 @@
require 'spec_helper'
RSpec.describe 'Pipeline Schedules', :js do
+ include Spec::Support::Helpers::ModalHelpers
+
let!(:project) { create(:project, :repository) }
let!(:pipeline_schedule) { create(:ci_pipeline_schedule, :nightly, project: project ) }
let!(:pipeline) { create(:ci_pipeline, pipeline_schedule: pipeline_schedule) }
let(:scope) { nil }
let!(:user) { create(:user) }
- context 'logged in as the pipeline scheduler owner' do
+ context 'logged in as the pipeline schedule owner' do
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
project.add_developer(user)
pipeline_schedule.update!(owner: user)
gitlab_sign_in(user)
@@ -81,7 +82,6 @@ RSpec.describe 'Pipeline Schedules', :js do
context 'logged in as a project maintainer' do
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
project.add_maintainer(user)
gitlab_sign_in(user)
end
@@ -117,7 +117,9 @@ RSpec.describe 'Pipeline Schedules', :js do
end
it 'deletes the pipeline' do
- accept_confirm { click_link 'Delete' }
+ click_link 'Delete'
+
+ accept_gl_confirm(button_text: 'Delete pipeline schedule')
expect(page).not_to have_css(".pipeline-schedule-table-row")
end
diff --git a/spec/features/projects/pipelines/legacy_pipeline_spec.rb b/spec/features/projects/pipelines/legacy_pipeline_spec.rb
index a29cef393a8..db6feecba03 100644
--- a/spec/features/projects/pipelines/legacy_pipeline_spec.rb
+++ b/spec/features/projects/pipelines/legacy_pipeline_spec.rb
@@ -1070,4 +1070,202 @@ RSpec.describe 'Pipeline', :js do
end
end
end
+
+ describe 'GET /:project/-/pipelines/:id/builds' do
+ include_context 'pipeline builds'
+
+ let_it_be(:project) { create(:project, :repository) }
+
+ let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) }
+
+ before do
+ visit builds_project_pipeline_path(project, pipeline)
+ end
+
+ it 'shows a list of jobs' do
+ expect(page).to have_content('Test')
+ expect(page).to have_content(build_passed.id)
+ expect(page).to have_content('Deploy')
+ expect(page).to have_content(build_failed.id)
+ expect(page).to have_content(build_running.id)
+ expect(page).to have_content(build_external.id)
+ expect(page).to have_content('Retry')
+ expect(page).to have_content('Cancel running')
+ expect(page).to have_button('Play')
+ end
+
+ context 'page tabs' do
+ it 'shows Pipeline, Jobs and DAG tabs with link' do
+ expect(page).to have_link('Pipeline')
+ expect(page).to have_link('Jobs')
+ expect(page).to have_link('Needs')
+ end
+
+ it 'shows counter in Jobs tab' do
+ expect(page.find('.js-builds-counter').text).to eq(pipeline.total_size.to_s)
+ end
+ end
+
+ context 'retrying jobs' do
+ it { expect(page).not_to have_content('retried') }
+
+ context 'when retrying' do
+ before do
+ find('[data-testid="retry"]', match: :first).click
+ end
+
+ it 'does not show a "Retry" button', :sidekiq_might_not_need_inline do
+ expect(page).not_to have_content('Retry')
+ end
+ end
+ end
+
+ context 'canceling jobs' do
+ it { expect(page).not_to have_selector('.ci-canceled') }
+
+ context 'when canceling' do
+ before do
+ click_on 'Cancel running'
+ end
+
+ it 'does not show a "Cancel running" button', :sidekiq_might_not_need_inline do
+ expect(page).not_to have_content('Cancel running')
+ end
+ end
+ end
+
+ context 'playing manual job' do
+ before do
+ within '[data-testid="jobs-tab-table"]' do
+ click_button('Play')
+
+ wait_for_requests
+ end
+ end
+
+ it { expect(build_manual.reload).to be_pending }
+ end
+
+ context 'when user unschedules a delayed job' do
+ before do
+ within '[data-testid="jobs-tab-table"]' do
+ click_button('Unschedule')
+ end
+ end
+
+ it 'unschedules the delayed job and shows play button as a manual job' do
+ expect(page).to have_button('Play')
+ expect(page).not_to have_button('Unschedule')
+ end
+ end
+ end
+
+ describe 'GET /:project/-/pipelines/:id/failures' do
+ let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: '1234') }
+ let(:pipeline_failures_page) { failures_project_pipeline_path(project, pipeline) }
+ let!(:failed_build) { create(:ci_build, :failed, pipeline: pipeline) }
+
+ subject { visit pipeline_failures_page }
+
+ context 'with failed build' do
+ before do
+ failed_build.trace.set('4 examples, 1 failure')
+ end
+
+ it 'lists failed builds' do
+ subject
+
+ expect(page).to have_content(failed_build.name)
+ expect(page).to have_content(failed_build.stage)
+ end
+
+ it 'shows build failure logs' do
+ subject
+
+ expect(page).to have_content('4 examples, 1 failure')
+ end
+
+ it 'shows the failure reason' do
+ subject
+
+ expect(page).to have_content('There is an unknown failure, please try again')
+ end
+
+ context 'when user does not have permission to retry build' do
+ it 'shows retry button for failed build' do
+ subject
+
+ page.within(find('#js-tab-failures', match: :first)) do
+ expect(page).not_to have_button('Retry')
+ end
+ end
+ end
+
+ context 'when user does have permission to retry build' do
+ before do
+ create(:protected_branch, :developers_can_merge,
+ name: pipeline.ref, project: project)
+ end
+
+ it 'shows retry button for failed build' do
+ subject
+
+ page.within(find('#js-tab-failures', match: :first)) do
+ expect(page).to have_button('Retry')
+ end
+ end
+ end
+ end
+
+ context 'when missing build logs' do
+ it 'lists failed builds' do
+ subject
+
+ expect(page).to have_content(failed_build.name)
+ expect(page).to have_content(failed_build.stage)
+ end
+
+ it 'does not show log' do
+ subject
+
+ expect(page).to have_content('No job log')
+ end
+ end
+
+ context 'without permission to access builds' do
+ let(:role) { :guest }
+
+ before do
+ project.update!(public_builds: false)
+ end
+
+ context 'when accessing failed jobs page' do
+ it 'renders a 404 page' do
+ requests = inspect_requests { subject }
+
+ expect(page).to have_title('Not Found')
+ expect(requests.first.status_code).to eq(404)
+ end
+ end
+ end
+
+ context 'without failures' do
+ before do
+ failed_build.update!(status: :success)
+ end
+
+ it 'does not show the failure tab' do
+ subject
+
+ expect(page).not_to have_content('Failed Jobs')
+ end
+
+ it 'displays the pipeline graph' do
+ subject
+
+ expect(page).to have_current_path(pipeline_path(pipeline), ignore_query: true)
+ expect(page).to have_selector('.js-pipeline-graph')
+ end
+ end
+ end
end
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index 9eda05f695d..a83d4191f38 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -414,16 +414,6 @@ RSpec.describe 'Pipeline', :js do
expect(page).to have_selector('button[aria-label="Retry downstream pipeline"]')
end
- context 'and the FF downstream_retry_action is disabled' do
- before do
- stub_feature_flags(downstream_retry_action: false)
- end
-
- it 'does not show the retry action' do
- expect(page).not_to have_selector('button[aria-label="Retry downstream pipeline"]')
- end
- end
-
context 'when retrying' do
before do
find('button[aria-label="Retry downstream pipeline"]').click
@@ -508,8 +498,7 @@ RSpec.describe 'Pipeline', :js do
end
it 'shows counter in Jobs tab' do
- skip('Enable in jobs `pipeline_tabs_vue` MR')
- expect(page.find('.js-builds-counter').text).to eq(pipeline.total_size.to_s)
+ expect(page.find('[data-testid="builds-counter"]').text).to eq(pipeline.total_size.to_s)
end
context 'without permission to access builds' do
@@ -889,7 +878,6 @@ RSpec.describe 'Pipeline', :js do
describe 'GET /:project/-/pipelines/:id/builds' do
before do
- stub_feature_flags(pipeline_tabs_vue: false)
visit builds_project_pipeline_path(project, pipeline)
end
@@ -1042,7 +1030,6 @@ RSpec.describe 'Pipeline', :js do
let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) }
before do
- stub_feature_flags(pipeline_tabs_vue: false)
visit builds_project_pipeline_path(project, pipeline)
end
@@ -1066,8 +1053,7 @@ RSpec.describe 'Pipeline', :js do
end
it 'shows counter in Jobs tab' do
- skip('unskip when jobs tab is implemented with ff `pipeline_tabs_vue`')
- expect(page.find('.js-builds-counter').text).to eq(pipeline.total_size.to_s)
+ expect(page.find('[data-testid="builds-counter"]').text).to eq(pipeline.total_size.to_s)
end
end
@@ -1130,10 +1116,6 @@ RSpec.describe 'Pipeline', :js do
let(:pipeline_failures_page) { failures_project_pipeline_path(project, pipeline) }
let!(:failed_build) { create(:ci_build, :failed, pipeline: pipeline) }
- before do
- stub_feature_flags(pipeline_tabs_vue: false)
- end
-
subject { visit pipeline_failures_page }
context 'with failed build' do
@@ -1160,42 +1142,11 @@ RSpec.describe 'Pipeline', :js do
expect(page).to have_content('There is an unknown failure, please try again')
end
- context 'when failed_jobs_tab_vue feature flag is disabled' do
- before do
- stub_feature_flags(failed_jobs_tab_vue: false)
- end
-
- context 'when user does not have permission to retry build' do
- it 'shows retry button for failed build' do
- subject
-
- page.within(find('.build-failures', match: :first)) do
- expect(page).not_to have_link('Retry')
- end
- end
- end
-
- context 'when user does have permission to retry build' do
- before do
- create(:protected_branch, :developers_can_merge,
- name: pipeline.ref, project: project)
- end
-
- it 'shows retry button for failed build' do
- subject
-
- page.within(find('.build-failures', match: :first)) do
- expect(page).to have_link('Retry')
- end
- end
- end
- end
-
context 'when user does not have permission to retry build' do
it 'shows retry button for failed build' do
subject
- page.within(find('#js-tab-failures', match: :first)) do
+ page.within(find('[data-testid="tab-failures"]', match: :first)) do
expect(page).not_to have_button('Retry')
end
end
@@ -1210,7 +1161,7 @@ RSpec.describe 'Pipeline', :js do
it 'shows retry button for failed build' do
subject
- page.within(find('#js-tab-failures', match: :first)) do
+ page.within(find('[data-testid="tab-failures"]', match: :first)) do
expect(page).to have_button('Retry')
end
end
@@ -1255,7 +1206,6 @@ RSpec.describe 'Pipeline', :js do
end
it 'does not show the failure tab' do
- skip('unskip when the failure tab has been implemented in ff `pipeline_tabs_vue`')
subject
expect(page).not_to have_content('Failed Jobs')
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index a18bf7c5caf..785edc69623 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -311,7 +311,6 @@ RSpec.describe 'Pipelines', :js do
end
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
visit_project_pipelines
end
diff --git a/spec/features/projects/releases/user_views_edit_release_spec.rb b/spec/features/projects/releases/user_views_edit_release_spec.rb
index f08f5529472..6551b254643 100644
--- a/spec/features/projects/releases/user_views_edit_release_spec.rb
+++ b/spec/features/projects/releases/user_views_edit_release_spec.rb
@@ -30,10 +30,12 @@ RSpec.describe 'User edits Release', :js do
it 'renders the breadcrumbs' do
within('.breadcrumbs') do
- expect(page).to have_content("#{project.creator.name} #{project.name} Edit Release")
+ expect(page).to have_content("#{project.creator.name} #{project.name} Releases #{release.name} Edit Release")
expect(page).to have_link(project.creator.name, href: user_path(project.creator))
expect(page).to have_link(project.name, href: project_path(project))
+ expect(page).to have_link(_('Releases'), href: project_releases_path(project))
+ expect(page).to have_link(release.name, href: project_release_path(project, release))
expect(page).to have_link('Edit Release', href: edit_project_release_path(project, release))
end
end
diff --git a/spec/features/projects/settings/access_tokens_spec.rb b/spec/features/projects/settings/access_tokens_spec.rb
index 122bf267021..88f9a50b093 100644
--- a/spec/features/projects/settings/access_tokens_spec.rb
+++ b/spec/features/projects/settings/access_tokens_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Project > Settings > Access Tokens', :js do
+ include Spec::Support::Helpers::ModalHelpers
+
let_it_be(:user) { create(:user) }
let_it_be(:bot_user) { create(:user, :project_bot) }
let_it_be(:group) { create(:group) }
@@ -14,7 +16,6 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do
end
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
end
@@ -24,6 +25,11 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do
create(:personal_access_token, user: bot_user)
end
+ def role_dropdown_options
+ role_dropdown = page.find_by_id('resource_access_token_access_level')
+ role_dropdown.all('option').map(&:text)
+ end
+
context 'when user is not a project maintainer' do
before do
project.add_developer(user)
@@ -33,37 +39,68 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do
end
describe 'token creation' do
- it_behaves_like 'resource access tokens creation', 'project'
+ context 'when user is a project owner' do
+ before do
+ project.add_owner(user)
+ end
- context 'when token creation is not allowed' do
- it_behaves_like 'resource access tokens creation disallowed', 'Project access token creation is disabled in this group. You can still use and manage existing tokens.'
+ it_behaves_like 'resource access tokens creation', 'project'
- context 'with a project in a personal namespace' do
- let(:personal_project) { create(:project) }
+ it 'shows Owner option' do
+ visit resource_settings_access_tokens_path
- before do
- personal_project.add_maintainer(user)
- end
+ expect(role_dropdown_options).to include('Owner')
+ end
+ end
- it 'shows access token creation form and text' do
- visit project_settings_access_tokens_path(personal_project)
+ context 'when user is a project maintainer' do
+ before_all do
+ project.add_maintainer(user)
+ end
+
+ it_behaves_like 'resource access tokens creation', 'project'
+
+ it 'does not show Owner option for a maintainer' do
+ visit resource_settings_access_tokens_path
- expect(page).to have_selector('#new_resource_access_token')
- expect(page).to have_text('Generate project access tokens scoped to this project for your applications that need access to the GitLab API.')
- end
+ expect(role_dropdown_options).not_to include('Owner')
end
end
end
- describe 'active tokens' do
- let!(:resource_access_token) { create_resource_access_token }
+ context 'when token creation is not allowed' do
+ it_behaves_like 'resource access tokens creation disallowed', 'Project access token creation is disabled in this group. You can still use and manage existing tokens.'
- it_behaves_like 'active resource access tokens'
+ context 'with a project in a personal namespace' do
+ let(:personal_project) { create(:project) }
+
+ before do
+ personal_project.add_maintainer(user)
+ end
+
+ it 'shows access token creation form and text' do
+ visit project_settings_access_tokens_path(personal_project)
+
+ expect(page).to have_selector('#js-new-access-token-form')
+ end
+ end
end
- describe 'inactive tokens' do
- let!(:resource_access_token) { create_resource_access_token }
+ describe 'viewing tokens' do
+ before_all do
+ project.add_maintainer(user)
+ end
+
+ describe 'active tokens' do
+ let!(:resource_access_token) { create_resource_access_token }
+
+ it_behaves_like 'active resource access tokens'
+ end
- it_behaves_like 'inactive resource access tokens', 'This project has no active access tokens.'
+ describe 'inactive tokens' do
+ let!(:resource_access_token) { create_resource_access_token }
+
+ it_behaves_like 'inactive resource access tokens', 'This project has no active access tokens.'
+ end
end
end
diff --git a/spec/features/projects/settings/branch_rules_settings_spec.rb b/spec/features/projects/settings/branch_rules_settings_spec.rb
new file mode 100644
index 00000000000..5cc35f108b5
--- /dev/null
+++ b/spec/features/projects/settings/branch_rules_settings_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Settings > Repository > Branch rules settings' do
+ let(:project) { create(:project_empty_repo) }
+ let(:user) { create(:user) }
+ let(:role) { :developer }
+
+ subject(:request) { visit project_settings_repository_branch_rules_path(project) }
+
+ before do
+ project.add_role(user, role)
+ sign_in(user)
+ end
+
+ context 'for developer' do
+ let(:role) { :developer }
+
+ it 'is not allowed to view' do
+ request
+
+ expect(page).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'for maintainer' do
+ let(:role) { :maintainer }
+
+ context 'Branch rules', :js do
+ it 'renders branch rules page' do
+ request
+
+ expect(page).to have_content('Branch rules')
+ end
+ end
+
+ context 'branch_rules feature flag disabled' do
+ it 'does not render branch rules content' do
+ stub_feature_flags(branch_rules: false)
+ request
+
+ expect(page).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/settings/packages_settings_spec.rb b/spec/features/projects/settings/packages_settings_spec.rb
index 057e6b635fe..1c2b0faa215 100644
--- a/spec/features/projects/settings/packages_settings_spec.rb
+++ b/spec/features/projects/settings/packages_settings_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe 'Projects > Settings > Packages', :js do
sign_in(user)
stub_config(packages: { enabled: packages_enabled })
+ stub_feature_flags(package_registry_access_level: package_registry_access_level)
visit edit_project_path(project)
end
@@ -18,14 +19,31 @@ RSpec.describe 'Projects > Settings > Packages', :js do
context 'Packages enabled in config' do
let(:packages_enabled) { true }
- it 'displays the packages toggle button' do
- expect(page).to have_selector('[data-testid="toggle-label"]', text: 'Packages')
- expect(page).to have_selector('input[name="project[packages_enabled]"] + button', visible: true)
+ context 'with feature flag disabled' do
+ let(:package_registry_access_level) { false }
+
+ it 'displays the packages toggle button' do
+ expect(page).to have_selector('[data-testid="toggle-label"]', text: 'Packages')
+ expect(page).to have_selector('input[name="project[packages_enabled]"] + button', visible: true)
+ end
+ end
+
+ context 'with feature flag enabled' do
+ let(:package_registry_access_level) { true }
+
+ it 'displays the packages access level setting' do
+ expect(page).to have_selector('[data-testid="package-registry-access-level"] > label', text: 'Package registry')
+ expect(page).to have_selector(
+ 'input[name="project[project_feature_attributes][package_registry_access_level]"]',
+ visible: false
+ )
+ end
end
end
context 'Packages disabled in config' do
let(:packages_enabled) { false }
+ let(:package_registry_access_level) { false }
it 'does not show up in UI' do
expect(page).not_to have_selector('[data-testid="toggle-label"]', text: 'Packages')
diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb
index 4e1b55d3d70..cfdd3d9224d 100644
--- a/spec/features/projects/settings/repository_settings_spec.rb
+++ b/spec/features/projects/settings/repository_settings_spec.rb
@@ -39,6 +39,22 @@ RSpec.describe 'Projects > Settings > Repository settings' do
end
end
+ context 'Branch rules', :js do
+ it 'renders branch rules settings' do
+ visit project_settings_repository_path(project)
+ expect(page).to have_content('Branch rules')
+ end
+
+ context 'branch_rules feature flag disabled', :js do
+ it 'does not render branch rules settings' do
+ stub_feature_flags(branch_rules: false)
+ visit project_settings_repository_path(project)
+
+ expect(page).not_to have_content('Branch rules')
+ end
+ end
+ end
+
context 'Deploy Keys', :js do
let_it_be(:private_deploy_key) { create(:deploy_key, title: 'private_deploy_key', public: false) }
let_it_be(:public_deploy_key) { create(:another_deploy_key, title: 'public_deploy_key', public: true) }
diff --git a/spec/features/projects/settings/user_searches_in_settings_spec.rb b/spec/features/projects/settings/user_searches_in_settings_spec.rb
index 44b5464a1b0..7ed96d01189 100644
--- a/spec/features/projects/settings/user_searches_in_settings_spec.rb
+++ b/spec/features/projects/settings/user_searches_in_settings_spec.rb
@@ -7,7 +7,6 @@ RSpec.describe 'User searches project settings', :js do
let_it_be(:project) { create(:project, :repository, namespace: user.namespace, pages_https_only: false) }
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
end
diff --git a/spec/features/promotion_spec.rb b/spec/features/promotion_spec.rb
index 8692930376f..903d6244a4c 100644
--- a/spec/features/promotion_spec.rb
+++ b/spec/features/promotion_spec.rb
@@ -27,7 +27,7 @@ RSpec.describe 'Promotions', :js do
visit edit_project_path(project)
within('#promote_service_desk') do
- find('.close').click
+ find('.js-close').click
end
wait_for_requests
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/user_replaces_files_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/user_replaces_files_spec.rb
deleted file mode 100644
index 5561cf15a66..00000000000
--- a/spec/features/refactor_blob_viewer_disabled/projects/files/user_replaces_files_spec.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'Projects > Files > User replaces files', :js do
- include DropzoneHelper
-
- let(:fork_message) do
- "You're not allowed to make changes to this project directly. "\
- "A fork of this project has been created that you can make changes in, so you can submit a merge request."
- end
-
- let(:project) { create(:project, :repository, name: 'Shop') }
- let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
- let(:project_tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
- let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) }
- let(:user) { create(:user) }
-
- before do
- stub_feature_flags(refactor_blob_viewer: false)
- sign_in(user)
- end
-
- context 'when an user has write access' do
- before do
- project.add_maintainer(user)
- visit(project_tree_path_root_ref)
- wait_for_requests
- end
-
- it 'replaces an existed file with a new one' do
- click_link('.gitignore')
-
- expect(page).to have_content('.gitignore')
-
- click_on('Replace')
- drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
-
- page.within('#modal-upload-blob') do
- fill_in(:commit_message, with: 'Replacement file commit message')
- end
-
- click_button('Replace file')
-
- expect(page).to have_content('Lorem ipsum dolor sit amet')
- expect(page).to have_content('Sed ut perspiciatis unde omnis')
- expect(page).to have_content('Replacement file commit message')
- end
- end
-
- context 'when an user does not have write access' do
- before do
- project2.add_reporter(user)
- visit(project2_tree_path_root_ref)
- wait_for_requests
- end
-
- it 'replaces an existed file with a new one in a forked project', :sidekiq_might_not_need_inline do
- click_link('.gitignore')
-
- expect(page).to have_content('.gitignore')
-
- click_on('Replace')
-
- expect(page).to have_link('Fork')
- expect(page).to have_button('Cancel')
-
- click_link('Fork')
-
- expect(page).to have_content(fork_message)
-
- click_on('Replace')
- drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
-
- page.within('#modal-upload-blob') do
- fill_in(:commit_message, with: 'Replacement file commit message')
- end
-
- click_button('Replace file')
-
- expect(page).to have_content('Replacement file commit message')
-
- fork = user.fork_of(project2.reload)
-
- expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
-
- click_link('Changes')
-
- expect(page).to have_content('Lorem ipsum dolor sit amet')
- expect(page).to have_content('Sed ut perspiciatis unde omnis')
- end
- end
-end
diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb
index 6bd31d7314c..8d55a7a64f4 100644
--- a/spec/features/snippets/notes_on_personal_snippets_spec.rb
+++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe 'Comments on personal snippets', :js do
include NoteInteractionHelpers
+ include Spec::Support::Helpers::ModalHelpers
let_it_be(:snippet) { create(:personal_snippet, :public) }
let_it_be(:other_note) { create(:note_on_personal_snippet) }
@@ -18,7 +19,6 @@ RSpec.describe 'Comments on personal snippets', :js do
end
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in user
visit snippet_path(snippet)
@@ -124,7 +124,7 @@ RSpec.describe 'Comments on personal snippets', :js do
page.within('.current-note-edit-form') do
fill_in 'note[note]', with: 'new content'
- find('.btn-success').click
+ find('.btn-confirm').click
end
page.within("#notes-list li#note_#{snippet_notes[0].id}") do
@@ -142,9 +142,11 @@ RSpec.describe 'Comments on personal snippets', :js do
open_more_actions_dropdown(snippet_notes[0])
page.within("#notes-list li#note_#{snippet_notes[0].id}") do
- accept_confirm { click_on 'Delete comment' }
+ click_on 'Delete comment'
end
+ accept_gl_confirm(button_text: 'Delete comment')
+
wait_for_requests
expect(page).not_to have_selector("#notes-list li#note_#{snippet_notes[0].id}")
diff --git a/spec/features/snippets/user_creates_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb
index c682ad06977..628468a2abe 100644
--- a/spec/features/snippets/user_creates_snippet_spec.rb
+++ b/spec/features/snippets/user_creates_snippet_spec.rb
@@ -16,7 +16,6 @@ RSpec.describe 'User creates snippet', :js do
let(:snippet_title_field) { 'snippet-title' }
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
visit new_snippet_path
diff --git a/spec/features/tags/developer_deletes_tag_spec.rb b/spec/features/tags/developer_deletes_tag_spec.rb
index 6b669695f7b..efd4b42c136 100644
--- a/spec/features/tags/developer_deletes_tag_spec.rb
+++ b/spec/features/tags/developer_deletes_tag_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe 'Developer deletes tag', :js do
before do
project.add_developer(user)
sign_in(user)
+ create(:protected_tag, project: project, name: 'v1.1.1')
visit project_tags_path(project)
end
@@ -22,6 +23,16 @@ RSpec.describe 'Developer deletes tag', :js do
expect(page).not_to have_content 'v1.1.0'
end
+
+ context 'protected tags' do
+ it 'can not delete protected tags' do
+ expect(page).to have_content 'v1.1.1'
+
+ container = page.find('.content .flex-row', text: 'v1.1.1')
+ expect(container).to have_button('Only a project maintainer or owner can delete a protected tag',
+ disabled: true)
+ end
+ end
end
context 'from a specific tag page' do
@@ -33,7 +44,7 @@ RSpec.describe 'Developer deletes tag', :js do
container = page.find('.nav-controls')
delete_tag container
- expect(page).to have_current_path("#{project_tags_path(project)}/", ignore_query: true)
+ expect(page).to have_current_path(project_tags_path(project), ignore_query: true)
expect(page).not_to have_content 'v1.0.0'
end
end
@@ -55,9 +66,9 @@ RSpec.describe 'Developer deletes tag', :js do
end
def delete_tag(container)
- container.find('.js-remove-tag').click
+ container.find('.js-delete-tag-button').click
- page.within('.modal') { click_button('Delete tag') }
+ page.within('.modal') { click_button('Yes, delete tag') }
wait_for_requests
end
end
diff --git a/spec/features/tags/maintainer_deletes_protected_tag_spec.rb b/spec/features/tags/maintainer_deletes_protected_tag_spec.rb
new file mode 100644
index 00000000000..0bf9645c2fb
--- /dev/null
+++ b/spec/features/tags/maintainer_deletes_protected_tag_spec.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Maintainer deletes protected tag', :js do
+ let(:user) { create(:user) }
+ let(:group) { create(:group) }
+ let(:project) { create(:project, :repository, namespace: group) }
+ let(:tag_name) { 'v1.1.1' }
+
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
+ create(:protected_tag, project: project, name: tag_name)
+ visit project_tags_path(project)
+ end
+
+ context 'from the tags list page' do
+ it 'deletes the tag' do
+ expect(page).to have_content "#{tag_name} protected"
+
+ page.find('.content .flex-row', text: tag_name).find('.js-delete-tag-button').click
+ assert_modal_content(tag_name)
+ confirm_delete_tag(tag_name)
+
+ expect(page).not_to have_content tag_name
+ end
+ end
+
+ context 'from a specific tag page' do
+ before do
+ click_on tag_name
+ end
+
+ it 'deletes the tag' do
+ expect(page).to have_current_path(project_tag_path(project, tag_name), ignore_query: true)
+
+ page.find('.js-delete-tag-button').click
+ assert_modal_content(tag_name)
+ confirm_delete_tag(tag_name)
+
+ expect(page).to have_current_path(project_tags_path(project), ignore_query: true)
+ expect(page).not_to have_content tag_name
+ end
+ end
+
+ def assert_modal_content(tag_name)
+ within '.modal' do
+ expect(page).to have_content("Please type the following to confirm: #{tag_name}")
+ expect(page).to have_field('delete_tag_input')
+ expect(page).to have_button('Yes, delete protected tag', disabled: true)
+ end
+ end
+
+ def confirm_delete_tag(tag_name)
+ within '.modal' do
+ fill_in('delete_tag_input', with: tag_name)
+ click_button('Yes, delete protected tag')
+ wait_for_requests
+ end
+ end
+end
diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb
index 7f5cf2359a3..eb497715df7 100644
--- a/spec/features/triggers_spec.rb
+++ b/spec/features/triggers_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Triggers', :js do
+ include Spec::Support::Helpers::ModalHelpers
+
let(:trigger_title) { 'trigger desc' }
let(:user) { create(:user) }
let(:user2) { create(:user) }
@@ -74,7 +76,6 @@ RSpec.describe 'Triggers', :js do
describe 'trigger "Revoke" workflow' do
before do
- stub_feature_flags(bootstrap_confirmation_modals: false)
create(:ci_trigger, owner: user2, project: @project, description: trigger_title)
visit project_settings_ci_cd_path(@project)
end
@@ -86,7 +87,7 @@ RSpec.describe 'Triggers', :js do
it 'revoke trigger' do
# See if "Revoke" on trigger works post trigger creation
- page.accept_confirm do
+ accept_gl_confirm(button_text: 'Revoke') do
find('[data-testid="trigger_revoke_button"]').send_keys(:return)
end
diff --git a/spec/features/user_sorts_things_spec.rb b/spec/features/user_sorts_things_spec.rb
index bcf3defe9c6..c6a1cfdc146 100644
--- a/spec/features/user_sorts_things_spec.rb
+++ b/spec/features/user_sorts_things_spec.rb
@@ -16,8 +16,6 @@ RSpec.describe "User sorts things", :js do
let_it_be(:merge_request) { create(:merge_request, target_project: project, source_project: project, author: current_user) }
before do
- stub_feature_flags(vue_issues_list: true)
-
project.add_developer(current_user)
sign_in(current_user)
end
diff --git a/spec/features/users/signup_spec.rb b/spec/features/users/signup_spec.rb
index 3eae4955167..30441dac7b6 100644
--- a/spec/features/users/signup_spec.rb
+++ b/spec/features/users/signup_spec.rb
@@ -341,6 +341,7 @@ RSpec.describe 'Signup' do
end
it 'redirects to step 2 of the signup process, sets the role and redirects back' do
+ stub_feature_flags(about_your_company_registration_flow: false)
visit new_user_registration_path
fill_in_signup_form
diff --git a/spec/features/users/zuora_csp_spec.rb b/spec/features/users/zuora_csp_spec.rb
new file mode 100644
index 00000000000..f3fd27d6495
--- /dev/null
+++ b/spec/features/users/zuora_csp_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Zuora content security policy' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ it 'has proper Content Security Policy headers' do
+ visit pipeline_path(pipeline)
+
+ expect(response_headers['Content-Security-Policy']).to include('https://*.zuora.com')
+ end
+end