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-03-18 23:02:30 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-03-18 23:02:30 +0300
commit41fe97390ceddf945f3d967b8fdb3de4c66b7dea (patch)
tree9c8d89a8624828992f06d892cd2f43818ff5dcc8 /spec/features
parent0804d2dc31052fb45a1efecedc8e06ce9bc32862 (diff)
Add latest changes from gitlab-org/gitlab@14-9-stable-eev14.9.0-rc42
Diffstat (limited to 'spec/features')
-rw-r--r--spec/features/admin/admin_appearance_spec.rb2
-rw-r--r--spec/features/admin/admin_broadcast_messages_spec.rb27
-rw-r--r--spec/features/admin/admin_deploy_keys_spec.rb6
-rw-r--r--spec/features/admin/admin_groups_spec.rb2
-rw-r--r--spec/features/admin/admin_hook_logs_spec.rb2
-rw-r--r--spec/features/admin/admin_hooks_spec.rb10
-rw-r--r--spec/features/admin/admin_mode/login_spec.rb14
-rw-r--r--spec/features/admin/admin_mode/logout_spec.rb4
-rw-r--r--spec/features/admin/admin_projects_spec.rb34
-rw-r--r--spec/features/admin/admin_runners_spec.rb10
-rw-r--r--spec/features/admin/admin_sees_background_migrations_spec.rb8
-rw-r--r--spec/features/admin/admin_settings_spec.rb67
-rw-r--r--spec/features/admin/admin_users_spec.rb2
-rw-r--r--spec/features/admin/admin_uses_repository_checks_spec.rb2
-rw-r--r--spec/features/admin/clusters/eks_spec.rb6
-rw-r--r--spec/features/admin/users/user_spec.rb10
-rw-r--r--spec/features/admin/users/users_spec.rb12
-rw-r--r--spec/features/boards/board_filters_spec.rb2
-rw-r--r--spec/features/boards/boards_spec.rb90
-rw-r--r--spec/features/callouts/registration_enabled_spec.rb31
-rw-r--r--spec/features/clusters/cluster_detail_page_spec.rb14
-rw-r--r--spec/features/commits_spec.rb56
-rw-r--r--spec/features/dashboard/group_spec.rb2
-rw-r--r--spec/features/dashboard/issuables_counter_spec.rb80
-rw-r--r--spec/features/dashboard/milestones_spec.rb8
-rw-r--r--spec/features/dashboard/projects_spec.rb6
-rw-r--r--spec/features/dashboard/todos/todos_filtering_spec.rb2
-rw-r--r--spec/features/dashboard/todos/todos_spec.rb4
-rw-r--r--spec/features/dashboard/user_filters_projects_spec.rb10
-rw-r--r--spec/features/expand_collapse_diffs_spec.rb2
-rw-r--r--spec/features/explore/topics_spec.rb4
-rw-r--r--spec/features/file_uploads/user_avatar_spec.rb2
-rw-r--r--spec/features/global_search_spec.rb4
-rw-r--r--spec/features/groups/clusters/eks_spec.rb6
-rw-r--r--spec/features/groups/clusters/user_spec.rb12
-rw-r--r--spec/features/groups/container_registry_spec.rb2
-rw-r--r--spec/features/groups/group_settings_spec.rb50
-rw-r--r--spec/features/groups/issues_spec.rb16
-rw-r--r--spec/features/groups/labels/create_spec.rb2
-rw-r--r--spec/features/groups/labels/edit_spec.rb2
-rw-r--r--spec/features/groups/labels/sort_labels_spec.rb4
-rw-r--r--spec/features/groups/members/leave_group_spec.rb8
-rw-r--r--spec/features/groups/members/manage_groups_spec.rb97
-rw-r--r--spec/features/groups/members/manage_members_spec.rb84
-rw-r--r--spec/features/groups/navbar_spec.rb25
-rw-r--r--spec/features/groups/settings/ci_cd_spec.rb18
-rw-r--r--spec/features/groups/settings/repository_spec.rb6
-rw-r--r--spec/features/groups/settings/user_searches_in_settings_spec.rb2
-rw-r--r--spec/features/groups_spec.rb77
-rw-r--r--spec/features/incidents/incident_details_spec.rb41
-rw-r--r--spec/features/incidents/incidents_list_spec.rb23
-rw-r--r--spec/features/incidents/user_views_incident_spec.rb8
-rw-r--r--spec/features/invites_spec.rb30
-rw-r--r--spec/features/issues/filtered_search/dropdown_assignee_spec.rb73
-rw-r--r--spec/features/issues/filtered_search/filter_issues_spec.rb10
-rw-r--r--spec/features/issues/form_spec.rb115
-rw-r--r--spec/features/issues/gfm_autocomplete_spec.rb22
-rw-r--r--spec/features/issues/incident_issue_spec.rb2
-rw-r--r--spec/features/issues/issue_detail_spec.rb4
-rw-r--r--spec/features/issues/issue_header_spec.rb8
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb7
-rw-r--r--spec/features/issues/move_spec.rb2
-rw-r--r--spec/features/issues/spam_akismet_issue_creation_spec.rb178
-rw-r--r--spec/features/issues/spam_issues_spec.rb188
-rw-r--r--spec/features/issues/user_creates_branch_and_merge_request_spec.rb4
-rw-r--r--spec/features/issues/user_creates_issue_spec.rb4
-rw-r--r--spec/features/issues/user_sorts_issues_spec.rb8
-rw-r--r--spec/features/issues/user_views_issue_spec.rb2
-rw-r--r--spec/features/jira_connect/subscriptions_spec.rb11
-rw-r--r--spec/features/labels_hierarchy_spec.rb58
-rw-r--r--spec/features/markdown/copy_as_gfm_spec.rb9
-rw-r--r--spec/features/markdown/keyboard_shortcuts_spec.rb8
-rw-r--r--spec/features/markdown/sandboxed_mermaid_spec.rb2
-rw-r--r--spec/features/merge_request/user_edits_assignees_sidebar_spec.rb174
-rw-r--r--spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb8
-rw-r--r--spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb1
-rw-r--r--spec/features/merge_request/user_sees_diff_spec.rb6
-rw-r--r--spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb18
-rw-r--r--spec/features/merge_request/user_sees_merge_widget_spec.rb5
-rw-r--r--spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_pipelines_spec.rb5
-rw-r--r--spec/features/merge_request/user_sees_suggest_pipeline_spec.rb3
-rw-r--r--spec/features/merge_requests/user_lists_merge_requests_spec.rb2
-rw-r--r--spec/features/milestones/user_views_milestones_spec.rb4
-rw-r--r--spec/features/oauth_login_spec.rb16
-rw-r--r--spec/features/password_reset_spec.rb8
-rw-r--r--spec/features/profiles/account_spec.rb8
-rw-r--r--spec/features/profiles/chat_names_spec.rb4
-rw-r--r--spec/features/profiles/password_spec.rb12
-rw-r--r--spec/features/profiles/user_visits_profile_preferences_page_spec.rb4
-rw-r--r--spec/features/profiles/user_visits_profile_spec.rb51
-rw-r--r--spec/features/projects/artifacts/file_spec.rb2
-rw-r--r--spec/features/projects/artifacts/raw_spec.rb2
-rw-r--r--spec/features/projects/artifacts/user_browses_artifacts_spec.rb2
-rw-r--r--spec/features/projects/blobs/blob_show_spec.rb618
-rw-r--r--spec/features/projects/blobs/edit_spec.rb2
-rw-r--r--spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb6
-rw-r--r--spec/features/projects/ci/editor_spec.rb10
-rw-r--r--spec/features/projects/ci/secure_files_spec.rb19
-rw-r--r--spec/features/projects/cluster_agents_spec.rb2
-rw-r--r--spec/features/projects/clusters/eks_spec.rb8
-rw-r--r--spec/features/projects/clusters/gcp_spec.rb26
-rw-r--r--spec/features/projects/clusters/user_spec.rb12
-rw-r--r--spec/features/projects/clusters_spec.rb36
-rw-r--r--spec/features/projects/commits/multi_view_diff_spec.rb85
-rw-r--r--spec/features/projects/container_registry_spec.rb2
-rw-r--r--spec/features/projects/environments/environment_metrics_spec.rb3
-rw-r--r--spec/features/projects/environments/environments_spec.rb86
-rw-r--r--spec/features/projects/files/project_owner_creates_license_file_spec.rb20
-rw-r--r--spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb8
-rw-r--r--spec/features/projects/files/user_browses_files_spec.rb18
-rw-r--r--spec/features/projects/files/user_browses_lfs_files_spec.rb19
-rw-r--r--spec/features/projects/files/user_creates_directory_spec.rb6
-rw-r--r--spec/features/projects/files/user_creates_files_spec.rb10
-rw-r--r--spec/features/projects/files/user_deletes_files_spec.rb5
-rw-r--r--spec/features/projects/files/user_edits_files_spec.rb119
-rw-r--r--spec/features/projects/files/user_replaces_files_spec.rb11
-rw-r--r--spec/features/projects/fork_spec.rb195
-rw-r--r--spec/features/projects/integrations/user_activates_issue_tracker_spec.rb6
-rw-r--r--spec/features/projects/integrations/user_activates_jetbrains_teamcity_ci_spec.rb2
-rw-r--r--spec/features/projects/integrations/user_activates_jira_spec.rb6
-rw-r--r--spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb4
-rw-r--r--spec/features/projects/jobs/user_browses_job_spec.rb7
-rw-r--r--spec/features/projects/jobs/user_browses_jobs_spec.rb2
-rw-r--r--spec/features/projects/jobs/user_triggers_manual_job_with_variables_spec.rb2
-rw-r--r--spec/features/projects/jobs_spec.rb18
-rw-r--r--spec/features/projects/labels/sort_labels_spec.rb4
-rw-r--r--spec/features/projects/members/group_members_spec.rb1
-rw-r--r--spec/features/projects/members/invite_group_spec.rb105
-rw-r--r--spec/features/projects/members/member_leaves_project_spec.rb4
-rw-r--r--spec/features/projects/members/user_requests_access_spec.rb6
-rw-r--r--spec/features/projects/navbar_spec.rb13
-rw-r--r--spec/features/projects/new_project_spec.rb72
-rw-r--r--spec/features/projects/pages/user_adds_domain_spec.rb2
-rw-r--r--spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb4
-rw-r--r--spec/features/projects/pipeline_schedules_spec.rb12
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb112
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb130
-rw-r--r--spec/features/projects/releases/user_views_edit_release_spec.rb2
-rw-r--r--spec/features/projects/remote_mirror_spec.rb2
-rw-r--r--spec/features/projects/settings/registry_settings_spec.rb39
-rw-r--r--spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb4
-rw-r--r--spec/features/projects/settings/user_manages_project_members_spec.rb23
-rw-r--r--spec/features/projects/settings/user_renames_a_project_spec.rb6
-rw-r--r--spec/features/projects/settings/user_transfers_a_project_spec.rb6
-rw-r--r--spec/features/projects/settings/webhooks_settings_spec.rb4
-rw-r--r--spec/features/projects/show/redirects_spec.rb8
-rw-r--r--spec/features/projects/show/user_interacts_with_stars_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_git_instructions_spec.rb2
-rw-r--r--spec/features/projects/tags/user_views_tags_spec.rb2
-rw-r--r--spec/features/projects/tracings_spec.rb11
-rw-r--r--spec/features/projects/user_creates_project_spec.rb6
-rw-r--r--spec/features/projects/wikis_spec.rb2
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/balsamiq_spec.rb18
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_line_permalink_updater_spec.rb103
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_show_spec.rb1154
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/edit_spec.rb213
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/shortcuts_blob_spec.rb45
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/user_creates_new_blob_in_new_project_spec.rb63
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb80
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/user_views_pipeline_editor_button_spec.rb46
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/editing_a_file_spec.rb34
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/find_file_keyboard_spec.rb42
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/project_owner_creates_license_file_spec.rb72
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_files_spec.rb377
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_lfs_files_spec.rb86
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/user_deletes_files_spec.rb74
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/user_edits_files_spec.rb226
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/user_replaces_files_spec.rb93
-rw-r--r--spec/features/search/user_searches_for_code_spec.rb125
-rw-r--r--spec/features/search/user_searches_for_issues_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_merge_requests_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_milestones_spec.rb4
-rw-r--r--spec/features/search/user_searches_for_wiki_pages_spec.rb2
-rw-r--r--spec/features/static_site_editor_spec.rb11
-rw-r--r--spec/features/tags/developer_creates_tag_spec.rb8
-rw-r--r--spec/features/tags/developer_deletes_tag_spec.rb6
-rw-r--r--spec/features/tags/developer_updates_tag_spec.rb8
-rw-r--r--spec/features/tags/developer_views_tags_spec.rb20
-rw-r--r--spec/features/triggers_spec.rb2
-rw-r--r--spec/features/unsubscribe_links_spec.rb8
-rw-r--r--spec/features/users/active_sessions_spec.rb6
-rw-r--r--spec/features/users/login_spec.rb71
-rw-r--r--spec/features/users/logout_spec.rb4
-rw-r--r--spec/features/users/show_spec.rb2
-rw-r--r--spec/features/users/signup_spec.rb16
-rw-r--r--spec/features/users/terms_spec.rb10
187 files changed, 4571 insertions, 2519 deletions
diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb
index 0785c736cfb..8bf8ef56353 100644
--- a/spec/features/admin/admin_appearance_spec.rb
+++ b/spec/features/admin/admin_appearance_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe 'Admin Appearance' do
fill_in 'appearance_profile_image_guidelines', with: 'Custom profile image guidelines'
click_button 'Update appearance settings'
- expect(current_path).to eq admin_application_settings_appearances_path
+ expect(page).to have_current_path admin_application_settings_appearances_path, ignore_query: true
expect(page).to have_content 'Appearance'
expect(page).to have_field('appearance_title', with: 'MyCompany')
diff --git a/spec/features/admin/admin_broadcast_messages_spec.rb b/spec/features/admin/admin_broadcast_messages_spec.rb
index 476dd4469bc..e40f4c4678c 100644
--- a/spec/features/admin/admin_broadcast_messages_spec.rb
+++ b/spec/features/admin/admin_broadcast_messages_spec.rb
@@ -7,7 +7,12 @@ RSpec.describe 'Admin Broadcast Messages' do
admin = create(:admin)
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
- create(:broadcast_message, :expired, message: 'Migration to new server')
+ create(
+ :broadcast_message,
+ :expired,
+ message: 'Migration to new server',
+ target_access_levels: [Gitlab::Access::DEVELOPER]
+ )
visit admin_broadcast_messages_path
end
@@ -21,10 +26,13 @@ RSpec.describe 'Admin Broadcast Messages' do
fill_in 'broadcast_message_target_path', with: '*/user_onboarded'
fill_in 'broadcast_message_font', with: '#b94a48'
select Date.today.next_year.year, from: 'broadcast_message_ends_at_1i'
+ check 'Guest'
+ check 'Owner'
click_button 'Add broadcast message'
- expect(current_path).to eq admin_broadcast_messages_path
+ expect(page).to have_current_path admin_broadcast_messages_path, ignore_query: true
expect(page).to have_content 'Application update from 4:00 CST to 5:00 CST'
+ expect(page).to have_content 'Guest, Owner'
expect(page).to have_content '*/user_onboarded'
expect(page).to have_selector 'strong', text: '4:00 CST to 5:00 CST'
expect(page).to have_selector %(div[style="background-color: #f2dede; color: #b94a48"])
@@ -35,10 +43,14 @@ RSpec.describe 'Admin Broadcast Messages' do
fill_in 'broadcast_message_target_path', with: '*/user_onboarded'
select 'Notification', from: 'broadcast_message_broadcast_type'
select Date.today.next_year.year, from: 'broadcast_message_ends_at_1i'
+ check 'Reporter'
+ check 'Developer'
+ check 'Maintainer'
click_button 'Add broadcast message'
- expect(current_path).to eq admin_broadcast_messages_path
+ expect(page).to have_current_path admin_broadcast_messages_path, ignore_query: true
expect(page).to have_content 'Application update from 4:00 CST to 5:00 CST'
+ expect(page).to have_content 'Reporter, Developer, Maintainer'
expect(page).to have_content '*/user_onboarded'
expect(page).to have_content 'Notification'
expect(page).to have_selector 'strong', text: '4:00 CST to 5:00 CST'
@@ -47,16 +59,21 @@ RSpec.describe 'Admin Broadcast Messages' do
it 'edit an existing broadcast message' do
click_link 'Edit'
fill_in 'broadcast_message_message', with: 'Application update RIGHT NOW'
+ check 'Reporter'
click_button 'Update broadcast message'
- expect(current_path).to eq admin_broadcast_messages_path
+ expect(page).to have_current_path admin_broadcast_messages_path, ignore_query: true
expect(page).to have_content 'Application update RIGHT NOW'
+
+ page.within('.table-responsive') do
+ expect(page).to have_content 'Reporter, Developer'
+ end
end
it 'remove an existing broadcast message' do
click_link 'Remove'
- expect(current_path).to eq admin_broadcast_messages_path
+ expect(page).to have_current_path admin_broadcast_messages_path, ignore_query: true
expect(page).not_to have_content 'Migration to new server'
end
diff --git a/spec/features/admin/admin_deploy_keys_spec.rb b/spec/features/admin/admin_deploy_keys_spec.rb
index 88b8fcd8d5e..56b8c7fce14 100644
--- a/spec/features/admin/admin_deploy_keys_spec.rb
+++ b/spec/features/admin/admin_deploy_keys_spec.rb
@@ -47,7 +47,7 @@ RSpec.describe 'admin deploy keys', :js do
fill_in 'deploy_key_key', with: new_ssh_key
click_button 'Create'
- expect(current_path).to eq admin_deploy_keys_path
+ expect(page).to have_current_path admin_deploy_keys_path, ignore_query: true
page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
expect(page).to have_content('laptop')
@@ -67,7 +67,7 @@ RSpec.describe 'admin deploy keys', :js do
fill_in 'deploy_key_title', with: 'new-title'
click_button 'Save changes'
- expect(current_path).to eq admin_deploy_keys_path
+ expect(page).to have_current_path admin_deploy_keys_path, ignore_query: true
page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
expect(page).to have_content('new-title')
@@ -87,7 +87,7 @@ RSpec.describe 'admin deploy keys', :js do
end
end
- expect(current_path).to eq admin_deploy_keys_path
+ expect(page).to have_current_path admin_deploy_keys_path, ignore_query: true
page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
expect(page).not_to have_content(deploy_key.title)
end
diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb
index a0a41061d64..3b3289a8487 100644
--- a/spec/features/admin/admin_groups_spec.rb
+++ b/spec/features/admin/admin_groups_spec.rb
@@ -58,7 +58,7 @@ RSpec.describe 'Admin Groups' do
fill_in 'group_admin_note_attributes_note', with: group_admin_note
click_button "Create group"
- expect(current_path).to eq admin_group_path(Group.find_by(path: path_component))
+ 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
diff --git a/spec/features/admin/admin_hook_logs_spec.rb b/spec/features/admin/admin_hook_logs_spec.rb
index 837cab49bd4..fd51fd71fea 100644
--- a/spec/features/admin/admin_hook_logs_spec.rb
+++ b/spec/features/admin/admin_hook_logs_spec.rb
@@ -39,6 +39,6 @@ RSpec.describe 'Admin::HookLogs' do
click_link 'View details'
click_link 'Resend Request'
- expect(current_path).to eq(edit_admin_hook_path(system_hook))
+ expect(page).to have_current_path(edit_admin_hook_path(system_hook), ignore_query: true)
end
end
diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb
index 32e4d18227e..388ab02d8e8 100644
--- a/spec/features/admin/admin_hooks_spec.rb
+++ b/spec/features/admin/admin_hooks_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe 'Admin::Hooks' do
click_on 'System Hooks', match: :first
end
- expect(current_path).to eq(admin_hooks_path)
+ expect(page).to have_current_path(admin_hooks_path, ignore_query: true)
end
it 'has hooks list' do
@@ -49,7 +49,7 @@ RSpec.describe 'Admin::Hooks' do
expect { click_button 'Add system hook' }.to change(SystemHook, :count).by(1)
expect(page).to have_content 'SSL Verification: enabled'
- expect(current_path).to eq(admin_hooks_path)
+ expect(page).to have_current_path(admin_hooks_path, ignore_query: true)
expect(page).to have_content(url)
end
end
@@ -70,7 +70,7 @@ RSpec.describe 'Admin::Hooks' do
click_button 'Save changes'
expect(page).to have_content 'SSL Verification: enabled'
- expect(current_path).to eq(admin_hooks_path)
+ expect(page).to have_current_path(admin_hooks_path, ignore_query: true)
expect(page).to have_content(new_url)
end
end
@@ -111,7 +111,7 @@ RSpec.describe 'Admin::Hooks' do
click_link 'Push events'
end
- it { expect(current_path).to eq(admin_hooks_path) }
+ it { expect(page).to have_current_path(admin_hooks_path, ignore_query: true) }
end
context 'Merge request hook' do
@@ -126,7 +126,7 @@ RSpec.describe 'Admin::Hooks' do
check 'Merge request events'
expect { click_button 'Add system hook' }.to change(SystemHook, :count).by(1)
- expect(current_path).to eq(admin_hooks_path)
+ expect(page).to have_current_path(admin_hooks_path, ignore_query: true)
expect(page).to have_content(url)
end
end
diff --git a/spec/features/admin/admin_mode/login_spec.rb b/spec/features/admin/admin_mode/login_spec.rb
index c8ee6c14499..659f66a67d2 100644
--- a/spec/features/admin/admin_mode/login_spec.rb
+++ b/spec/features/admin/admin_mode/login_spec.rb
@@ -30,7 +30,7 @@ RSpec.describe 'Admin Mode Login' do
enter_code(repeated_otp)
- expect(current_path).to eq admin_session_path
+ expect(page).to have_current_path admin_session_path, ignore_query: true
expect(page).to have_content('Invalid two-factor code')
end
@@ -51,7 +51,7 @@ RSpec.describe 'Admin Mode Login' do
travel_to(30.seconds.from_now) do
enter_code(user.current_otp)
- expect(current_path).to eq admin_root_path
+ expect(page).to have_current_path admin_root_path, ignore_query: true
expect(page).to have_content('Admin mode enabled')
end
end
@@ -74,7 +74,7 @@ RSpec.describe 'Admin Mode Login' do
enter_code(user.current_otp)
- expect(current_path).to eq admin_root_path
+ expect(page).to have_current_path admin_root_path, ignore_query: true
expect(page).to have_content('Admin mode enabled')
end
end
@@ -93,7 +93,7 @@ RSpec.describe 'Admin Mode Login' do
it 'allows login' do
enter_code(codes.sample)
- expect(current_path).to eq admin_root_path
+ expect(page).to have_current_path admin_root_path, ignore_query: true
expect(page).to have_content('Admin mode enabled')
end
@@ -146,7 +146,7 @@ RSpec.describe 'Admin Mode Login' do
enable_admin_mode_using_saml!
expect(page).not_to have_content('Two-Factor Authentication')
- expect(current_path).to eq admin_root_path
+ expect(page).to have_current_path admin_root_path, ignore_query: true
expect(page).to have_content('Admin mode enabled')
end
end
@@ -166,7 +166,7 @@ RSpec.describe 'Admin Mode Login' do
travel_to(30.seconds.from_now) do
enter_code(user.current_otp)
- expect(current_path).to eq admin_root_path
+ expect(page).to have_current_path admin_root_path, ignore_query: true
expect(page).to have_content('Admin mode enabled')
end
end
@@ -218,7 +218,7 @@ RSpec.describe 'Admin Mode Login' do
travel_to(30.seconds.from_now) do
enter_code(user.current_otp)
- expect(current_path).to eq admin_root_path
+ expect(page).to have_current_path admin_root_path, ignore_query: true
expect(page).to have_content('Admin mode enabled')
end
end
diff --git a/spec/features/admin/admin_mode/logout_spec.rb b/spec/features/admin/admin_mode/logout_spec.rb
index f2f6e26fbee..3ca66ef0d6a 100644
--- a/spec/features/admin/admin_mode/logout_spec.rb
+++ b/spec/features/admin/admin_mode/logout_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe 'Admin Mode Logout', :js do
it 'disable removes admin mode and redirects to root page' do
gitlab_disable_admin_mode
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
open_top_nav
@@ -43,7 +43,7 @@ RSpec.describe 'Admin Mode Logout', :js do
it 'disable removes admin mode and redirects to root page' do
gitlab_disable_admin_mode
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
open_top_nav
diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb
index 8938bab60d7..b0737377de0 100644
--- a/spec/features/admin/admin_projects_spec.rb
+++ b/spec/features/admin/admin_projects_spec.rb
@@ -5,7 +5,6 @@ require 'spec_helper'
RSpec.describe "Admin::Projects" do
include Spec::Support::Helpers::Features::MembersHelpers
include Spec::Support::Helpers::Features::InviteMembersModalHelper
- include Select2Helper
include Spec::Support::Helpers::ModalHelpers
let(:user) { create :user }
@@ -26,7 +25,7 @@ RSpec.describe "Admin::Projects" do
end
it "is ok" do
- expect(current_path).to eq(admin_projects_path)
+ expect(page).to have_current_path(admin_projects_path, ignore_query: true)
end
it 'renders projects list without archived project' do
@@ -63,7 +62,7 @@ RSpec.describe "Admin::Projects" do
end
it "has project info" do
- expect(current_path).to eq admin_project_path(project)
+ expect(page).to have_current_path admin_project_path(project), ignore_query: true
expect(page).to have_content(project.path)
expect(page).to have_content(project.name)
expect(page).to have_content(project.full_name)
@@ -117,18 +116,6 @@ RSpec.describe "Admin::Projects" do
expect(find_member_row(current_user)).to have_content('Developer')
end
-
- context 'with the invite_members_group_modal feature flag disabled' do
- it 'adds admin to the project as developer' do
- stub_feature_flags(invite_members_group_modal: false)
-
- visit project_project_members_path(project)
-
- add_member_using_form(current_user.id, role: 'Developer')
-
- expect(find_member_row(current_user)).to have_content('Developer')
- end
- end
end
describe 'admin removes themselves from the project', :js do
@@ -150,22 +137,7 @@ RSpec.describe "Admin::Projects" do
click_button('Leave')
end
- expect(current_path).to match dashboard_projects_path
- end
- end
-
- # temporary method for the form until the :invite_members_group_modal feature flag is
- # enabled: https://gitlab.com/gitlab-org/gitlab/-/issues/247208
- def add_member_using_form(id, role: 'Developer')
- page.within '.invite-users-form' do
- select2(id, from: '#user_ids', multiple: true)
-
- fill_in 'expires_at', with: 5.days.from_now.to_date
- find_field('expires_at').native.send_keys :enter
-
- select(role, from: "access_level")
-
- click_on 'Invite'
+ expect(page).to have_current_path(dashboard_projects_path, ignore_query: true, url: false)
end
end
end
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index 25ff4022454..3f0c7e64a1f 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -11,6 +11,8 @@ RSpec.describe "Admin Runners" do
admin = create(:admin)
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
+
+ wait_for_requests
end
describe "Runners page", :js do
@@ -21,7 +23,7 @@ RSpec.describe "Admin Runners" do
context "when there are runners" do
it 'has all necessary texts' do
- create(:ci_runner, :instance, created_at: 1.year.ago, contacted_at: Time.now)
+ create(:ci_runner, :instance, created_at: 1.year.ago, contacted_at: Time.zone.now)
create(:ci_runner, :instance, created_at: 1.year.ago, contacted_at: 1.week.ago)
create(:ci_runner, :instance, created_at: 1.year.ago, contacted_at: 1.year.ago)
@@ -156,9 +158,9 @@ RSpec.describe "Admin Runners" do
let!(:never_contacted) { create(:ci_runner, :instance, description: 'runner-never-contacted', contacted_at: nil) }
before do
- create(:ci_runner, :instance, description: 'runner-1', contacted_at: Time.now)
- create(:ci_runner, :instance, description: 'runner-2', contacted_at: Time.now)
- create(:ci_runner, :instance, description: 'runner-paused', active: false, contacted_at: Time.now)
+ create(:ci_runner, :instance, description: 'runner-1', contacted_at: Time.zone.now)
+ create(:ci_runner, :instance, description: 'runner-2', contacted_at: Time.zone.now)
+ create(:ci_runner, :instance, description: 'runner-paused', active: false, contacted_at: Time.zone.now)
visit admin_runners_path
end
diff --git a/spec/features/admin/admin_sees_background_migrations_spec.rb b/spec/features/admin/admin_sees_background_migrations_spec.rb
index a3d0c7bdd4d..d05a09a79ef 100644
--- a/spec/features/admin/admin_sees_background_migrations_spec.rb
+++ b/spec/features/admin/admin_sees_background_migrations_spec.rb
@@ -56,7 +56,13 @@ RSpec.describe "Admin > Admin sees background migrations" do
context 'when there are failed migrations' do
before do
allow_next_instance_of(Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchingStrategy) do |batch_class|
- allow(batch_class).to receive(:next_batch).with(anything, anything, batch_min_value: 6, batch_size: 5).and_return([6, 10])
+ allow(batch_class).to receive(:next_batch).with(
+ anything,
+ anything,
+ batch_min_value: 6,
+ batch_size: 5,
+ job_arguments: failed_migration.job_arguments
+ ).and_return([6, 10])
end
end
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index ca452264c02..df93bd773a6 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -373,7 +373,8 @@ RSpec.describe 'Admin updates settings' do
{
container_registry_delete_tags_service_timeout: 'Container Registry delete tags service execution timeout',
container_registry_expiration_policies_worker_capacity: 'Cleanup policy maximum workers running concurrently',
- container_registry_cleanup_tags_service_max_list_size: 'Cleanup policy maximum number of tags to be deleted'
+ container_registry_cleanup_tags_service_max_list_size: 'Cleanup policy maximum number of tags to be deleted',
+ container_registry_expiration_policies_caching: 'Enable container expiration caching'
}
end
@@ -393,26 +394,16 @@ RSpec.describe 'Admin updates settings' do
%i[container_registry_delete_tags_service_timeout container_registry_expiration_policies_worker_capacity container_registry_cleanup_tags_service_max_list_size].each do |setting|
context "for container registry setting #{setting}" do
- context 'with feature flag enabled' do
- context 'with client supporting tag delete' do
- it 'changes the setting' do
- visit ci_cd_admin_application_settings_path
-
- page.within('.as-registry') do
- fill_in "application_setting_#{setting}", with: 400
- click_button 'Save changes'
- end
-
- expect(current_settings.public_send(setting)).to eq(400)
- expect(page).to have_content "Application settings saved successfully"
- end
- end
-
- context 'with client not supporting tag delete' do
- let(:client_support) { false }
+ it 'changes the setting' do
+ visit ci_cd_admin_application_settings_path
- it_behaves_like 'not having container registry setting', setting
+ page.within('.as-registry') do
+ fill_in "application_setting_#{setting}", with: 400
+ click_button 'Save changes'
end
+
+ expect(current_settings.public_send(setting)).to eq(400)
+ expect(page).to have_content "Application settings saved successfully"
end
context 'with feature flag disabled' do
@@ -422,6 +413,28 @@ RSpec.describe 'Admin updates settings' do
end
end
end
+
+ context 'for container registry setting container_registry_expiration_policies_caching' do
+ it 'updates container_registry_expiration_policies_caching' do
+ old_value = current_settings.container_registry_expiration_policies_caching
+
+ visit ci_cd_admin_application_settings_path
+
+ page.within('.as-registry') do
+ find('#application_setting_container_registry_expiration_policies_caching.form-check-input').click
+ click_button 'Save changes'
+ end
+
+ expect(current_settings.container_registry_expiration_policies_caching).to eq(!old_value)
+ expect(page).to have_content "Application settings saved successfully"
+ end
+
+ context 'with feature flag disabled' do
+ let(:feature_flag_enabled) { false }
+
+ it_behaves_like 'not having container registry setting', :container_registry_expiration_policies_caching
+ end
+ end
end
end
@@ -694,6 +707,20 @@ RSpec.describe 'Admin updates settings' do
include_examples 'regular throttle rate limit settings'
end
+
+ it 'changes search rate limits' do
+ visit network_admin_application_settings_path
+
+ page.within('.as-search-limits') do
+ fill_in 'Maximum number of requests per minute for an authenticated user', with: 98
+ fill_in 'Maximum number of requests per minute for an unauthenticated IP address', with: 76
+ click_button 'Save changes'
+ end
+
+ expect(page).to have_content "Application settings saved successfully"
+ expect(current_settings.search_rate_limit).to eq(98)
+ expect(current_settings.search_rate_limit_unauthenticated).to eq(76)
+ end
end
context 'Preferences page' do
@@ -838,7 +865,7 @@ RSpec.describe 'Admin updates settings' do
end
it 'loads admin settings page without redirect for reauthentication' do
- expect(current_path).to eq general_admin_application_settings_path
+ expect(page).to have_current_path general_admin_application_settings_path, ignore_query: true
end
end
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index 95e3f5c70e5..f4b7fa45e4f 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -54,7 +54,7 @@ RSpec.describe "Admin::Users" do
visit admin_users_path(tab: 'cohorts')
- expect(page).to have_content("#{Time.now.strftime('%b %Y')} 3 0")
+ expect(page).to have_content("#{Time.zone.now.strftime('%b %Y')} 3 0")
end
end
diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb
index c13313609b5..4e6aae7c46f 100644
--- a/spec/features/admin/admin_uses_repository_checks_spec.rb
+++ b/spec/features/admin/admin_uses_repository_checks_spec.rb
@@ -43,7 +43,7 @@ RSpec.describe 'Admin uses repository checks', :request_store do
project = create(:project)
project.update_columns(
last_repository_check_failed: true,
- last_repository_check_at: Time.now
+ last_repository_check_at: Time.zone.now
)
visit_admin_project_page(project)
diff --git a/spec/features/admin/clusters/eks_spec.rb b/spec/features/admin/clusters/eks_spec.rb
index bb2678de2ae..71d2bba73b1 100644
--- a/spec/features/admin/clusters/eks_spec.rb
+++ b/spec/features/admin/clusters/eks_spec.rb
@@ -8,13 +8,15 @@ RSpec.describe 'Instance-level AWS EKS Cluster', :js do
before do
sign_in(user)
gitlab_enable_admin_mode_sign_in(user)
+ stub_application_setting(eks_integration_enabled: true)
end
context 'when user does not have a cluster and visits group clusters page' do
before do
visit admin_clusters_path
- click_link 'Connect with a certificate'
+ click_button 'Actions'
+ click_link 'Create a new cluster'
end
context 'when user creates a cluster on AWS EKS' do
@@ -23,7 +25,7 @@ RSpec.describe 'Instance-level AWS EKS Cluster', :js do
end
it 'user sees a form to create an EKS cluster' do
- expect(page).to have_content('Create new cluster on EKS')
+ expect(page).to have_content('Authenticate with Amazon Web Services')
end
end
end
diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb
index 0d053329627..7e8dee9cc0b 100644
--- a/spec/features/admin/users/user_spec.rb
+++ b/spec/features/admin/users/user_spec.rb
@@ -220,13 +220,13 @@ RSpec.describe 'Admin::Users::User' do
context 'a user with an expired password' do
before do
- another_user.update!(password_expires_at: Time.now - 5.minutes)
+ another_user.update!(password_expires_at: Time.zone.now - 5.minutes)
end
it 'does not redirect to password change page' do
subject
- expect(current_path).to eq('/')
+ expect(page).to have_current_path('/')
end
end
end
@@ -250,18 +250,18 @@ RSpec.describe 'Admin::Users::User' do
it 'is redirected back to the impersonated users page in the admin after stopping' do
subject
- expect(current_path).to eq("/admin/users/#{another_user.username}")
+ expect(page).to have_current_path("/admin/users/#{another_user.username}", ignore_query: true)
end
context 'a user with an expired password' do
before do
- another_user.update!(password_expires_at: Time.now - 5.minutes)
+ another_user.update!(password_expires_at: Time.zone.now - 5.minutes)
end
it 'is redirected back to the impersonated users page in the admin after stopping' do
subject
- expect(current_path).to eq("/admin/users/#{another_user.username}")
+ expect(page).to have_current_path("/admin/users/#{another_user.username}", ignore_query: true)
end
end
end
diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb
index 5b0b6e085c9..4d9a7f31911 100644
--- a/spec/features/admin/users/users_spec.rb
+++ b/spec/features/admin/users/users_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe 'Admin::Users' do
end
it "is ok" do
- expect(current_path).to eq(admin_users_path)
+ expect(page).to have_current_path(admin_users_path, ignore_query: true)
end
it "has users list" do
@@ -132,7 +132,7 @@ RSpec.describe 'Admin::Users' do
end
it 'searches with respect of sorting' do
- visit admin_users_path(sort: 'Name')
+ visit admin_users_path(sort: 'name_asc')
fill_in :search_query, with: 'Foo'
click_button('Search users')
@@ -338,6 +338,8 @@ RSpec.describe 'Admin::Users' do
end
it 'displays count of the users authorized groups' do
+ visit admin_users_path
+
wait_for_requests
expect(page.find("[data-testid='user-group-count-#{current_user.id}']").text).to eq("2")
@@ -574,7 +576,7 @@ RSpec.describe 'Admin::Users' do
user.reload
expect(user.name).to eq('Big Bang')
expect(user.admin?).to be_truthy
- expect(user.password_expires_at).to be <= Time.now
+ expect(user.password_expires_at).to be <= Time.zone.now
end
end
@@ -602,8 +604,8 @@ RSpec.describe 'Admin::Users' do
def sort_by(option)
page.within('.filtered-search-block') do
- find('.dropdown-menu-toggle').click
- click_link option
+ find('.gl-new-dropdown').click
+ find('.gl-new-dropdown-item', text: option).click
end
end
end
diff --git a/spec/features/boards/board_filters_spec.rb b/spec/features/boards/board_filters_spec.rb
index e37bf515088..537b677cbd0 100644
--- a/spec/features/boards/board_filters_spec.rb
+++ b/spec/features/boards/board_filters_spec.rb
@@ -22,8 +22,6 @@ RSpec.describe 'Issue board filters', :js do
let(:filter_submit) { find('.gl-search-box-by-click-search-button') }
before do
- stub_feature_flags(issue_boards_filtered_search: true)
-
project.add_maintainer(user)
sign_in(user)
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index 2ca4ff94911..5dd627f3b76 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -13,12 +13,17 @@ RSpec.describe 'Project issue boards', :js do
let_it_be(:user) { create(:user) }
let_it_be(:user2) { create(:user) }
+ let(:filtered_search) { find('[data-testid="issue-board-filtered-search"]') }
+ let(:filter_input) { find('.gl-filtered-search-term-input') }
+ let(:filter_submit) { find('.gl-search-box-by-click-search-button') }
+
context 'signed in user' do
before do
project.add_maintainer(user)
project.add_maintainer(user2)
sign_in(user)
+ stub_feature_flags(gl_avatar_for_all_user_avatars: false)
set_cookie('sidebar_collapsed', 'true')
end
@@ -90,8 +95,7 @@ RSpec.describe 'Project issue boards', :js do
end
it 'search closed list' do
- find('.filtered-search').set(issue8.title)
- find('.filtered-search').native.send_keys(:enter)
+ set_filter_and_search_by_token_value(issue8.title)
wait_for_requests
@@ -101,8 +105,7 @@ RSpec.describe 'Project issue boards', :js do
end
it 'search list' do
- find('.filtered-search').set(issue5.title)
- find('.filtered-search').native.send_keys(:enter)
+ set_filter_and_search_by_token_value(issue5.title)
wait_for_requests
@@ -111,26 +114,6 @@ RSpec.describe 'Project issue boards', :js do
expect(find('.board:nth-child(4)')).to have_selector('.board-card', count: 0)
end
- context 'search list negation queries' do
- before do
- visit_project_board_path_without_query_limit(project, board)
- end
-
- it 'does not have the != option' do
- find('.filtered-search').set('label:')
-
- wait_for_requests
- within('#js-dropdown-operator') do
- tokens = all(:css, 'li.filter-dropdown-item')
- expect(tokens.count).to eq(2)
- button = tokens[0].find('button')
- expect(button).to have_content('=')
- button = tokens[1].find('button')
- expect(button).to have_content('!=')
- end
- end
- end
-
it 'allows user to delete board' do
remove_list
@@ -309,8 +292,8 @@ RSpec.describe 'Project issue boards', :js do
context 'filtering' do
it 'filters by author' do
set_filter("author", user2.username)
- click_filter_link(user2.username)
- submit_filter
+ click_on user2.username
+ filter_submit.click
wait_for_requests
wait_for_board_cards(2, 1)
@@ -319,8 +302,8 @@ RSpec.describe 'Project issue boards', :js do
it 'filters by assignee' do
set_filter("assignee", user.username)
- click_filter_link(user.username)
- submit_filter
+ click_on user.username
+ filter_submit.click
wait_for_requests
@@ -330,8 +313,8 @@ RSpec.describe 'Project issue boards', :js do
it 'filters by milestone' do
set_filter("milestone", "\"#{milestone.title}")
- click_filter_link(milestone.title)
- submit_filter
+ click_on milestone.title
+ filter_submit.click
wait_for_requests
wait_for_board_cards(2, 1)
@@ -341,8 +324,8 @@ RSpec.describe 'Project issue boards', :js do
it 'filters by label' do
set_filter("label", testing.title)
- click_filter_link(testing.title)
- submit_filter
+ click_on testing.title
+ filter_submit.click
wait_for_requests
wait_for_board_cards(2, 1)
@@ -351,8 +334,10 @@ RSpec.describe 'Project issue boards', :js do
it 'filters by label with encoded character' do
set_filter("label", a_plus.title)
- click_filter_link(a_plus.title)
- submit_filter
+ # This one is a char encoding issue like the & issue
+ click_on a_plus.title
+ filter_submit.click
+ wait_for_requests
wait_for_board_cards(1, 1)
wait_for_empty_boards((2..4))
@@ -360,8 +345,8 @@ RSpec.describe 'Project issue boards', :js do
it 'filters by label with space after reload', :quarantine do
set_filter("label", "\"#{accepting.title}")
- click_filter_link(accepting.title)
- submit_filter
+ click_on accepting.title
+ filter_submit.click
# Test after reload
page.evaluate_script 'window.location.reload()'
@@ -384,13 +369,13 @@ RSpec.describe 'Project issue boards', :js do
it 'removes filtered labels' do
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
set_filter("label", testing.title)
- click_filter_link(testing.title)
- submit_filter
+ click_on testing.title
+ filter_submit.click
wait_for_board_cards(2, 1)
- find('.clear-search').click
- submit_filter
+ find('[data-testid="filtered-search-clear-button"]').click
+ filter_submit.click
end
wait_for_board_cards(2, 8)
@@ -400,9 +385,9 @@ RSpec.describe 'Project issue boards', :js do
create_list(:labeled_issue, 30, project: project, labels: [planning, testing])
set_filter("label", testing.title)
- click_filter_link(testing.title)
+ click_on testing.title
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
- submit_filter
+ filter_submit.click
end
wait_for_requests
@@ -442,10 +427,10 @@ RSpec.describe 'Project issue boards', :js do
it 'filters by multiple labels', :quarantine do
set_filter("label", testing.title)
- click_filter_link(testing.title)
+ click_on testing.title
set_filter("label", bug.title)
- click_filter_link(bug.title)
+ click_on bug.title
submit_filter
@@ -463,7 +448,7 @@ RSpec.describe 'Project issue boards', :js do
wait_for_requests
end
- page.within('.tokens-container') do
+ page.within('.gl-filtered-search-token') do
expect(page).to have_content(bug.title)
end
@@ -561,19 +546,26 @@ RSpec.describe 'Project issue boards', :js do
end
end
+ def set_filter_and_search_by_token_value(value)
+ filter_input.click
+ filter_input.set(value)
+ filter_submit.click
+ end
+
def set_filter(type, text)
- find('.filtered-search').native.send_keys("#{type}:=#{text}")
+ filter_input.click
+ filter_input.native.send_keys("#{type}:=#{text}")
end
def submit_filter
- find('.filtered-search').native.send_keys(:enter)
+ filter_input.native.send_keys(:enter)
end
def click_filter_link(link_text)
- page.within('.filtered-search-box') do
+ page.within(filtered_search) do
expect(page).to have_button(link_text)
- click_button(link_text)
+ click_on link_text
end
end
diff --git a/spec/features/callouts/registration_enabled_spec.rb b/spec/features/callouts/registration_enabled_spec.rb
index 4055965273f..79e99712183 100644
--- a/spec/features/callouts/registration_enabled_spec.rb
+++ b/spec/features/callouts/registration_enabled_spec.rb
@@ -5,6 +5,8 @@ require 'spec_helper'
RSpec.describe 'Registration enabled callout' do
let_it_be(:admin) { create(:admin) }
let_it_be(:non_admin) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:callout_title) { _('Anyone can register for an account.') }
context 'when "Sign-up enabled" setting is `true`' do
before do
@@ -14,23 +16,42 @@ RSpec.describe 'Registration enabled callout' do
context 'when an admin is logged in' do
before do
sign_in(admin)
+ end
+
+ it 'displays callout on admin and dashboard pages and root page' do
+ visit root_path
+
+ expect(page).to have_content callout_title
+ expect(page).to have_link _('Turn off'), href: general_admin_application_settings_path(anchor: 'js-signup-settings')
+
visit root_dashboard_path
+
+ expect(page).to have_content callout_title
+
+ visit admin_root_path
+
+ expect(page).to have_content callout_title
end
- it 'displays callout' do
- expect(page).to have_content 'Open registration is enabled on your instance.'
- expect(page).to have_link 'View setting', href: general_admin_application_settings_path(anchor: 'js-signup-settings')
+ it 'does not display callout on pages other than root, admin, or dashboard' do
+ visit project_issues_path(project)
+
+ expect(page).not_to have_content callout_title
end
context 'when callout is dismissed', :js do
before do
+ visit admin_root_path
+
find('[data-testid="close-registration-enabled-callout"]').click
+ wait_for_requests
+
visit root_dashboard_path
end
it 'does not display callout' do
- expect(page).not_to have_content 'Open registration is enabled on your instance.'
+ expect(page).not_to have_content callout_title
end
end
end
@@ -42,7 +63,7 @@ RSpec.describe 'Registration enabled callout' do
end
it 'does not display callout' do
- expect(page).not_to have_content 'Open registration is enabled on your instance.'
+ expect(page).not_to have_content callout_title
end
end
end
diff --git a/spec/features/clusters/cluster_detail_page_spec.rb b/spec/features/clusters/cluster_detail_page_spec.rb
index 06e3e00db7d..09e042b00cc 100644
--- a/spec/features/clusters/cluster_detail_page_spec.rb
+++ b/spec/features/clusters/cluster_detail_page_spec.rb
@@ -36,6 +36,20 @@ 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/commits_spec.rb b/spec/features/commits_spec.rb
index e600a99e3b6..db841ffc627 100644
--- a/spec/features/commits_spec.rb
+++ b/spec/features/commits_spec.rb
@@ -30,23 +30,7 @@ RSpec.describe 'Commits' do
project.add_reporter(user)
end
- describe 'Commit builds with jobs_tab_vue feature flag off' do
- before do
- stub_feature_flags(jobs_tab_vue: false)
- visit builds_project_pipeline_path(project, pipeline)
- end
-
- it { expect(page).to have_content pipeline.sha[0..7] }
-
- it 'contains generic commit status build' do
- page.within('.table-holder') do
- expect(page).to have_content "##{status.id}" # build id
- expect(page).to have_content 'generic' # build name
- end
- end
- end
-
- describe 'Commit builds with jobs_tab_vue feature flag on', :js do
+ describe 'Commit builds', :js do
before do
visit builds_project_pipeline_path(project, pipeline)
@@ -107,20 +91,7 @@ RSpec.describe 'Commits' do
end
end
- context 'Download artifacts with jobs_tab_vue feature flag off' do
- before do
- stub_feature_flags(jobs_tab_vue: false)
- create(:ci_job_artifact, :archive, file: artifacts_file, job: build)
- end
-
- it do
- visit pipeline_path(pipeline)
- click_on 'Download artifacts'
- expect(page.response_headers['Content-Type']).to eq(artifacts_file.content_type)
- end
- end
-
- context 'Download artifacts with jobs_tab_vue feature flag on', :js do
+ context 'Download artifacts', :js do
before do
create(:ci_job_artifact, :archive, file: artifacts_file, job: build)
end
@@ -149,28 +120,7 @@ RSpec.describe 'Commits' do
end
end
- context "when logged as reporter and with jobs_tab_vue feature flag off" do
- before do
- stub_feature_flags(jobs_tab_vue: false)
- project.add_reporter(user)
- create(:ci_job_artifact, :archive, file: artifacts_file, job: build)
- visit pipeline_path(pipeline)
- end
-
- it 'renders header', :js do
- expect(page).to have_content pipeline.sha[0..7]
- expect(page).to have_content pipeline.git_commit_message.gsub!(/\s+/, ' ')
- expect(page).to have_content pipeline.user.name
- expect(page).not_to have_link('Cancel running')
- expect(page).not_to have_link('Retry')
- end
-
- it do
- expect(page).to have_link('Download artifacts')
- end
- end
-
- context "when logged as reporter and with jobs_tab_vue feature flag on", :js do
+ context "when logged as reporter", :js do
before do
project.add_reporter(user)
create(:ci_job_artifact, :archive, file: artifacts_file, job: build)
diff --git a/spec/features/dashboard/group_spec.rb b/spec/features/dashboard/group_spec.rb
index 02cbdc7c777..f1283d29f4c 100644
--- a/spec/features/dashboard/group_spec.rb
+++ b/spec/features/dashboard/group_spec.rb
@@ -23,7 +23,7 @@ RSpec.describe 'Dashboard Group' do
fill_in 'group_name', with: new_name
click_button 'Create group'
- expect(current_path).to eq group_path(Group.find_by(name: new_name))
+ expect(page).to have_current_path group_path(Group.find_by(name: new_name)), ignore_query: true
expect(page).to have_content(new_name)
end
end
diff --git a/spec/features/dashboard/issuables_counter_spec.rb b/spec/features/dashboard/issuables_counter_spec.rb
index 6700ec07765..aa445265eec 100644
--- a/spec/features/dashboard/issuables_counter_spec.rb
+++ b/spec/features/dashboard/issuables_counter_spec.rb
@@ -8,41 +8,68 @@ RSpec.describe 'Navigation bar counter', :use_clean_rails_memory_store_caching d
let(:issue) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, source_project: project) }
- before do
- issue.assignees = [user]
- merge_request.update!(assignees: [user])
- sign_in(user)
- end
+ describe 'feature flag mr_attention_requests is disabled' do
+ before do
+ stub_feature_flags(mr_attention_requests: false)
- it 'reflects dashboard issues count' do
- visit issues_path
+ issue.assignees = [user]
+ merge_request.update!(assignees: [user])
+ sign_in(user)
+ end
- expect_counters('issues', '1', n_("%d assigned issue", "%d assigned issues", 1) % 1)
+ it 'reflects dashboard issues count' do
+ visit issues_path
- issue.assignees = []
+ expect_counters('issues', '1', n_("%d assigned issue", "%d assigned issues", 1) % 1)
- user.invalidate_cache_counts
+ issue.assignees = []
- travel_to(3.minutes.from_now) do
- visit issues_path
+ user.invalidate_cache_counts
+
+ travel_to(3.minutes.from_now) do
+ visit issues_path
- expect_counters('issues', '0', n_("%d assigned issue", "%d assigned issues", 0) % 0)
+ expect_counters('issues', '0', n_("%d assigned issue", "%d assigned issues", 0) % 0)
+ end
+ end
+
+ it 'reflects dashboard merge requests count', :js do
+ visit merge_requests_path
+
+ expect_counters('merge_requests', '1', n_("%d merge request", "%d merge requests", 1) % 1)
+
+ merge_request.update!(assignees: [])
+
+ user.invalidate_cache_counts
+
+ travel_to(3.minutes.from_now) do
+ visit merge_requests_path
+
+ expect_counters('merge_requests', '0', n_("%d merge request", "%d merge requests", 0) % 0)
+ end
end
end
- it 'reflects dashboard merge requests count' do
- visit merge_requests_path
+ describe 'feature flag mr_attention_requests is enabled' do
+ before do
+ merge_request.update!(assignees: [user])
+ sign_in(user)
+ end
- expect_counters('merge_requests', '1', n_("%d merge request", "%d merge requests", 1) % 1)
+ it 'reflects dashboard merge requests count', :js do
+ visit merge_requests_attention_path
- merge_request.update!(assignees: [])
+ expect_counters('merge_requests', '1', n_("%d merge request", "%d merge requests", 1) % 1)
- user.invalidate_cache_counts
+ merge_request.find_assignee(user).update!(state: :reviewed)
- travel_to(3.minutes.from_now) do
- visit merge_requests_path
+ user.invalidate_attention_requested_count
- expect_counters('merge_requests', '0', n_("%d merge request", "%d merge requests", 0) % 0)
+ travel_to(3.minutes.from_now) do
+ visit merge_requests_attention_path
+
+ expect_counters('merge_requests', '0', n_("%d merge request", "%d merge requests", 0) % 0)
+ end
end
end
@@ -54,14 +81,15 @@ RSpec.describe 'Navigation bar counter', :use_clean_rails_memory_store_caching d
merge_requests_dashboard_path(assignee_username: user.username)
end
+ def merge_requests_attention_path
+ merge_requests_dashboard_path(attention: user.username)
+ end
+
def expect_counters(issuable_type, count, badge_label)
dashboard_count = find('.gl-tabs-nav li a.active')
- nav_count = find(".dashboard-shortcuts-#{issuable_type}")
expect(dashboard_count).to have_content(count)
- expect(nav_count).to have_content(count)
- within("span[aria-label='#{badge_label}']") do
- expect(page).to have_content(count)
- end
+ expect(page).to have_css(".dashboard-shortcuts-#{issuable_type}", visible: :all, text: count)
+ expect(page).to have_css("span[aria-label='#{badge_label}']", visible: :all, text: count)
end
end
diff --git a/spec/features/dashboard/milestones_spec.rb b/spec/features/dashboard/milestones_spec.rb
index 9758454ab61..3f89955b12b 100644
--- a/spec/features/dashboard/milestones_spec.rb
+++ b/spec/features/dashboard/milestones_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'Dashboard > Milestones' do
end
it 'is redirected to sign-in page' do
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
end
@@ -27,7 +27,7 @@ RSpec.describe 'Dashboard > Milestones' do
end
it 'sees milestones' do
- expect(current_path).to eq dashboard_milestones_path
+ expect(page).to have_current_path dashboard_milestones_path, ignore_query: true
expect(page).to have_content(milestone.title)
expect(page).to have_content(group.name)
expect(first('.milestone')).to have_content('Merge requests')
@@ -43,7 +43,7 @@ RSpec.describe 'Dashboard > Milestones' do
find('.js-new-project-item-link').click
- expect(current_path).to eq(new_group_milestone_path(group))
+ expect(page).to have_current_path(new_group_milestone_path(group), ignore_query: true)
end
end
end
@@ -61,7 +61,7 @@ RSpec.describe 'Dashboard > Milestones' do
end
it 'does not see milestones' do
- expect(current_path).to eq dashboard_milestones_path
+ expect(page).to have_current_path dashboard_milestones_path, ignore_query: true
expect(page).to have_content(milestone.title)
expect(first('.milestone')).to have_no_content('Merge Requests')
end
diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb
index 82288a6c1a6..847d0faf60d 100644
--- a/spec/features/dashboard/projects_spec.rb
+++ b/spec/features/dashboard/projects_spec.rb
@@ -48,7 +48,7 @@ RSpec.describe 'Dashboard Projects' do
context 'when last_repository_updated_at, last_activity_at and update_at are present' do
it 'shows the last_repository_updated_at attribute as the update date' do
- project.update!(last_repository_updated_at: Time.now, last_activity_at: 1.hour.ago)
+ project.update!(last_repository_updated_at: Time.zone.now, last_activity_at: 1.hour.ago)
visit dashboard_projects_path
@@ -56,7 +56,7 @@ RSpec.describe 'Dashboard Projects' do
end
it 'shows the last_activity_at attribute as the update date' do
- project.update!(last_repository_updated_at: 1.hour.ago, last_activity_at: Time.now)
+ project.update!(last_repository_updated_at: 1.hour.ago, last_activity_at: Time.zone.now)
visit dashboard_projects_path
@@ -236,7 +236,7 @@ RSpec.describe 'Dashboard Projects' do
end
expect(page).to have_selector('.merge-request-form')
- expect(current_path).to eq project_new_merge_request_path(project)
+ expect(page).to have_current_path project_new_merge_request_path(project), ignore_query: true
expect(find('#merge_request_target_project_id', visible: false).value).to eq project.id.to_s
expect(page).to have_content "From feature into master"
end
diff --git a/spec/features/dashboard/todos/todos_filtering_spec.rb b/spec/features/dashboard/todos/todos_filtering_spec.rb
index 53209db3107..938e42623f6 100644
--- a/spec/features/dashboard/todos/todos_filtering_spec.rb
+++ b/spec/features/dashboard/todos/todos_filtering_spec.rb
@@ -178,7 +178,7 @@ RSpec.describe 'Dashboard > User filters todos', :js do
review_requested: ' requested a review of ',
mentioned: ' mentioned ',
marked: ' added a todo for ',
- build_failed: ' build failed for '
+ build_failed: ' pipeline failed in '
}
action_name_text = action_names.delete(action_name)
diff --git a/spec/features/dashboard/todos/todos_spec.rb b/spec/features/dashboard/todos/todos_spec.rb
index b00bdeac3b9..68d979bb1cf 100644
--- a/spec/features/dashboard/todos/todos_spec.rb
+++ b/spec/features/dashboard/todos/todos_spec.rb
@@ -400,7 +400,7 @@ RSpec.describe 'Dashboard Todos' do
end
it 'shows the todo' do
- expect(page).to have_content 'The build failed for merge request'
+ expect(page).to have_content 'The pipeline failed in merge request'
end
it 'links to the pipelines for the merge request' do
@@ -441,7 +441,7 @@ RSpec.describe 'Dashboard Todos' do
target.project, target.issue, target.filename
)
- expect(current_path).to eq(expectation)
+ expect(page).to have_current_path(expectation, ignore_query: true)
end
end
end
diff --git a/spec/features/dashboard/user_filters_projects_spec.rb b/spec/features/dashboard/user_filters_projects_spec.rb
index f6821ae66e8..2cf56f93cf9 100644
--- a/spec/features/dashboard/user_filters_projects_spec.rb
+++ b/spec/features/dashboard/user_filters_projects_spec.rb
@@ -79,11 +79,11 @@ RSpec.describe 'Dashboard > User filters projects' do
page.find('.filtered-search-block #filtered-search-sorting-dropdown .reverse-sort-btn').click
end
- def select_dropdown_option(selector, label)
+ def select_dropdown_option(selector, label, option_selector = '.dropdown-menu a')
dropdown = page.find(selector)
dropdown.click
- dropdown.find('.dropdown-menu a', text: label, match: :first).click
+ dropdown.find(option_selector, text: label, match: :first).click
end
def expect_to_see_projects(sorted_projects)
@@ -125,7 +125,7 @@ RSpec.describe 'Dashboard > User filters projects' do
end
it 'filters private projects only' do
- select_dropdown_option '#filtered-search-visibility-dropdown', 'Private'
+ select_dropdown_option '#filtered-search-visibility-dropdown > .dropdown', 'Private', '.dropdown-item'
expect(current_url).to match(/visibility_level=0/)
@@ -135,7 +135,7 @@ RSpec.describe 'Dashboard > User filters projects' do
end
it 'filters internal projects only' do
- select_dropdown_option '#filtered-search-visibility-dropdown', 'Internal'
+ select_dropdown_option '#filtered-search-visibility-dropdown > .dropdown', 'Internal', '.dropdown-item'
expect(current_url).to match(/visibility_level=10/)
@@ -145,7 +145,7 @@ RSpec.describe 'Dashboard > User filters projects' do
end
it 'filters any project' do
- select_dropdown_option '#filtered-search-visibility-dropdown', 'Any'
+ select_dropdown_option '#filtered-search-visibility-dropdown > .dropdown', 'Any', '.dropdown-item'
list = page.all('.projects-list .project-name').map(&:text)
expect(list).to contain_exactly("Internal project", "Private project", "Treasure", "Victorialand")
diff --git a/spec/features/expand_collapse_diffs_spec.rb b/spec/features/expand_collapse_diffs_spec.rb
index 63e16946a0b..98282e47488 100644
--- a/spec/features/expand_collapse_diffs_spec.rb
+++ b/spec/features/expand_collapse_diffs_spec.rb
@@ -13,6 +13,8 @@ RSpec.describe 'Expand and collapse diffs', :js do
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
+ wait_for_requests
+
# Ensure that undiffable.md is in .gitattributes
project.repository.copy_gitattributes(branch)
visit project_commit_path(project, project.commit(branch))
diff --git a/spec/features/explore/topics_spec.rb b/spec/features/explore/topics_spec.rb
index 9d2e76bc3a1..d6f3d6a123d 100644
--- a/spec/features/explore/topics_spec.rb
+++ b/spec/features/explore/topics_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe 'Explore Topics' do
it 'renders empty message', :aggregate_failures do
visit topics_explore_projects_path
- expect(current_path).to eq topics_explore_projects_path
+ expect(page).to have_current_path topics_explore_projects_path, ignore_query: true
expect(page).to have_content('There are no topics to show.')
end
end
@@ -18,7 +18,7 @@ RSpec.describe 'Explore Topics' do
it 'renders topic list' do
visit topics_explore_projects_path
- expect(current_path).to eq topics_explore_projects_path
+ expect(page).to have_current_path topics_explore_projects_path, ignore_query: true
expect(page).to have_content('topic1')
end
end
diff --git a/spec/features/file_uploads/user_avatar_spec.rb b/spec/features/file_uploads/user_avatar_spec.rb
index c30e3452201..34cfb4a4128 100644
--- a/spec/features/file_uploads/user_avatar_spec.rb
+++ b/spec/features/file_uploads/user_avatar_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe 'Upload a user avatar', :js do
expect(page).to have_content 'Profile was successfully updated'
expect(user.reload.avatar.file).to be_present
expect(user.avatar).to be_instance_of AvatarUploader
- expect(current_path).to eq(profile_path)
+ expect(page).to have_current_path(profile_path, ignore_query: true)
end
end
diff --git a/spec/features/global_search_spec.rb b/spec/features/global_search_spec.rb
index 0397e72502a..baa691d244e 100644
--- a/spec/features/global_search_spec.rb
+++ b/spec/features/global_search_spec.rb
@@ -72,6 +72,10 @@ RSpec.describe 'Global search' do
# TODO: Remove this along with feature flag #339348
stub_feature_flags(new_header_search: true)
visit dashboard_projects_path
+
+ # intialize javascript loaded input search input field
+ find('#search').click
+ find('body').click
end
it 'renders updated search bar' do
diff --git a/spec/features/groups/clusters/eks_spec.rb b/spec/features/groups/clusters/eks_spec.rb
index fe62efbd3bf..3cca2d0919c 100644
--- a/spec/features/groups/clusters/eks_spec.rb
+++ b/spec/features/groups/clusters/eks_spec.rb
@@ -13,13 +13,15 @@ RSpec.describe 'Group AWS EKS Cluster', :js do
allow(Groups::ClustersController).to receive(:STATUS_POLLING_INTERVAL) { 100 }
allow_any_instance_of(Clusters::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute)
allow_any_instance_of(Clusters::Cluster).to receive(:retrieve_connection_status).and_return(:connected)
+ stub_application_setting(eks_integration_enabled: true)
end
context 'when user does not have a cluster and visits group clusters page' do
before do
visit group_clusters_path(group)
- click_link 'Connect with a certificate'
+ click_button 'Actions'
+ click_link 'Create a new cluster'
end
context 'when user creates a cluster on AWS EKS' do
@@ -28,7 +30,7 @@ RSpec.describe 'Group AWS EKS Cluster', :js do
end
it 'user sees a form to create an EKS cluster' do
- expect(page).to have_content('Create new cluster on EKS')
+ expect(page).to have_content('Authenticate with Amazon Web Services')
end
end
end
diff --git a/spec/features/groups/clusters/user_spec.rb b/spec/features/groups/clusters/user_spec.rb
index 1788167c94c..2ed6ddc09ab 100644
--- a/spec/features/groups/clusters/user_spec.rb
+++ b/spec/features/groups/clusters/user_spec.rb
@@ -26,7 +26,6 @@ RSpec.describe 'User Cluster', :js do
visit group_clusters_path(group)
click_link 'Connect with a certificate'
- click_link 'Connect existing cluster'
end
context 'when user filled form with valid parameters' do
@@ -94,16 +93,7 @@ RSpec.describe 'User Cluster', :js do
expect(page).to have_button('Save changes')
end
- context 'when user disables the cluster' do
- before do
- page.find(:css, '.js-cluster-enable-toggle-area .js-project-feature-toggle').click
- page.within('.js-cluster-details-form') { click_button 'Save changes' }
- end
-
- it 'user sees the successful message' do
- expect(page).to have_content('Kubernetes cluster was successfully updated.')
- end
- end
+ include_examples "user disables a cluster"
context 'when user changes cluster parameters' do
before do
diff --git a/spec/features/groups/container_registry_spec.rb b/spec/features/groups/container_registry_spec.rb
index f5af9ba8b7b..7bef2dc9416 100644
--- a/spec/features/groups/container_registry_spec.rb
+++ b/spec/features/groups/container_registry_spec.rb
@@ -97,6 +97,8 @@ RSpec.describe 'Container Registry', :js do
expect(find('.modal .modal-title')).to have_content _('Remove tag')
find('.modal .modal-footer .btn-danger').click
end
+
+ it_behaves_like 'rejecting tags destruction for an importing repository on', tags: ['latest']
end
end
diff --git a/spec/features/groups/group_settings_spec.rb b/spec/features/groups/group_settings_spec.rb
index 30a81333547..50982cb1452 100644
--- a/spec/features/groups/group_settings_spec.rb
+++ b/spec/features/groups/group_settings_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe 'Edit group settings' do
update_path(new_group_path)
visit new_group_full_path
- expect(current_path).to eq(new_group_full_path)
+ expect(page).to have_current_path(new_group_full_path, ignore_query: true)
expect(find('h1.home-panel-title')).to have_content(group.name)
end
@@ -28,7 +28,7 @@ RSpec.describe 'Edit group settings' do
update_path(new_group_path)
visit old_group_full_path
- expect(current_path).to eq(new_group_full_path)
+ expect(page).to have_current_path(new_group_full_path, ignore_query: true)
expect(find('h1.home-panel-title')).to have_content(group.name)
end
@@ -41,7 +41,7 @@ RSpec.describe 'Edit group settings' do
update_path(new_group_path)
visit new_subgroup_full_path
- expect(current_path).to eq(new_subgroup_full_path)
+ expect(page).to have_current_path(new_subgroup_full_path, ignore_query: true)
expect(find('h1.home-panel-title')).to have_content(subgroup.name)
end
@@ -49,7 +49,7 @@ RSpec.describe 'Edit group settings' do
update_path(new_group_path)
visit old_subgroup_full_path
- expect(current_path).to eq(new_subgroup_full_path)
+ expect(page).to have_current_path(new_subgroup_full_path, ignore_query: true)
expect(find('h1.home-panel-title')).to have_content(subgroup.name)
end
end
@@ -71,7 +71,7 @@ RSpec.describe 'Edit group settings' do
update_path(new_group_path)
visit new_project_full_path
- expect(current_path).to eq(new_project_full_path)
+ expect(page).to have_current_path(new_project_full_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(project.path)
end
@@ -79,7 +79,7 @@ RSpec.describe 'Edit group settings' do
update_path(new_group_path)
visit old_project_full_path
- expect(current_path).to eq(new_project_full_path)
+ expect(page).to have_current_path(new_project_full_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(project.path)
end
end
@@ -154,32 +154,50 @@ RSpec.describe 'Edit group settings' do
namespace_select.find('button').click
namespace_select.find('.dropdown-menu p', text: target_group_name, match: :first).click
- click_button "Transfer group"
+ click_button 'Transfer group'
end
page.within(confirm_modal) do
- expect(page).to have_text "You are going to transfer #{selected_group.name} to another namespace. Are you ABSOLUTELY sure? "
+ expect(page).to have_text "You are going to transfer #{selected_group.name} to another namespace. Are you ABSOLUTELY sure?"
- fill_in "confirm_name_input", with: selected_group.name
- click_button "Confirm"
+ fill_in 'confirm_name_input', with: selected_group.name
+ click_button 'Confirm'
end
expect(page).to have_text "Group '#{selected_group.name}' was successfully transferred."
+ expect(current_url).to include(selected_group.reload.full_path)
end
end
- context 'with a sub group' do
+ context 'from a subgroup' do
let(:selected_group) { create(:group, path: 'foo-subgroup', parent: group) }
- let(:target_group_name) { "No parent group" }
- it_behaves_like 'can transfer the group'
+ context 'to no parent group' do
+ let(:target_group_name) { 'No parent group' }
+
+ it_behaves_like 'can transfer the group'
+ end
+
+ context 'to a different parent group' do
+ let(:target_group) { create(:group, path: 'foo-parentgroup') }
+ let(:target_group_name) { target_group.name }
+
+ before do
+ target_group.add_owner(user)
+ end
+
+ it_behaves_like 'can transfer the group'
+ end
end
- context 'with a root group' do
+ context 'from a root group' do
let(:selected_group) { create(:group, path: 'foo-rootgroup') }
- let(:target_group_name) { group.name }
- it_behaves_like 'can transfer the group'
+ context 'to a parent group' do
+ let(:target_group_name) { group.name }
+
+ it_behaves_like 'can transfer the group'
+ end
end
end
diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb
index 3fc1484826c..6b663445124 100644
--- a/spec/features/groups/issues_spec.rb
+++ b/spec/features/groups/issues_spec.rb
@@ -108,6 +108,22 @@ RSpec.describe 'Group issues page' do
end
end
+ context 'group with no issues', :js do
+ let!(:group_with_no_issues) { create(:group) }
+ let!(:subgroup_with_issues) { create(:group, parent: group_with_no_issues) }
+ let!(:subgroup_project) { create(:project, :public, group: subgroup_with_issues) }
+ let!(:subgroup_issue) { create(:issue, project: subgroup_project) }
+
+ before do
+ stub_feature_flags(vue_issues_list: true)
+ visit issues_group_path(group_with_no_issues)
+ end
+
+ it 'shows issues from subgroups on issues list' do
+ expect(page).to have_text subgroup_issue.title
+ end
+ end
+
context 'projects with issues disabled' do
describe 'issue dropdown' do
let(:user_in_group) { create(:group_member, :maintainer, user: create(:user), group: group ).user }
diff --git a/spec/features/groups/labels/create_spec.rb b/spec/features/groups/labels/create_spec.rb
index 9c1a3672ebd..19433e612ff 100644
--- a/spec/features/groups/labels/create_spec.rb
+++ b/spec/features/groups/labels/create_spec.rb
@@ -18,6 +18,6 @@ RSpec.describe 'Create a group label' do
click_button 'Create label'
expect(page).to have_content 'test-label'
- expect(current_path).to eq(group_labels_path(group))
+ expect(page).to have_current_path(group_labels_path(group), ignore_query: true)
end
end
diff --git a/spec/features/groups/labels/edit_spec.rb b/spec/features/groups/labels/edit_spec.rb
index 8e6560af352..cf1729af97d 100644
--- a/spec/features/groups/labels/edit_spec.rb
+++ b/spec/features/groups/labels/edit_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe 'Edit group label' do
fill_in 'label_title', with: 'new label name'
click_button 'Save changes'
- expect(current_path).to eq(root_path)
+ expect(page).to have_current_path(root_path, ignore_query: true)
expect(label.reload.title).to eq('new label name')
end
diff --git a/spec/features/groups/labels/sort_labels_spec.rb b/spec/features/groups/labels/sort_labels_spec.rb
index df75ff7c3cb..fba166449f8 100644
--- a/spec/features/groups/labels/sort_labels_spec.rb
+++ b/spec/features/groups/labels/sort_labels_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'Sort labels', :js do
it 'sorts by date' do
click_button 'Name'
- sort_options = find('ul.dropdown-menu-sort li').all('a').collect(&:text)
+ sort_options = find('ul.dropdown-menu').all('li').collect(&:text)
expect(sort_options[0]).to eq('Name')
expect(sort_options[1]).to eq('Name, descending')
@@ -37,7 +37,7 @@ RSpec.describe 'Sort labels', :js do
expect(sort_options[4]).to eq('Updated date')
expect(sort_options[5]).to eq('Oldest updated')
- click_link 'Name, descending'
+ click_button 'Name, descending'
# assert default sorting
within '.other-labels' do
diff --git a/spec/features/groups/members/leave_group_spec.rb b/spec/features/groups/members/leave_group_spec.rb
index 9612c6625f6..50d5db46cee 100644
--- a/spec/features/groups/members/leave_group_spec.rb
+++ b/spec/features/groups/members/leave_group_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe 'Groups > Members > Leave group' do
visit group_path(group)
click_link 'Leave group'
- expect(current_path).to eq(dashboard_groups_path)
+ expect(page).to have_current_path(dashboard_groups_path, ignore_query: true)
expect(page).to have_content left_group_message(group)
expect(group.users).not_to include(user)
end
@@ -35,7 +35,7 @@ RSpec.describe 'Groups > Members > Leave group' do
page.accept_confirm
wait_for_all_requests
- expect(current_path).to eq(dashboard_groups_path)
+ expect(page).to have_current_path(dashboard_groups_path, ignore_query: true)
expect(group.users).not_to include(user)
end
@@ -45,7 +45,7 @@ RSpec.describe 'Groups > Members > Leave group' do
visit group_path(group)
click_link 'Leave group'
- expect(current_path).to eq(dashboard_groups_path)
+ expect(page).to have_current_path(dashboard_groups_path, ignore_query: true)
expect(page).to have_content left_group_message(group)
expect(group.users).not_to include(user)
end
@@ -57,7 +57,7 @@ RSpec.describe 'Groups > Members > Leave group' do
visit group_path(group)
click_link 'Leave group'
- expect(current_path).to eq(dashboard_groups_path)
+ expect(page).to have_current_path(dashboard_groups_path, ignore_query: true)
expect(page).to have_content left_group_message(group)
expect(group.users).not_to include(user)
end
diff --git a/spec/features/groups/members/manage_groups_spec.rb b/spec/features/groups/members/manage_groups_spec.rb
index 61c6709f9cc..5ab5a7ea716 100644
--- a/spec/features/groups/members/manage_groups_spec.rb
+++ b/spec/features/groups/members/manage_groups_spec.rb
@@ -14,34 +14,6 @@ RSpec.describe 'Groups > Members > Manage groups', :js do
sign_in(user)
end
- context 'with invite_members_group_modal disabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- context 'when group link does not exist' do
- let_it_be(:group) { create(:group) }
- let_it_be(:group_to_add) { create(:group) }
-
- before do
- group.add_owner(user)
- group_to_add.add_owner(user)
- visit group_group_members_path(group)
- end
-
- it 'can share group with group' do
- add_group(group_to_add.id, 'Reporter')
-
- click_groups_tab
-
- page.within(first_row) do
- expect(page).to have_content(group_to_add.name)
- expect(page).to have_content('Reporter')
- end
- end
- end
- end
-
context 'when group link does not exist' do
it 'can share a group with group' do
group = create(:group)
@@ -177,32 +149,14 @@ RSpec.describe 'Groups > Members > Manage groups', :js do
end
context 'when sharing with groups outside the hierarchy is enabled' do
- context 'when the invite members group modal is disabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- it 'shows groups within and outside the hierarchy in search results' do
- visit group_group_members_path(group)
-
- click_on 'Invite group'
- click_on 'Search for a group'
-
- expect(page).to have_text group_within_hierarchy.name
- expect(page).to have_text group_outside_hierarchy.name
- end
- end
-
- context 'when the invite members group modal is enabled' do
- it 'shows groups within and outside the hierarchy in search results' do
- visit group_group_members_path(group)
+ it 'shows groups within and outside the hierarchy in search results' do
+ visit group_group_members_path(group)
- click_on 'Invite a group'
- click_on 'Select a group'
+ click_on 'Invite a group'
+ click_on 'Select a group'
- expect(page).to have_text group_within_hierarchy.name
- expect(page).to have_text group_outside_hierarchy.name
- end
+ expect(page).to have_text group_within_hierarchy.name
+ expect(page).to have_text group_outside_hierarchy.name
end
end
@@ -211,45 +165,18 @@ RSpec.describe 'Groups > Members > Manage groups', :js do
group.namespace_settings.update!(prevent_sharing_groups_outside_hierarchy: true)
end
- context 'when the invite members group modal is disabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- it 'shows only groups within the hierarchy in search results' do
- visit group_group_members_path(group)
-
- click_on 'Invite group'
- click_on 'Search for a group'
-
- expect(page).to have_text group_within_hierarchy.name
- expect(page).not_to have_text group_outside_hierarchy.name
- end
- end
-
- context 'when the invite members group modal is enabled' do
- it 'shows only groups within the hierarchy in search results' do
- visit group_group_members_path(group)
+ it 'shows only groups within the hierarchy in search results' do
+ visit group_group_members_path(group)
- click_on 'Invite a group'
- click_on 'Select a group'
+ click_on 'Invite a group'
+ click_on 'Select a group'
- expect(page).to have_text group_within_hierarchy.name
- expect(page).not_to have_text group_outside_hierarchy.name
- end
+ expect(page).to have_text group_within_hierarchy.name
+ expect(page).not_to have_text group_outside_hierarchy.name
end
end
end
- def add_group(id, role)
- page.click_link 'Invite group'
- page.within ".invite-group-form" do
- select2(id, from: "#shared_with_group_id")
- select(role, from: "shared_group_access")
- click_button "Invite"
- end
- end
-
def click_groups_tab
expect(page).to have_link 'Groups'
click_link "Groups"
diff --git a/spec/features/groups/members/manage_members_spec.rb b/spec/features/groups/members/manage_members_spec.rb
index e5dad5ee4be..533d2118b30 100644
--- a/spec/features/groups/members/manage_members_spec.rb
+++ b/spec/features/groups/members/manage_members_spec.rb
@@ -15,42 +15,18 @@ RSpec.describe 'Groups > Members > Manage members' do
sign_in(user1)
end
- shared_examples 'includes the correct Invite link' do |should_include, should_not_include|
- it 'includes either the form or the modal trigger', :aggregate_failures do
+ shared_examples 'includes the correct Invite link' do |should_include|
+ it 'includes the modal trigger', :aggregate_failures do
group.add_owner(user1)
visit group_group_members_path(group)
expect(page).to have_selector(should_include)
- expect(page).not_to have_selector(should_not_include)
end
end
- shared_examples 'does not include either invite modal or either invite form' do
- it 'does not include either of the invite members or invite group modal buttons', :aggregate_failures do
- expect(page).not_to have_selector '.js-invite-members-modal'
- expect(page).not_to have_selector '.js-invite-group-modal'
- end
-
- it 'does not include either of the invite users or invite group forms', :aggregate_failures do
- expect(page).not_to have_selector '.invite-users-form'
- expect(page).not_to have_selector '.invite-group-form'
- end
- end
-
- context 'when Invite Members modal is enabled' do
- it_behaves_like 'includes the correct Invite link', '.js-invite-members-trigger', '.invite-users-form'
- it_behaves_like 'includes the correct Invite link', '.js-invite-group-trigger', '.invite-group-form'
- end
-
- context 'when Invite Members modal is disabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- it_behaves_like 'includes the correct Invite link', '.invite-users-form', '.js-invite-members-trigger'
- it_behaves_like 'includes the correct Invite link', '.invite-group-form', '.js-invite-group-trigger'
- end
+ it_behaves_like 'includes the correct Invite link', '.js-invite-members-trigger'
+ it_behaves_like 'includes the correct Invite link', '.js-invite-group-trigger'
it 'update user to owner level', :js do
group.add_owner(user1)
@@ -106,33 +82,6 @@ RSpec.describe 'Groups > Members > Manage members' do
expect(page).to have_content('Invite "undisclosed_email@gitlab.com" by email')
end
- context 'when Invite Members modal is disabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- it 'do not disclose email addresses', :js do
- group.add_owner(user1)
- create(:user, email: 'undisclosed_email@gitlab.com', name: "Jane 'invisible' Doe")
-
- visit group_group_members_path(group)
-
- find('.select2-container').click
- select_input = find('.select2-input')
-
- select_input.send_keys('@gitlab.com')
- wait_for_requests
-
- expect(page).to have_content('No matches found')
-
- select_input.native.clear
- select_input.send_keys('undisclosed_email@gitlab.com')
- wait_for_requests
-
- expect(page).to have_content('Invite "undisclosed_email@gitlab.com" by email')
- end
- end
-
it 'remove user from group', :js do
group.add_owner(user1)
group.add_developer(user2)
@@ -205,30 +154,11 @@ RSpec.describe 'Groups > Members > Manage members' do
visit group_group_members_path(group)
end
- it_behaves_like 'does not include either invite modal or either invite form'
-
- it 'does not include a button on the members page list to manage or remove the existing member', :js, :aggregate_failures do
- page.within(second_row) do
- # Can not modify user2 role
- expect(page).not_to have_button 'Developer'
-
- # Can not remove user2
- expect(page).not_to have_selector 'button[title="Remove member"]'
- end
- end
- end
-
- context 'when user is a guest and the :invite_members_group_modal feature flag is disabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- group.add_guest(user1)
- group.add_developer(user2)
-
- visit group_group_members_path(group)
+ it 'does not include either of the invite members or invite group modal buttons', :aggregate_failures do
+ expect(page).not_to have_selector '.js-invite-members-modal'
+ expect(page).not_to have_selector '.js-invite-group-modal'
end
- it_behaves_like 'does not include either invite modal or either invite form'
-
it 'does not include a button on the members page list to manage or remove the existing member', :js, :aggregate_failures do
page.within(second_row) do
# Can not modify user2 role
diff --git a/spec/features/groups/navbar_spec.rb b/spec/features/groups/navbar_spec.rb
index c5d2f5e6733..e4b44d65438 100644
--- a/spec/features/groups/navbar_spec.rb
+++ b/spec/features/groups/navbar_spec.rb
@@ -18,6 +18,7 @@ RSpec.describe 'Group navbar' do
stub_feature_flags(customer_relations: false)
stub_config(dependency_proxy: { enabled: false })
stub_config(registry: { enabled: false })
+ stub_feature_flags(harbor_registry_integration: false)
stub_group_wikis(false)
group.add_maintainer(user)
sign_in(user)
@@ -59,6 +60,18 @@ RSpec.describe 'Group navbar' do
it_behaves_like 'verified navigation bar'
end
+ context 'when customer_relations feature and flag 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
+
+ it_behaves_like 'verified navigation bar'
+ end
+
context 'when dependency proxy is available' do
before do
stub_config(dependency_proxy: { enabled: true })
@@ -70,4 +83,16 @@ RSpec.describe 'Group navbar' do
it_behaves_like 'verified navigation bar'
end
+
+ context 'when harbor registry is available' do
+ before do
+ stub_feature_flags(harbor_registry_integration: true)
+
+ insert_harbor_registry_nav(_('Package Registry'))
+
+ visit group_path(group)
+ end
+
+ it_behaves_like 'verified navigation bar'
+ end
end
diff --git a/spec/features/groups/settings/ci_cd_spec.rb b/spec/features/groups/settings/ci_cd_spec.rb
index b059cd8da29..8851aeb6381 100644
--- a/spec/features/groups/settings/ci_cd_spec.rb
+++ b/spec/features/groups/settings/ci_cd_spec.rb
@@ -13,6 +13,24 @@ RSpec.describe 'Group CI/CD settings' do
sign_in(user)
end
+ describe 'new group runners view banner' do
+ it 'displays banner' do
+ visit group_settings_ci_cd_path(group)
+
+ expect(page).to have_content(s_('Runners|New group runners view'))
+ expect(page).to have_link(href: group_runners_path(group))
+ end
+
+ it 'does not display banner' do
+ stub_feature_flags(runner_list_group_view_vue_ui: false)
+
+ visit group_settings_ci_cd_path(group)
+
+ expect(page).not_to have_content(s_('Runners|New group runners view'))
+ expect(page).not_to have_link(href: group_runners_path(group))
+ end
+ end
+
describe 'runners registration token' do
let!(:token) { group.runners_token }
diff --git a/spec/features/groups/settings/repository_spec.rb b/spec/features/groups/settings/repository_spec.rb
index d95eaf3c92c..159deb2a4e3 100644
--- a/spec/features/groups/settings/repository_spec.rb
+++ b/spec/features/groups/settings/repository_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe 'Group Repository settings' do
end
end
- context 'Default initial branch name' do
+ context 'Default branch' do
before do
visit group_settings_repository_path(group)
end
@@ -37,8 +37,8 @@ RSpec.describe 'Group Repository settings' do
it 'renders the correct setting section content' do
within("#js-default-branch-name") do
- expect(page).to have_content("Default initial branch name")
- expect(page).to have_content("The default name for the initial branch of new repositories created in the group.")
+ expect(page).to have_content("Default branch")
+ expect(page).to have_content("Set the initial name and protections for the default branch of new repositories created in the group.")
end
end
end
diff --git a/spec/features/groups/settings/user_searches_in_settings_spec.rb b/spec/features/groups/settings/user_searches_in_settings_spec.rb
index abf56232aff..c7b7b25caa7 100644
--- a/spec/features/groups/settings/user_searches_in_settings_spec.rb
+++ b/spec/features/groups/settings/user_searches_in_settings_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe 'User searches group settings', :js do
visit group_settings_repository_path(group)
end
- it_behaves_like 'can search settings', 'Deploy tokens', 'Default initial branch name'
+ it_behaves_like 'can search settings', 'Deploy tokens', 'Default branch'
end
context 'in CI/CD page' do
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index 925bbc47cf6..08183badda1 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe 'Group' do
group = Group.find_by(name: 'test-group')
expect(group.visibility_level).to eq(Gitlab::VisibilityLevel::PUBLIC)
- expect(current_path).to eq(group_path(group))
+ expect(page).to have_current_path(group_path(group), ignore_query: true)
expect(page).to have_selector '.visibility-icon [data-testid="earth-icon"]'
end
end
@@ -51,7 +51,7 @@ RSpec.describe 'Group' do
fill_in 'Group URL', with: 'space group'
click_button 'Create group'
- expect(current_path).to eq(new_group_path)
+ expect(page).to have_current_path(new_group_path, ignore_query: true)
expect(page).to have_text('Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores.')
end
end
@@ -62,7 +62,7 @@ RSpec.describe 'Group' do
fill_in 'Group URL', with: 'atom_group.atom'
click_button 'Create group'
- expect(current_path).to eq(groups_path)
+ expect(page).to have_current_path(groups_path, ignore_query: true)
expect(page).to have_namespace_error_message
end
end
@@ -73,7 +73,7 @@ RSpec.describe 'Group' do
fill_in 'Group URL', with: 'git_group.git'
click_button 'Create group'
- expect(current_path).to eq(groups_path)
+ expect(page).to have_current_path(groups_path, ignore_query: true)
expect(page).to have_namespace_error_message
end
end
@@ -211,7 +211,7 @@ RSpec.describe 'Group' do
fill_in 'Group name', with: 'bar'
click_button 'Create group'
- expect(current_path).to eq(group_path('foo/bar'))
+ expect(page).to have_current_path(group_path('foo/bar'), ignore_query: true)
expect(page).to have_selector 'h1', text: 'bar'
end
end
@@ -237,7 +237,7 @@ RSpec.describe 'Group' do
fill_in 'Group name', with: 'bar'
click_button 'Create group'
- expect(current_path).to eq(group_path('foo/bar'))
+ expect(page).to have_current_path(group_path('foo/bar'), ignore_query: true)
expect(page).to have_selector 'h1', text: 'bar'
end
end
@@ -474,4 +474,69 @@ RSpec.describe 'Group' do
fill_in 'confirm_name_input', with: confirm_with
click_button 'Confirm'
end
+
+ describe 'storage_enforcement_banner', :js do
+ let_it_be(:group) { create(:group) }
+ let_it_be_with_refind(:user) { create(:user) }
+
+ before_all do
+ group.add_owner(user)
+ sign_in(user)
+ end
+
+ context 'with storage_enforcement_date set' do
+ let_it_be(:storage_enforcement_date) { Date.today + 30 }
+
+ before do
+ allow_next_found_instance_of(Group) do |g|
+ allow(g).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
+ end
+ end
+
+ it 'displays the banner in the group page' do
+ visit group_path(group)
+ expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ end
+
+ it 'does not display the banner in a paid group page' do
+ allow_next_found_instance_of(Group) do |g|
+ allow(g).to receive(:paid?).and_return(true)
+ end
+ visit group_path(group)
+ expect_page_not_to_have_storage_enforcement_banner
+ end
+
+ it 'does not display the banner if user has previously closed unless threshold has changed' do
+ visit group_path(group)
+ expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ find('.js-storage-enforcement-banner [data-testid="close-icon"]').click
+ page.refresh
+ expect_page_not_to_have_storage_enforcement_banner
+
+ storage_enforcement_date = Date.today + 13
+ allow_next_found_instance_of(Group) do |g|
+ allow(g).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
+ end
+ page.refresh
+ expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ end
+ end
+
+ context 'with storage_enforcement_date not set' do
+ # This test should break and be rewritten after the implementation of the storage_enforcement_date
+ # TBD: https://gitlab.com/gitlab-org/gitlab/-/issues/350632
+ it 'does not display the banner in the group page' do
+ visit group_path(group)
+ expect_page_not_to_have_storage_enforcement_banner
+ end
+ end
+ end
+
+ def expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ expect(page).to have_text "From #{storage_enforcement_date} storage limits will apply to this namespace"
+ end
+
+ def expect_page_not_to_have_storage_enforcement_banner
+ expect(page).not_to have_text "storage limits will apply to this namespace"
+ end
end
diff --git a/spec/features/incidents/incident_details_spec.rb b/spec/features/incidents/incident_details_spec.rb
index b704a0515c8..dad3dfd3440 100644
--- a/spec/features/incidents/incident_details_spec.rb
+++ b/spec/features/incidents/incident_details_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe 'Incident details', :js do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user) }
let_it_be(:incident) { create(:incident, project: project, author: developer, description: 'description') }
+ let_it_be(:escalation_status) { create(:incident_management_issuable_escalation_status, issue: incident) }
before_all do
project.add_developer(developer)
@@ -21,7 +22,7 @@ RSpec.describe 'Incident details', :js do
context 'when a developer+ displays the incident' do
it 'shows the incident' do
page.within('.issuable-details') do
- expect(find('h2')).to have_content(incident.title)
+ expect(find('h1')).to have_content(incident.title)
end
end
@@ -33,7 +34,7 @@ RSpec.describe 'Incident details', :js do
page.within('.issuable-details') do
incident_tabs = find('[data-testid="incident-tabs"]')
- expect(find('h2')).to have_content(incident.title)
+ expect(find('h1')).to have_content(incident.title)
expect(incident_tabs).to have_content('Summary')
expect(incident_tabs).to have_content(incident.description)
end
@@ -46,6 +47,42 @@ RSpec.describe 'Incident details', :js do
expect(page).to have_selector('.right-sidebar[data-issuable-type="issue"]')
expect(sidebar).to have_selector('.incident-severity')
expect(sidebar).to have_selector('.milestone')
+ expect(sidebar).to have_selector('[data-testid="escalation_status_container"]')
+ end
+ end
+
+ context 'escalation status' do
+ let(:sidebar) { page.find('.right-sidebar') }
+ let(:widget) { sidebar.find('[data-testid="escalation_status_container"]') }
+ let(:expected_dropdown_options) { escalation_status.class::STATUSES.keys.take(3).map { |key| key.to_s.titleize } }
+
+ it 'has an interactable escalation status widget' do
+ expect(current_status).to have_text(escalation_status.status_name.to_s.titleize)
+
+ # list the available statuses
+ widget.find('[data-testid="edit-button"]').click
+ expect(dropdown_options.map(&:text)).to eq(expected_dropdown_options)
+ expect(widget).not_to have_selector('#escalation-status-help')
+
+ # update the status
+ select_resolved(dropdown_options)
+ expect(current_status).to have_text('Resolved')
+ expect(escalation_status.reload).to be_resolved
+ end
+
+ private
+
+ def dropdown_options
+ widget.all('[data-testid="status-dropdown-item"]', count: 3)
+ end
+
+ def select_resolved(options)
+ options.last.click
+ wait_for_requests
+ end
+
+ def current_status
+ widget.find('[data-testid="collapsed-content"]')
end
end
end
diff --git a/spec/features/incidents/incidents_list_spec.rb b/spec/features/incidents/incidents_list_spec.rb
index c65c83b2804..789cc89e083 100644
--- a/spec/features/incidents/incidents_list_spec.rb
+++ b/spec/features/incidents/incidents_list_spec.rb
@@ -34,5 +34,28 @@ RSpec.describe 'Incident Management index', :js do
it 'alert page title' do
expect(page).to have_content('Incidents')
end
+
+ it 'has expected columns' do
+ table = page.find('.gl-table')
+
+ expect(table).to have_content('Severity')
+ expect(table).to have_content('Incident')
+ expect(table).to have_content('Status')
+ 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/incidents/user_views_incident_spec.rb b/spec/features/incidents/user_views_incident_spec.rb
index fe54f7708c9..a669966502e 100644
--- a/spec/features/incidents/user_views_incident_spec.rb
+++ b/spec/features/incidents/user_views_incident_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe "User views incident" do
it 'shows the merge request and incident actions', :js, :aggregate_failures do
click_button 'Incident actions'
- expect(page).to have_link('New incident', href: new_project_issue_path(project, { issuable_template: 'incident', issue: { issue_type: 'incident', description: "Related to \##{incident.iid}.\n\n" } }))
+ expect(page).to have_link('New related incident', href: new_project_issue_path(project, { issuable_template: 'incident', issue: { issue_type: 'incident' }, add_related_issue: incident.iid }))
expect(page).to have_button('Create merge request')
expect(page).to have_button('Close incident')
end
@@ -40,10 +40,8 @@ RSpec.describe "User views incident" do
visit(project_issues_incident_path(project, incident))
end
- it 'does not show the incident action', :js, :aggregate_failures do
- click_button 'Incident actions'
-
- expect(page).not_to have_link('New incident')
+ it 'does not show the incident actions', :js, :aggregate_failures do
+ expect(page).not_to have_button('Incident actions')
end
end
end
diff --git a/spec/features/invites_spec.rb b/spec/features/invites_spec.rb
index 9cb9416e7a0..965e97baadd 100644
--- a/spec/features/invites_spec.rb
+++ b/spec/features/invites_spec.rb
@@ -57,7 +57,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
it 'renders sign up page with sign up notice' do
- expect(current_path).to eq(new_user_registration_path)
+ expect(page).to have_current_path(new_user_registration_path, ignore_query: true)
expect(page).to have_content('To accept this invitation, create an account or sign in')
end
@@ -85,7 +85,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
fill_in_sign_in_form(user)
- expect(current_path).to eq(activity_group_path(group))
+ expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
end
end
@@ -98,7 +98,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
it 'shows message user already a member' do
- expect(current_path).to eq(invite_path(group_invite.raw_invite_token))
+ expect(page).to have_current_path(invite_path(group_invite.raw_invite_token), ignore_query: true)
expect(page).to have_link(user.name, href: user_path(user))
expect(page).to have_content('You are already a member of this group.')
end
@@ -127,7 +127,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
it 'declines application and redirects to dashboard' do
- expect(current_path).to eq(dashboard_projects_path)
+ expect(page).to have_current_path(dashboard_projects_path, ignore_query: true)
expect(page).to have_content('You have declined the invitation to join group Owned.')
expect { group_invite.reload }.to raise_error ActiveRecord::RecordNotFound
end
@@ -139,7 +139,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
it 'declines application and redirects to sign in page' do
- expect(current_path).to eq(decline_invite_path(group_invite.raw_invite_token))
+ expect(page).to have_current_path(decline_invite_path(group_invite.raw_invite_token), ignore_query: true)
expect(page).not_to have_content('You have declined the invitation to join')
expect(page).to have_content('You successfully declined the invitation')
expect { group_invite.reload }.to raise_error ActiveRecord::RecordNotFound
@@ -174,7 +174,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
it 'does not sign the user in' do
fill_in_sign_up_form(new_user)
- expect(current_path).to eq(new_user_session_path)
+ expect(page).to have_current_path(new_user_session_path, ignore_query: true)
expect(page).to have_content('You have signed up successfully. However, we could not sign you in because your account is awaiting approval from your GitLab administrator')
end
end
@@ -186,7 +186,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
fill_in_sign_up_form(new_user)
fill_in_welcome_form
- expect(current_path).to eq(activity_group_path(group))
+ expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
expect(page).to have_content('You have been granted Owner access to group Owned.')
end
@@ -197,7 +197,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
fill_in_sign_up_form(new_user)
fill_in_welcome_form
- expect(current_path).to eq(activity_group_path(group))
+ expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
end
end
end
@@ -209,7 +209,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
it 'fails sign up and redirects back to sign up', :aggregate_failures do
expect { fill_in_sign_up_form(new_user) }.not_to change { User.count }
expect(page).to have_content('prohibited this user from being saved')
- expect(current_path).to eq(user_registration_path)
+ expect(page).to have_current_path(user_registration_path, ignore_query: true)
end
end
@@ -230,7 +230,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
fill_in_sign_up_form(new_user)
fill_in_welcome_form
- expect(current_path).to eq(activity_group_path(group))
+ expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
end
context 'the user sign-up using a different email address' do
@@ -248,7 +248,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
fill_in_sign_in_form(new_user)
fill_in_welcome_form
- expect(current_path).to eq(activity_group_path(group))
+ expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
end
end
@@ -262,7 +262,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
fill_in_sign_up_form(new_user)
fill_in_welcome_form
- expect(current_path).to eq(activity_group_path(group))
+ expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
end
end
end
@@ -273,11 +273,11 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
it 'lands on sign up page and then registers' do
visit invite_path(group_invite.raw_invite_token)
- expect(current_path).to eq(new_user_registration_path)
+ expect(page).to have_current_path(new_user_registration_path, ignore_query: true)
fill_in_sign_up_form(new_user, 'Register')
- expect(current_path).to eq(users_sign_up_welcome_path)
+ expect(page).to have_current_path(users_sign_up_welcome_path, ignore_query: true)
end
end
@@ -285,7 +285,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
it 'declines application and shows a decline page' do
visit decline_invite_path(group_invite.raw_invite_token)
- expect(current_path).to eq(decline_invite_path(group_invite.raw_invite_token))
+ expect(page).to have_current_path(decline_invite_path(group_invite.raw_invite_token), ignore_query: true)
expect(page).to have_content('You successfully declined the invitation')
expect { group_invite.reload }.to raise_error ActiveRecord::RecordNotFound
end
diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
index e873ebb21c4..3ba2f7e788d 100644
--- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
@@ -12,14 +12,14 @@ RSpec.describe 'Dropdown assignee', :js do
let(:js_dropdown_assignee) { '#js-dropdown-assignee' }
let(:filter_dropdown) { find("#{js_dropdown_assignee} .filter-dropdown") }
- before do
- project.add_maintainer(user)
- sign_in(user)
+ describe 'behavior' do
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
- visit project_issues_path(project)
- end
+ visit project_issues_path(project)
+ end
- describe 'behavior' do
it 'loads all the assignees when opened' do
input_filtered_search('assignee:=', submit: false, extra_space: false)
@@ -35,6 +35,11 @@ RSpec.describe 'Dropdown assignee', :js do
describe 'selecting from dropdown without Ajax call' do
before do
+ project.add_maintainer(user)
+ sign_in(user)
+
+ visit project_issues_path(project)
+
Gitlab::Testing::RequestBlockerMiddleware.block_requests!
input_filtered_search('assignee:=', submit: false, extra_space: false)
end
@@ -51,4 +56,60 @@ RSpec.describe 'Dropdown assignee', :js do
expect_filtered_search_input_empty
end
end
+
+ context 'assignee suggestions' do
+ let!(:group) { create(:group) }
+ let!(:group_project) { create(:project, namespace: group) }
+ let!(:group_user) { create(:user) }
+
+ let!(:subgroup) { create(:group, parent: group) }
+ let!(:subgroup_project) { create(:project, namespace: subgroup) }
+ let!(:subgroup_project_issue) { create(:issue, project: subgroup_project) }
+ let!(:subgroup_user) { create(:user) }
+
+ let!(:subsubgroup) { create(:group, parent: subgroup) }
+ let!(:subsubgroup_project) { create(:project, namespace: subsubgroup) }
+ let!(:subsubgroup_user) { create(:user) }
+
+ let!(:invited_to_group_group) { create(:group) }
+ let!(:invited_to_group_group_user) { create(:user) }
+
+ let!(:invited_to_project_group) { create(:group) }
+ let!(:invited_to_project_group_user) { create(:user) }
+
+ before do
+ group.add_developer(group_user)
+ subgroup.add_developer(subgroup_user)
+ subsubgroup.add_developer(subsubgroup_user)
+ invited_to_group_group.add_developer(invited_to_group_group_user)
+ invited_to_project_group.add_developer(invited_to_project_group_user)
+
+ create(:group_group_link, shared_group: subgroup, shared_with_group: invited_to_group_group)
+ create(:project_group_link, project: subgroup_project, group: invited_to_project_group)
+
+ sign_in(subgroup_user)
+ end
+
+ it 'shows inherited, direct, and invited group members but not descendent members', :aggregate_failures do
+ visit issues_group_path(subgroup)
+
+ input_filtered_search('assignee:=', submit: false, extra_space: false)
+
+ expect(page).to have_text group_user.name
+ expect(page).to have_text subgroup_user.name
+ expect(page).to have_text invited_to_group_group_user.name
+ expect(page).not_to have_text subsubgroup_user.name
+ expect(page).not_to have_text invited_to_project_group_user.name
+
+ visit project_issues_path(subgroup_project)
+
+ input_filtered_search('assignee:=', submit: false, extra_space: false)
+
+ expect(page).to have_text group_user.name
+ expect(page).to have_text subgroup_user.name
+ expect(page).to have_text invited_to_project_group_user.name
+ expect(page).not_to have_text subsubgroup_user.name
+ expect(page).not_to have_text invited_to_group_group_user.name
+ end
+ end
end
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index edf3df7c16e..1375384d1aa 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -497,6 +497,8 @@ RSpec.describe 'Filter issues', :js do
end
it 'filters issues by searched text containing special characters' do
+ stub_feature_flags(issues_full_text_search: false)
+
issue = create(:issue, project: project, author: user, title: "issue with !@\#{$%^&*()-+")
search = '!@#{$%^&*()-+'
@@ -514,6 +516,14 @@ RSpec.describe 'Filter issues', :js do
expect_no_issues_list
expect_filtered_search_input(search)
end
+
+ it 'filters issues by issue reference' do
+ search = '#1'
+ input_filtered_search(search)
+
+ expect_issues_list_count(1)
+ expect_filtered_search_input(search)
+ end
end
context 'searched text with other filters' do
diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb
index b26f65316c5..0700423983f 100644
--- a/spec/features/issues/form_spec.rb
+++ b/spec/features/issues/form_spec.rb
@@ -5,19 +5,22 @@ require 'spec_helper'
RSpec.describe 'New/edit issue', :js do
include ActionView::Helpers::JavaScriptHelper
- let_it_be(:project) { create(:project) }
+ let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
let_it_be(:user2) { create(:user) }
+ let_it_be(:guest) { create(:user) }
let_it_be(:milestone) { create(:milestone, project: project) }
let_it_be(:label) { create(:label, project: project) }
let_it_be(:label2) { create(:label, project: project) }
let_it_be(:issue) { create(:issue, project: project, assignees: [user], milestone: milestone) }
+ let_it_be(:confidential_issue) { create(:issue, project: project, assignees: [user], milestone: milestone, confidential: true) }
let(:current_user) { user }
before_all do
project.add_maintainer(user)
project.add_maintainer(user2)
+ project.add_guest(guest)
end
before do
@@ -184,6 +187,14 @@ RSpec.describe 'New/edit issue', :js do
end
end
+ it 'displays an error message when submitting an invalid form' do
+ click_button 'Create issue'
+
+ page.within('[data-testid="issue-title-input-field"]') do
+ expect(page).to have_text(_('This field is required.'))
+ end
+ end
+
it 'correctly updates the dropdown toggle when removing a label' do
click_button 'Labels'
@@ -310,6 +321,108 @@ RSpec.describe 'New/edit issue', :js do
end
end
+ describe 'new issue with query parameters' do
+ before do
+ project.repository.create_file(
+ current_user,
+ '.gitlab/issue_templates/test_template.md',
+ 'description from template',
+ message: 'Add test_template.md',
+ branch_name: project.default_branch_or_main
+ )
+ end
+
+ after do
+ project.repository.delete_file(
+ current_user,
+ '.gitlab/issue_templates/test_template.md',
+ message: 'Remove test_template.md',
+ branch_name: project.default_branch_or_main
+ )
+ end
+
+ it 'leaves the description blank if no query parameters are specified' do
+ visit new_project_issue_path(project)
+
+ expect(find('#issue_description').value).to be_empty
+ end
+
+ it 'fills the description from the issue[description] query parameter' do
+ visit new_project_issue_path(project, issue: { description: 'description from query parameter' })
+
+ expect(find('#issue_description').value).to match('description from query parameter')
+ end
+
+ it 'fills the description from the issuable_template query parameter' do
+ visit new_project_issue_path(project, issuable_template: 'test_template')
+ wait_for_requests
+
+ expect(find('#issue_description').value).to match('description from template')
+ end
+
+ it 'fills the description from the issuable_template and issue[description] query parameters' do
+ visit new_project_issue_path(project, issuable_template: 'test_template', issue: { description: 'description from query parameter' })
+ wait_for_requests
+
+ expect(find('#issue_description').value).to match('description from template\ndescription from query parameter')
+ end
+ end
+
+ describe 'new issue from related issue' do
+ it 'does not offer to link the new issue to any other issues if the URL parameter is absent' do
+ visit new_project_issue_path(project)
+ expect(page).not_to have_selector '#add_related_issue'
+ expect(page).not_to have_text "Relate to"
+ end
+
+ context 'guest' do
+ let(:current_user) { guest }
+
+ it 'does not offer to link the new issue to an issue that the user does not have access to' do
+ visit new_project_issue_path(project, { add_related_issue: confidential_issue.iid })
+ expect(page).not_to have_selector '#add_related_issue'
+ expect(page).not_to have_text "Relate to"
+ end
+ end
+
+ it 'links the new issue and the issue of origin' do
+ visit new_project_issue_path(project, { add_related_issue: issue.iid })
+ expect(page).to have_selector '#add_related_issue'
+ expect(page).to have_text "Relate to issue \##{issue.iid}"
+ expect(page).to have_text 'Adds this issue as related to the issue it was created from'
+ fill_in 'issue_title', with: 'title'
+ click_button 'Create issue'
+ page.within '#related-issues' do
+ expect(page).to have_text "\##{issue.iid}"
+ end
+ end
+
+ it 'links the new incident and the incident of origin' do
+ incident = create(:incident, project: project)
+ visit new_project_issue_path(project, { add_related_issue: incident.iid })
+ expect(page).to have_selector '#add_related_issue'
+ expect(page).to have_text "Relate to incident \##{incident.iid}"
+ expect(page).to have_text 'Adds this incident as related to the incident it was created from'
+ fill_in 'issue_title', with: 'title'
+ click_button 'Create issue'
+ page.within '#related-issues' do
+ expect(page).to have_text "\##{incident.iid}"
+ end
+ end
+
+ it 'does not link the new issue to any other issues if the checkbox is not checked' do
+ visit new_project_issue_path(project, { add_related_issue: issue.iid })
+ expect(page).to have_selector '#add_related_issue'
+ expect(page).to have_text "Relate to issue \##{issue.iid}"
+ uncheck "Relate to issue \##{issue.iid}"
+ fill_in 'issue_title', with: 'title'
+ click_button 'Create issue'
+ page.within '#related-issues' do
+ expect(page).not_to have_text "\##{issue.iid}"
+ end
+ end
+ end
+
describe 'edit issue' do
before do
visit edit_project_issue_path(project, issue)
diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb
index b4d1b0aeab9..6f4a13c5fad 100644
--- a/spec/features/issues/gfm_autocomplete_spec.rb
+++ b/spec/features/issues/gfm_autocomplete_spec.rb
@@ -111,6 +111,20 @@ RSpec.describe 'GFM autocomplete', :js do
fill_in 'Comment', with: "test\n\n@"
expect(find_autocomplete_menu).to be_visible
end
+
+ it 'does not open label autocomplete menu after strikethrough', :aggregate_failures do
+ fill_in 'Comment', with: "~~"
+ expect(page).not_to have_css('.atwho-view')
+
+ fill_in 'Comment', with: "~~gone~~"
+ expect(page).not_to have_css('.atwho-view')
+
+ fill_in 'Comment', with: "~"
+ expect(find_autocomplete_menu).to be_visible
+
+ fill_in 'Comment', with: "test\n\n~"
+ expect(find_autocomplete_menu).to be_visible
+ end
end
context 'xss checks' do
@@ -406,6 +420,14 @@ RSpec.describe 'GFM autocomplete', :js do
end
end
end
+
+ context 'when typing enter for autocomplete in a markdown list' do
+ it 'does not create a new list item' do
+ fill_in 'Comment', with: "- @#{user.username}\n"
+
+ expect(find_field('Comment').value).to eq "- @#{user.username}\n"
+ end
+ end
end
private
diff --git a/spec/features/issues/incident_issue_spec.rb b/spec/features/issues/incident_issue_spec.rb
index 3033a138551..2956ddede2e 100644
--- a/spec/features/issues/incident_issue_spec.rb
+++ b/spec/features/issues/incident_issue_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe 'Incident Detail', :js do
incident_tabs = find('[data-testid="incident-tabs"]')
aggregate_failures 'shows title and Summary tab' do
- expect(find('h2')).to have_content(incident.title)
+ expect(find('h1')).to have_content(incident.title)
expect(incident_tabs).to have_content('Summary')
expect(incident_tabs).to have_content(incident.description)
end
diff --git a/spec/features/issues/issue_detail_spec.rb b/spec/features/issues/issue_detail_spec.rb
index b37c8e9d1cf..88709d66887 100644
--- a/spec/features/issues/issue_detail_spec.rb
+++ b/spec/features/issues/issue_detail_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe 'Issue Detail', :js do
it 'shows the issue' do
page.within('.issuable-details') do
- expect(find('h2')).to have_content(issue.title)
+ expect(find('h1')).to have_content(issue.title)
end
end
end
@@ -85,7 +85,7 @@ RSpec.describe 'Issue Detail', :js do
it 'shows the issue' do
page.within('.issuable-details') do
- expect(find('h2')).to have_content(issue.reload.title)
+ expect(find('h1')).to have_content(issue.reload.title)
end
end
end
diff --git a/spec/features/issues/issue_header_spec.rb b/spec/features/issues/issue_header_spec.rb
index 3e27ce81860..165015013dd 100644
--- a/spec/features/issues/issue_header_spec.rb
+++ b/spec/features/issues/issue_header_spec.rb
@@ -25,8 +25,8 @@ RSpec.describe 'issue header', :js do
click_button 'Issue actions'
end
- it 'shows the "New issue", "Report abuse", and "Delete issue" items', :aggregate_failures do
- expect(page).to have_link 'New issue'
+ it 'shows the "New related issue", "Report abuse", and "Delete issue" items', :aggregate_failures do
+ expect(page).to have_link 'New related issue'
expect(page).to have_link 'Report abuse'
expect(page).to have_button 'Delete issue'
expect(page).not_to have_link 'Submit as spam'
@@ -114,8 +114,8 @@ RSpec.describe 'issue header', :js do
click_button 'Issue actions'
end
- it 'only shows the "New issue" and "Report abuse" items', :aggregate_failures do
- expect(page).to have_link 'New issue'
+ it 'only shows the "New related issue" and "Report abuse" items', :aggregate_failures do
+ expect(page).to have_link 'New related issue'
expect(page).to have_link 'Report abuse'
expect(page).not_to have_link 'Submit as spam'
expect(page).not_to have_button 'Delete issue'
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index 868946814c3..aaa478378a9 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -106,6 +106,7 @@ RSpec.describe 'Issue Sidebar' do
end
context 'when GraphQL assignees widget feature flag is enabled' do
+ # TODO: Move to shared examples when feature flag is removed: https://gitlab.com/gitlab-org/gitlab/-/issues/328185
context 'when a privileged user can invite' do
it 'shows a link for inviting members and launches invite modal' do
project.add_maintainer(user)
@@ -236,6 +237,12 @@ RSpec.describe 'Issue Sidebar' do
it_behaves_like 'labels sidebar widget'
end
+ context 'escalation status', :js do
+ it 'is not available for default issue type' do
+ expect(page).not_to have_selector('.block.escalation-status')
+ end
+ end
+
context 'interacting with collapsed sidebar', :js do
collapsed_sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed'
expanded_sidebar_selector = 'aside.right-sidebar.right-sidebar-expanded'
diff --git a/spec/features/issues/move_spec.rb b/spec/features/issues/move_spec.rb
index ee2fbf0865e..054b7b3855b 100644
--- a/spec/features/issues/move_spec.rb
+++ b/spec/features/issues/move_spec.rb
@@ -50,7 +50,7 @@ RSpec.describe 'issue move to another project' do
expect(page).to have_content("Text with #{cross_reference}#{mr.to_reference}")
expect(page).to have_content("moved from #{cross_reference}#{issue.to_reference}")
expect(page).to have_content(issue.title)
- expect(page.current_path).to include project_path(new_project)
+ expect(page).to have_current_path(%r(#{project_path(new_project)}))
end
it 'searching project dropdown', :js do
diff --git a/spec/features/issues/spam_akismet_issue_creation_spec.rb b/spec/features/issues/spam_akismet_issue_creation_spec.rb
new file mode 100644
index 00000000000..4cc4c4cf607
--- /dev/null
+++ b/spec/features/issues/spam_akismet_issue_creation_spec.rb
@@ -0,0 +1,178 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Spam detection on issue creation', :js do
+ include StubENV
+
+ let(:project) { create(:project, :public) }
+ let(:user) { create(:user) }
+
+ include_context 'includes Spam constants'
+
+ before do
+ stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
+
+ Gitlab::CurrentSettings.update!(
+ akismet_enabled: true,
+ akismet_api_key: 'testkey',
+ spam_check_api_key: 'testkey',
+ recaptcha_enabled: true,
+ recaptcha_site_key: 'test site key',
+ recaptcha_private_key: 'test private key'
+ )
+
+ project.add_maintainer(user)
+ sign_in(user)
+ visit new_project_issue_path(project)
+
+ fill_in 'issue_title', with: 'issue title'
+ fill_in 'issue_description', with: 'issue description'
+ end
+
+ shared_examples 'disallows issue creation' do
+ it 'disallows issue creation' do
+ click_button 'Create issue'
+
+ expect(page).to have_content('discarded')
+ expect(page).not_to have_css('.recaptcha')
+ expect(page).not_to have_content('issue title')
+ end
+ end
+
+ shared_examples 'allows issue creation with CAPTCHA' do
+ it 'allows issue creation' do
+ click_button 'Create issue'
+
+ # it is impossible to test reCAPTCHA automatically and there is no possibility to fill in recaptcha
+ # reCAPTCHA verification is skipped in test environment and it always returns true
+ expect(page).not_to have_content('issue title')
+ expect(page).to have_css('.recaptcha')
+
+ click_button 'Create issue'
+
+ expect(page.find('.issue-details h1.title')).to have_content('issue title')
+ expect(page.find('.issue-details .description')).to have_content('issue description')
+ end
+ end
+
+ shared_examples 'allows issue creation without CAPTCHA' do
+ it 'allows issue creation without need to solve CAPTCHA' do
+ click_button 'Create issue'
+
+ expect(page).not_to have_css('.recaptcha')
+ expect(page.find('.issue-details h1.title')).to have_content('issue title')
+ expect(page.find('.issue-details .description')).to have_content('issue description')
+ end
+ end
+
+ shared_examples 'creates a spam_log record' do
+ it 'creates a spam_log record' do
+ expect { click_button 'Create issue' }
+ .to log_spam(title: 'issue title', description: 'issue description', user_id: user.id, noteable_type: 'Issue')
+ end
+ end
+
+ shared_examples 'does not create a spam_log record' do
+ it 'does not creates a spam_log record' do
+ expect { click_button 'Create issue' }
+ .not_to log_spam(title: 'issue title', description: 'issue description', user_id: user.id, noteable_type: 'Issue')
+ end
+ end
+
+ shared_context 'when spammable is identified as possible spam' do
+ before do
+ allow_next_instance_of(Spam::AkismetService) do |akismet_service|
+ allow(akismet_service).to receive(:spam?).and_return(true)
+ end
+ end
+ end
+
+ shared_context 'when spammable is not identified as possible spam' do
+ before do
+ allow_next_instance_of(Spam::AkismetService) do |akismet_service|
+ allow(akismet_service).to receive(:spam?).and_return(false)
+ end
+ end
+ end
+
+ shared_context 'when CAPTCHA is enabled' do
+ before do
+ stub_application_setting(recaptcha_enabled: true)
+ end
+ end
+
+ shared_context 'when CAPTCHA is not enabled' do
+ before do
+ stub_application_setting(recaptcha_enabled: false)
+ end
+ end
+
+ shared_context 'when allow_possible_spam feature flag is true' do
+ before do
+ stub_feature_flags(allow_possible_spam: true)
+ end
+ end
+
+ shared_context 'when allow_possible_spam feature flag is false' do
+ before do
+ stub_feature_flags(allow_possible_spam: false)
+ end
+ end
+
+ describe 'spam handling' do
+ # verdict, spam_flagged, captcha_enabled, allow_possible_spam_flag, creates_spam_log
+ # TODO: Add example for BLOCK_USER verdict when we add support for testing SpamCheck - see https://gitlab.com/groups/gitlab-org/-/epics/5527#lacking-coverage-for-spamcheck-vs-akismet
+ # DISALLOW, true, false, false, true
+ # CONDITIONAL_ALLOW, true, true, false, true
+ # OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM, true, true, true, true
+ # OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM, true, false, true, true
+ # ALLOW, false, true, false, false
+ # TODO: Add example for NOOP verdict when we add support for testing SpamCheck - see https://gitlab.com/groups/gitlab-org/-/epics/5527#lacking-coverage-for-spamcheck-vs-akismet
+
+ context 'DISALLOW: spam_flagged=true, captcha_enabled=true, allow_possible_spam=true' do
+ include_context 'when spammable is identified as possible spam'
+ include_context 'when CAPTCHA is enabled'
+ include_context 'when allow_possible_spam feature flag is true'
+
+ it_behaves_like 'allows issue creation without CAPTCHA'
+ it_behaves_like 'creates a spam_log record'
+ end
+
+ context 'CONDITIONAL_ALLOW: spam_flagged=true, captcha_enabled=true, allow_possible_spam=false' do
+ include_context 'when spammable is identified as possible spam'
+ include_context 'when CAPTCHA is enabled'
+ include_context 'when allow_possible_spam feature flag is false'
+
+ it_behaves_like 'allows issue creation with CAPTCHA'
+ it_behaves_like 'creates a spam_log record'
+ end
+
+ context 'OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM: spam_flagged=true, captcha_enabled=true, allow_possible_spam=true' do
+ include_context 'when spammable is identified as possible spam'
+ include_context 'when CAPTCHA is enabled'
+ include_context 'when allow_possible_spam feature flag is true'
+
+ it_behaves_like 'allows issue creation without CAPTCHA'
+ it_behaves_like 'creates a spam_log record'
+ end
+
+ context 'OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM: spam_flagged=true, captcha_enabled=false, allow_possible_spam=true' do
+ include_context 'when spammable is identified as possible spam'
+ include_context 'when CAPTCHA is not enabled'
+ include_context 'when allow_possible_spam feature flag is true'
+
+ it_behaves_like 'allows issue creation without CAPTCHA'
+ it_behaves_like 'creates a spam_log record'
+ end
+
+ context 'ALLOW: spam_flagged=false, captcha_enabled=true, allow_possible_spam=false' do
+ include_context 'when spammable is not identified as possible spam'
+ include_context 'when CAPTCHA is not enabled'
+ include_context 'when allow_possible_spam feature flag is false'
+
+ it_behaves_like 'allows issue creation without CAPTCHA'
+ it_behaves_like 'does not create a spam_log record'
+ end
+ end
+end
diff --git a/spec/features/issues/spam_issues_spec.rb b/spec/features/issues/spam_issues_spec.rb
deleted file mode 100644
index 70d7deadec3..00000000000
--- a/spec/features/issues/spam_issues_spec.rb
+++ /dev/null
@@ -1,188 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'New issue', :js do
- include StubENV
-
- let(:project) { create(:project, :public) }
- let(:user) { create(:user)}
-
- before do
- stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
-
- Gitlab::CurrentSettings.update!(
- akismet_enabled: true,
- akismet_api_key: 'testkey',
- spam_check_api_key: 'testkey',
- recaptcha_enabled: true,
- recaptcha_site_key: 'test site key',
- recaptcha_private_key: 'test private key'
- )
-
- project.add_maintainer(user)
- sign_in(user)
- end
-
- context 'when SpamVerdictService disallows' do
- include_context 'includes Spam constants'
-
- before do
- allow_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- allow(verdict_service).to receive(:execute).and_return(DISALLOW)
- end
-
- visit new_project_issue_path(project)
- end
-
- context 'when allow_possible_spam feature flag is false' do
- before do
- stub_feature_flags(allow_possible_spam: false)
-
- fill_in 'issue_title', with: 'issue title'
- fill_in 'issue_description', with: 'issue description'
- end
-
- it 'rejects issue creation' do
- click_button 'Create issue'
-
- expect(page).to have_content('discarded')
- expect(page).not_to have_content('potential spam')
- expect(page).not_to have_content('issue title')
- end
-
- it 'creates a spam log record' do
- expect { click_button 'Create issue' }
- .to log_spam(title: 'issue title', description: 'issue description', user_id: user.id, noteable_type: 'Issue')
- end
- end
-
- context 'when allow_possible_spam feature flag is true' do
- before do
- fill_in 'issue_title', with: 'issue title'
- fill_in 'issue_description', with: 'issue description'
- end
-
- it 'allows issue creation' do
- click_button 'Create issue'
-
- expect(page.find('.issue-details h2.title')).to have_content('issue title')
- expect(page.find('.issue-details .description')).to have_content('issue description')
- end
-
- it 'creates a spam log record' do
- expect { click_button 'Create issue' }
- .to log_spam(title: 'issue title', description: 'issue description', user_id: user.id, noteable_type: 'Issue')
- end
- end
- end
-
- context 'when SpamVerdictService requires recaptcha' do
- include_context 'includes Spam constants'
-
- before do
- allow_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- allow(verdict_service).to receive(:execute).and_return(CONDITIONAL_ALLOW)
- end
-
- visit new_project_issue_path(project)
- end
-
- context 'when recaptcha is enabled' do
- before do
- stub_application_setting(recaptcha_enabled: true)
- end
-
- context 'when allow_possible_spam feature flag is false' do
- before do
- stub_feature_flags(allow_possible_spam: false)
- end
-
- it 'creates an issue after solving reCaptcha' do
- fill_in 'issue_title', with: 'issue title'
- fill_in 'issue_description', with: 'issue description'
-
- click_button 'Create issue'
-
- # it is impossible to test reCAPTCHA automatically and there is no possibility to fill in recaptcha
- # reCAPTCHA verification is skipped in test environment and it always returns true
- expect(page).not_to have_content('issue title')
- expect(page).to have_css('.recaptcha')
-
- click_button 'Create issue'
-
- expect(page.find('.issue-details h2.title')).to have_content('issue title')
- expect(page.find('.issue-details .description')).to have_content('issue description')
- end
- end
-
- context 'when allow_possible_spam feature flag is true' do
- before do
- fill_in 'issue_title', with: 'issue title'
- fill_in 'issue_description', with: 'issue description'
- end
-
- it 'creates an issue without a need to solve reCAPTCHA' do
- click_button 'Create issue'
-
- expect(page).not_to have_css('.recaptcha')
- expect(page.find('.issue-details h2.title')).to have_content('issue title')
- expect(page.find('.issue-details .description')).to have_content('issue description')
- end
-
- it 'creates a spam log record' do
- expect { click_button 'Create issue' }
- .to log_spam(title: 'issue title', description: 'issue description', user_id: user.id, noteable_type: 'Issue')
- end
- end
- end
-
- context 'when reCAPTCHA is not enabled' do
- before do
- stub_application_setting(recaptcha_enabled: false)
- end
-
- context 'when allow_possible_spam feature flag is true' do
- before do
- fill_in 'issue_title', with: 'issue title'
- fill_in 'issue_description', with: 'issue description'
- end
-
- it 'creates an issue without a need to solve reCaptcha' do
- click_button 'Create issue'
-
- expect(page).not_to have_css('.recaptcha')
- expect(page.find('.issue-details h2.title')).to have_content('issue title')
- expect(page.find('.issue-details .description')).to have_content('issue description')
- end
-
- it 'creates a spam log record' do
- expect { click_button 'Create issue' }
- .to log_spam(title: 'issue title', description: 'issue description', user_id: user.id, noteable_type: 'Issue')
- end
- end
- end
- end
-
- context 'when the SpamVerdictService allows' do
- include_context 'includes Spam constants'
-
- before do
- allow_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- allow(verdict_service).to receive(:execute).and_return(ALLOW)
- end
-
- visit new_project_issue_path(project)
- end
-
- it 'creates an issue' do
- fill_in 'issue_title', with: 'issue title'
- fill_in 'issue_description', with: 'issue description'
-
- click_button 'Create issue'
-
- expect(page.find('.issue-details h2.title')).to have_content('issue title')
- expect(page.find('.issue-details .description')).to have_content('issue description')
- end
- end
-end
diff --git a/spec/features/issues/user_creates_branch_and_merge_request_spec.rb b/spec/features/issues/user_creates_branch_and_merge_request_spec.rb
index 8c80e19810e..ae1bce7ea4c 100644
--- a/spec/features/issues/user_creates_branch_and_merge_request_spec.rb
+++ b/spec/features/issues/user_creates_branch_and_merge_request_spec.rb
@@ -85,7 +85,7 @@ RSpec.describe 'User creates branch and merge request on issue page', :js do
wait_for_requests
expect(page).to have_selector('.dropdown-toggle-text ', text: '1-cherry-coloured-funk')
- expect(current_path).to eq project_tree_path(project, '1-cherry-coloured-funk')
+ expect(page).to have_current_path project_tree_path(project, '1-cherry-coloured-funk'), ignore_query: true
end
end
@@ -110,7 +110,7 @@ RSpec.describe 'User creates branch and merge request on issue page', :js do
wait_for_requests
expect(page).to have_selector('.dropdown-toggle-text ', text: branch_name)
- expect(current_path).to eq project_tree_path(project, branch_name)
+ expect(page).to have_current_path project_tree_path(project, branch_name), ignore_query: true
end
end
end
diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb
index 37e324e6ded..446f13dc4d0 100644
--- a/spec/features/issues/user_creates_issue_spec.rb
+++ b/spec/features/issues/user_creates_issue_spec.rb
@@ -22,11 +22,11 @@ RSpec.describe "User creates issue" do
click_link "New issue"
end
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
gitlab_sign_in(create(:user))
- expect(current_path).to eq new_project_issue_path(project)
+ expect(page).to have_current_path new_project_issue_path(project), ignore_query: true
end
end
diff --git a/spec/features/issues/user_sorts_issues_spec.rb b/spec/features/issues/user_sorts_issues_spec.rb
index f3eaff379a1..86bdaf5d706 100644
--- a/spec/features/issues/user_sorts_issues_spec.rb
+++ b/spec/features/issues/user_sorts_issues_spec.rb
@@ -9,9 +9,9 @@ RSpec.describe "User sorts issues" do
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project_empty_repo, :public, group: group) }
- let_it_be(:issue1, reload: true) { create(:issue, title: 'foo', created_at: Time.now, project: project) }
- let_it_be(:issue2, reload: true) { create(:issue, title: 'bar', created_at: Time.now - 60, project: project) }
- let_it_be(:issue3, reload: true) { create(:issue, title: 'baz', created_at: Time.now - 120, project: project) }
+ let_it_be(:issue1, reload: true) { create(:issue, title: 'foo', created_at: Time.zone.now, project: project) }
+ let_it_be(:issue2, reload: true) { create(:issue, title: 'bar', created_at: Time.zone.now - 60, project: project) }
+ let_it_be(:issue3, reload: true) { create(:issue, title: 'baz', created_at: Time.zone.now - 120, project: project) }
let_it_be(:newer_due_milestone) { create(:milestone, project: project, due_date: '2013-12-11') }
let_it_be(:later_due_milestone) { create(:milestone, project: project, due_date: '2013-12-12') }
@@ -75,7 +75,7 @@ RSpec.describe "User sorts issues" do
end
it 'sorts by most recently updated', :js do
- issue3.updated_at = Time.now + 100
+ issue3.updated_at = Time.zone.now + 100
issue3.save!
visit project_issues_path(project, sort: sort_value_recently_updated)
diff --git a/spec/features/issues/user_views_issue_spec.rb b/spec/features/issues/user_views_issue_spec.rb
index 31bf7649470..eca698bb2f4 100644
--- a/spec/features/issues/user_views_issue_spec.rb
+++ b/spec/features/issues/user_views_issue_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe "User views issue" do
it 'shows the merge request and issue actions', :js, :aggregate_failures do
click_button 'Issue actions'
- expect(page).to have_link('New issue', href: new_project_issue_path(project, { issue: { description: "Related to \##{issue.iid}.\n\n" } }))
+ expect(page).to have_link('New related issue', href: new_project_issue_path(project, { add_related_issue: issue.iid }))
expect(page).to have_button('Create merge request')
expect(page).to have_button('Close issue')
end
diff --git a/spec/features/jira_connect/subscriptions_spec.rb b/spec/features/jira_connect/subscriptions_spec.rb
index e1589ba997e..0b7321bf271 100644
--- a/spec/features/jira_connect/subscriptions_spec.rb
+++ b/spec/features/jira_connect/subscriptions_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Subscriptions Content Security Policy' do
+ include ContentSecurityPolicyHelpers
+
let(:installation) { create(:jira_connect_installation) }
let(:qsh) { Atlassian::Jwt.create_query_string_hash('https://gitlab.test/subscriptions', 'GET', 'https://gitlab.test') }
let(:jwt) { Atlassian::Jwt.encode({ iss: installation.client_key, qsh: qsh }, installation.shared_secret) }
@@ -11,10 +13,7 @@ RSpec.describe 'Subscriptions Content Security Policy' do
context 'when there is no global config' do
before do
- expect_next_instance_of(JiraConnect::SubscriptionsController) do |controller|
- expect(controller).to receive(:current_content_security_policy)
- .and_return(ActionDispatch::ContentSecurityPolicy.new)
- end
+ setup_csp_for_controller(JiraConnect::SubscriptionsController)
end
it 'does not add CSP directives' do
@@ -31,9 +30,7 @@ RSpec.describe 'Subscriptions Content Security Policy' do
p.style_src :self, 'https://some-cdn.test'
end
- expect_next_instance_of(JiraConnect::SubscriptionsController) do |controller|
- expect(controller).to receive(:current_content_security_policy).and_return(csp)
- end
+ setup_existing_csp_for_controller(JiraConnect::SubscriptionsController, csp)
end
it 'appends to CSP directives' do
diff --git a/spec/features/labels_hierarchy_spec.rb b/spec/features/labels_hierarchy_spec.rb
index 6c8d41fd96f..479199b72b7 100644
--- a/spec/features/labels_hierarchy_spec.rb
+++ b/spec/features/labels_hierarchy_spec.rb
@@ -160,7 +160,7 @@ RSpec.describe 'Labels Hierarchy', :js do
find('.btn-confirm').click
- expect(page.find('.issue-details h2.title')).to have_content('new created issue')
+ expect(page.find('.issue-details h1.title')).to have_content('new created issue')
expect(page).to have_selector('span.gl-label-text', text: grandparent_group_label.title)
expect(page).to have_selector('span.gl-label-text', text: parent_group_label.title)
expect(page).to have_selector('span.gl-label-text', text: project_label_1.title)
@@ -179,38 +179,6 @@ RSpec.describe 'Labels Hierarchy', :js do
it_behaves_like 'assigning labels from sidebar'
end
-
- context 'on project board issue sidebar' do
- let(:board) { create(:board, project: project_1) }
-
- before do
- project_1.add_developer(user)
-
- visit project_board_path(project_1, board)
-
- wait_for_requests
-
- find('.board-card').click
- end
-
- it_behaves_like 'assigning labels from sidebar'
- end
-
- context 'on group board issue sidebar' do
- let(:board) { create(:board, group: parent) }
-
- before do
- parent.add_developer(user)
-
- visit group_board_path(parent, board)
-
- wait_for_requests
-
- find('.board-card').click
- end
-
- it_behaves_like 'assigning labels from sidebar'
- end
end
context 'issuable filtering' do
@@ -242,29 +210,5 @@ RSpec.describe 'Labels Hierarchy', :js do
it_behaves_like 'filtering by ancestor labels for groups'
end
-
- context 'on project boards filter' do
- let(:board) { create(:board, project: project_1) }
-
- before do
- project_1.add_developer(user)
-
- visit project_board_path(project_1, board)
- end
-
- it_behaves_like 'filtering by ancestor labels for projects', true
- end
-
- context 'on group boards filter' do
- let(:board) { create(:board, group: parent) }
-
- before do
- parent.add_developer(user)
-
- visit group_board_path(parent, board)
- end
-
- it_behaves_like 'filtering by ancestor labels for groups', true
- end
end
end
diff --git a/spec/features/markdown/copy_as_gfm_spec.rb b/spec/features/markdown/copy_as_gfm_spec.rb
index 6951d8298e5..d472134a2c7 100644
--- a/spec/features/markdown/copy_as_gfm_spec.rb
+++ b/spec/features/markdown/copy_as_gfm_spec.rb
@@ -7,10 +7,6 @@ RSpec.describe 'Copy as GFM', :js do
include RepoHelpers
include ActionView::Helpers::JavaScriptHelper
- before do
- stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/350454
- end
-
describe 'Copying rendered GFM' do
before do
@feat = MarkdownFeature.new
@@ -764,8 +760,8 @@ RSpec.describe 'Copy as GFM', :js do
context 'selecting one word of text' do
it 'copies as inline code' do
verify(
- '.line[id="LC9"] .no',
- '`RuntimeError`'
+ '.line[id="LC10"]',
+ '`end`'
)
end
end
@@ -834,6 +830,7 @@ RSpec.describe 'Copy as GFM', :js do
end
def verify(selector, gfm, target: nil)
+ expect(page).to have_selector('.js-syntax-highlight')
html = html_for_selector(selector)
output_gfm = html_to_gfm(html, 'transformCodeSelection', target: target)
wait_for_requests
diff --git a/spec/features/markdown/keyboard_shortcuts_spec.rb b/spec/features/markdown/keyboard_shortcuts_spec.rb
index 81b1928658c..82288af1f9f 100644
--- a/spec/features/markdown/keyboard_shortcuts_spec.rb
+++ b/spec/features/markdown/keyboard_shortcuts_spec.rb
@@ -37,6 +37,14 @@ RSpec.describe 'Markdown keyboard shortcuts', :js do
expect(markdown_field.value).to eq('_italic_')
end
+ it 'strikes text when <modifier>+<shift>+x is pressed' do
+ type_and_select('strikethrough')
+
+ markdown_field.send_keys([modifier_key, :shift, 'x'])
+
+ expect(markdown_field.value).to eq('~~strikethrough~~')
+ end
+
it 'links text when <modifier>+K is pressed' do
type_and_select('link')
diff --git a/spec/features/markdown/sandboxed_mermaid_spec.rb b/spec/features/markdown/sandboxed_mermaid_spec.rb
index f118fb3db66..05fe83b3107 100644
--- a/spec/features/markdown/sandboxed_mermaid_spec.rb
+++ b/spec/features/markdown/sandboxed_mermaid_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe 'Sandboxed Mermaid rendering', :js do
wait_for_requests
- expected = %(<iframe src="/-/sandbox/mermaid" sandbox="allow-scripts" frameborder="0" scrolling="no")
+ expected = %(<iframe src="/-/sandbox/mermaid" sandbox="allow-scripts allow-popups" frameborder="0" scrolling="no")
expect(page.html).to include(expected)
end
end
diff --git a/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb b/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb
index 5894ec923c2..92b9b785148 100644
--- a/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb
+++ b/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb
@@ -17,66 +17,172 @@ RSpec.describe 'Merge request > User edits assignees sidebar', :js do
let(:sidebar_assignee_block) { page.find('.js-issuable-sidebar .assignee') }
let(:sidebar_assignee_avatar_link) { sidebar_assignee_block.find_all('a').find { |a| a['href'].include? assignee.username } }
let(:sidebar_assignee_tooltip) { sidebar_assignee_avatar_link['title'] || '' }
- let(:sidebar_assignee_dropdown_item) { sidebar_assignee_block.find(".dropdown-menu li[data-user-id=\"#{assignee.id}\"]") }
- let(:sidebar_assignee_dropdown_tooltip) { sidebar_assignee_dropdown_item.find('a')['data-title'] || '' }
- context 'when user is an owner' do
+ context 'when GraphQL assignees widget feature flag is disabled' do
+ let(:sidebar_assignee_dropdown_item) { sidebar_assignee_block.find(".dropdown-menu li[data-user-id=\"#{assignee.id}\"]") }
+ let(:sidebar_assignee_dropdown_tooltip) { sidebar_assignee_dropdown_item.find('a')['data-title'] || '' }
+
before do
- stub_const('Autocomplete::UsersFinder::LIMIT', users_find_limit)
+ stub_feature_flags(issue_assignees_widget: false)
+ end
- sign_in(project.first_owner)
+ context 'when user is an owner' do
+ before do
+ stub_const('Autocomplete::UsersFinder::LIMIT', users_find_limit)
- merge_request.assignees << assignee
+ sign_in(project.first_owner)
- visit project_merge_request_path(project, merge_request)
+ merge_request.assignees << assignee
- wait_for_requests
+ visit project_merge_request_path(project, merge_request)
+
+ wait_for_requests
+ end
+
+ shared_examples 'when assigned' do |expected_tooltip: ''|
+ it 'shows assignee name' do
+ expect(sidebar_assignee_block).to have_text(assignee.name)
+ end
+
+ it "shows assignee tooltip '#{expected_tooltip}'" do
+ expect(sidebar_assignee_tooltip).to eql(expected_tooltip)
+ end
+
+ context 'when edit is clicked' do
+ before do
+ sidebar_assignee_block.click_link('Edit')
+
+ wait_for_requests
+ end
+
+ it "shows assignee tooltip '#{expected_tooltip}" do
+ expect(sidebar_assignee_dropdown_tooltip).to eql(expected_tooltip)
+ end
+ end
+ end
+
+ context 'when assigned to maintainer' do
+ let(:assignee) { project_maintainers.last }
+
+ it_behaves_like 'when assigned', expected_tooltip: ''
+ end
+
+ context 'when assigned to developer' do
+ let(:assignee) { project_developers.last }
+
+ it_behaves_like 'when assigned', expected_tooltip: 'Cannot merge'
+ end
end
- shared_examples 'when assigned' do |expected_tooltip: ''|
- it 'shows assignee name' do
- expect(sidebar_assignee_block).to have_text(assignee.name)
+ context 'with invite members considerations' do
+ let_it_be(:user) { create(:user) }
+
+ before do
+ sign_in(user)
end
- it "shows assignee tooltip '#{expected_tooltip}'" do
- expect(sidebar_assignee_tooltip).to eql(expected_tooltip)
+ include_examples 'issuable invite members' do
+ let(:issuable_path) { project_merge_request_path(project, merge_request) }
end
+ end
+ end
+
+ context 'when GraphQL assignees widget feature flag is enabled' do
+ let(:sidebar_assignee_dropdown_item) { sidebar_assignee_block.find(".dropdown-item", text: assignee.username ) }
+ let(:sidebar_assignee_dropdown_tooltip) { sidebar_assignee_dropdown_item['title']}
+
+ context 'when user is an owner' do
+ before do
+ stub_const('Autocomplete::UsersFinder::LIMIT', users_find_limit)
+
+ sign_in(project.first_owner)
+
+ merge_request.assignees << assignee
- context 'when edit is clicked' do
- before do
- sidebar_assignee_block.click_link('Edit')
+ visit project_merge_request_path(project, merge_request)
- wait_for_requests
+ wait_for_requests
+ end
+
+ shared_examples 'when assigned' do |expected_tooltip: ''|
+ it 'shows assignee name' do
+ expect(sidebar_assignee_block).to have_text(assignee.name)
end
- it "shows assignee tooltip '#{expected_tooltip}" do
- expect(sidebar_assignee_dropdown_tooltip).to eql(expected_tooltip)
+ it "shows assignee tooltip '#{expected_tooltip}'" do
+ expect(sidebar_assignee_tooltip).to eql(expected_tooltip)
+ end
+
+ context 'when edit is clicked' do
+ before do
+ open_assignees_dropdown
+ end
+
+ it "shows assignee tooltip '#{expected_tooltip}" do
+ expect(sidebar_assignee_dropdown_tooltip).to eql(expected_tooltip)
+ end
end
end
- end
- context 'when assigned to maintainer' do
- let(:assignee) { project_maintainers.last }
+ context 'when assigned to maintainer' do
+ let(:assignee) { project_maintainers.last }
- it_behaves_like 'when assigned', expected_tooltip: ''
- end
+ it_behaves_like 'when assigned', expected_tooltip: ''
+ end
- context 'when assigned to developer' do
- let(:assignee) { project_developers.last }
+ context 'when assigned to developer' do
+ let(:assignee) { project_developers.last }
- it_behaves_like 'when assigned', expected_tooltip: 'Cannot merge'
+ it_behaves_like 'when assigned', expected_tooltip: 'Cannot merge'
+ end
end
- end
- context 'with invite members considerations' do
- let_it_be(:user) { create(:user) }
+ context 'with invite members considerations' do
+ let_it_be(:user) { create(:user) }
- before do
- sign_in(user)
+ before do
+ sign_in(user)
+ end
+
+ # TODO: Move to shared examples when feature flag is removed: https://gitlab.com/gitlab-org/gitlab/-/issues/328185
+ context 'when a privileged user can invite' do
+ it 'shows a link for inviting members and launches invite modal' do
+ project.add_maintainer(user)
+ visit project_merge_request_path(project, merge_request)
+
+ open_assignees_dropdown
+
+ page.within '.dropdown-menu-user' do
+ expect(page).to have_link('Invite members')
+ expect(page).to have_selector('[data-track-action="click_invite_members"]')
+ expect(page).to have_selector('[data-track-label="edit_assignee"]')
+ end
+
+ click_link 'Invite members'
+
+ expect(page).to have_content("You're inviting members to the")
+ end
+ end
+
+ context 'when user cannot invite members in assignee dropdown' do
+ it 'shows author in assignee dropdown and no invite link' do
+ project.add_developer(user)
+ visit project_merge_request_path(project, merge_request)
+
+ open_assignees_dropdown
+
+ page.within '.dropdown-menu-user' do
+ expect(page).not_to have_link('Invite members')
+ end
+ end
+ end
end
+ end
- include_examples 'issuable invite members' do
- let(:issuable_path) { project_merge_request_path(project, merge_request) }
+ def open_assignees_dropdown
+ page.within('.assignee') do
+ click_button('Edit')
+ wait_for_requests
end
end
end
diff --git a/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb b/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb
index 8343e04aef1..231722c166d 100644
--- a/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb
+++ b/spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb
@@ -140,7 +140,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
describe 'reply form' do
before do
- click_button 'Toggle thread'
+ click_button _('Show thread')
end
it 'allows user to comment' do
@@ -362,7 +362,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'displays next thread even if hidden' do
page.all('.note-discussion', count: 2).each do |discussion|
page.within discussion do
- click_button 'Toggle thread'
+ click_button _('Hide thread')
end
end
@@ -549,13 +549,13 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'shows resolved icon' do
expect(page).to have_content 'All threads resolved'
- click_button 'Toggle thread'
+ click_button _('Show thread')
expect(page).to have_selector('.line-resolve-btn.is-active')
end
it 'does not allow user to click resolve button' do
expect(page).to have_selector('.line-resolve-btn.is-active')
- click_button 'Toggle thread'
+ click_button _('Show thread')
expect(page).to have_selector('.line-resolve-btn.is-active')
end
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 33c5a936b8d..fca40dc7edc 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
@@ -25,6 +25,7 @@ RSpec.describe 'Merge request > User sees avatars on diff notes', :js do
before do
project.add_maintainer(user)
sign_in user
+ stub_feature_flags(gl_avatar_for_all_user_avatars: false)
set_cookie('sidebar_collapsed', 'true')
end
diff --git a/spec/features/merge_request/user_sees_diff_spec.rb b/spec/features/merge_request/user_sees_diff_spec.rb
index 7cd9ef80874..50f4cce5c23 100644
--- a/spec/features/merge_request/user_sees_diff_spec.rb
+++ b/spec/features/merge_request/user_sees_diff_spec.rb
@@ -45,8 +45,8 @@ RSpec.describe 'Merge request > User sees diff', :js do
visit diffs_project_merge_request_path(project, merge_request)
- page.within('.alert') do
- expect(page).to have_text("Too many changes to show. Plain diff Email patch To preserve performance only 3 of 3+ files are displayed.")
+ page.within('.gl-alert') do
+ expect(page).to have_text("Too many changes to show. To preserve performance only 3 of 3+ files are displayed. Plain diff Email patch")
end
end
end
@@ -69,7 +69,7 @@ RSpec.describe 'Merge request > User sees diff', :js do
end
context 'as user who needs to fork' do
- it 'shows fork/cancel confirmation', :sidekiq_might_not_need_inline do
+ it 'shows fork/cancel confirmation', :sidekiq_might_not_need_inline, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/337477' do
sign_in(user)
visit diffs_project_merge_request_path(project, merge_request)
diff --git a/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb b/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
index 2a49109d360..09c6b6bce3b 100644
--- a/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
+++ b/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
@@ -25,6 +25,8 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
}
end
+ let(:expected_detached_mr_tag) {'merge request'}
+
before do
stub_application_setting(auto_devops_enabled: false)
stub_ci_pipeline_yaml_file(YAML.dump(config))
@@ -118,16 +120,16 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
it 'sees detached tag for detached merge request pipelines' do
page.within('.ci-table') do
expect(all('.pipeline-tags')[0])
- .to have_content("detached")
+ .to have_content(expected_detached_mr_tag)
expect(all('.pipeline-tags')[1])
- .to have_content("detached")
+ .to have_content(expected_detached_mr_tag)
expect(all('.pipeline-tags')[2])
- .not_to have_content("detached")
+ .not_to have_content(expected_detached_mr_tag)
expect(all('.pipeline-tags')[3])
- .not_to have_content("detached")
+ .not_to have_content(expected_detached_mr_tag)
end
end
@@ -312,16 +314,16 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
it 'sees detached tag for detached merge request pipelines' do
page.within('.ci-table') do
expect(all('.pipeline-tags')[0])
- .to have_content("detached")
+ .to have_content(expected_detached_mr_tag)
expect(all('.pipeline-tags')[1])
- .to have_content("detached")
+ .to have_content(expected_detached_mr_tag)
expect(all('.pipeline-tags')[2])
- .not_to have_content("detached")
+ .not_to have_content(expected_detached_mr_tag)
expect(all('.pipeline-tags')[3])
- .not_to have_content("detached")
+ .not_to have_content(expected_detached_mr_tag)
end
end
diff --git a/spec/features/merge_request/user_sees_merge_widget_spec.rb b/spec/features/merge_request/user_sees_merge_widget_spec.rb
index 872507c3b7a..27f7c699c50 100644
--- a/spec/features/merge_request/user_sees_merge_widget_spec.rb
+++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb
@@ -96,10 +96,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
context 'view merge request with external CI service' do
before do
- create(:integration, project: project,
- active: true,
- type: 'DroneCiService',
- category: 'ci')
+ create(:drone_ci_integration, project: project)
visit project_merge_request_path(project, merge_request)
end
diff --git a/spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb b/spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb
index e5592ae9535..23b03e33f5d 100644
--- a/spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb
+++ b/spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb
@@ -137,7 +137,7 @@ RSpec.describe 'Merge request < User sees mini pipeline graph', :js do
build_item.click
find('.build-page')
- expect(current_path).to eql(project_job_path(project, build))
+ expect(page).to have_current_path(project_job_path(project, build), ignore_query: true)
end
it 'shows tooltip when hovered' do
diff --git a/spec/features/merge_request/user_sees_pipelines_spec.rb b/spec/features/merge_request/user_sees_pipelines_spec.rb
index 266ae0d8c37..9696b1ff551 100644
--- a/spec/features/merge_request/user_sees_pipelines_spec.rb
+++ b/spec/features/merge_request/user_sees_pipelines_spec.rb
@@ -125,7 +125,6 @@ RSpec.describe 'Merge request > User sees pipelines', :js do
before do
stub_feature_flags(ci_disallow_to_create_merge_request_pipelines_in_target_project: false)
- stub_feature_flags(rearrange_pipelines_table: false)
end
it 'creates a pipeline in the parent project when user proceeds with the warning' do
@@ -186,7 +185,7 @@ RSpec.describe 'Merge request > User sees pipelines', :js do
page.within(first('.commit')) do
page.within('.pipeline-tags') do
expect(page.find('[data-testid="pipeline-url-link"]')[:href]).to include(expected_project.full_path)
- expect(page).to have_content('detached')
+ expect(page).to have_content('merge request')
end
page.within('.pipeline-triggerer') do
expect(page).to have_link(href: user_path(actor))
@@ -232,7 +231,7 @@ RSpec.describe 'Merge request > User sees pipelines', :js do
sign_in user
end
- context 'when pipeline and merge request were created simultaneously' do
+ context 'when pipeline and merge request were created simultaneously', :delete do
before do
stub_ci_pipeline_to_return_yaml_file
diff --git a/spec/features/merge_request/user_sees_suggest_pipeline_spec.rb b/spec/features/merge_request/user_sees_suggest_pipeline_spec.rb
index 2191849edd9..448ef750508 100644
--- a/spec/features/merge_request/user_sees_suggest_pipeline_spec.rb
+++ b/spec/features/merge_request/user_sees_suggest_pipeline_spec.rb
@@ -42,9 +42,6 @@ RSpec.describe 'Merge request > User sees suggest pipeline', :js do
wait_for_requests
- # Drawer is open
- expect(page).to have_content('This template creates a simple test pipeline. To use it:')
-
# Editor shows template
expect(page).to have_content('This file is a template, and might need editing before it works on your project.')
diff --git a/spec/features/merge_requests/user_lists_merge_requests_spec.rb b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
index f96717970bf..8c1d9dd38b0 100644
--- a/spec/features/merge_requests/user_lists_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
@@ -77,7 +77,7 @@ RSpec.describe 'Merge requests > User lists merge requests' do
it 'filters on no assignee' do
visit_merge_requests(project, assignee_id: IssuableFinder::Params::FILTER_NONE)
- expect(current_path).to eq(project_merge_requests_path(project))
+ expect(page).to have_current_path(project_merge_requests_path(project), ignore_query: true)
expect(page).to have_content 'merge-test'
expect(page).to have_content 'feature'
expect(page).not_to have_content 'fix'
diff --git a/spec/features/milestones/user_views_milestones_spec.rb b/spec/features/milestones/user_views_milestones_spec.rb
index 58439df92ba..752cc63486f 100644
--- a/spec/features/milestones/user_views_milestones_spec.rb
+++ b/spec/features/milestones/user_views_milestones_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe "User views milestones" do
it "opens milestone" do
click_link(milestone.title)
- expect(current_path).to eq(project_milestone_path(project, milestone))
+ expect(page).to have_current_path(project_milestone_path(project, milestone), ignore_query: true)
expect(page).to have_content(milestone.title)
.and have_selector("#tab-issues li.issuable-row", count: 2)
.and have_content(issue.title)
@@ -85,7 +85,7 @@ RSpec.describe "User views milestones with no MR" do
it "opens milestone" do
click_link(milestone.title)
- expect(current_path).to eq(project_milestone_path(project, milestone))
+ expect(page).to have_current_path(project_milestone_path(project, milestone), ignore_query: true)
expect(page).to have_content(milestone.title)
.and have_selector("#tab-issues")
.and have_no_selector("#tab-merge-requests")
diff --git a/spec/features/oauth_login_spec.rb b/spec/features/oauth_login_spec.rb
index 0ea14bc00a5..93674057fed 100644
--- a/spec/features/oauth_login_spec.rb
+++ b/spec/features/oauth_login_spec.rb
@@ -45,7 +45,7 @@ RSpec.describe 'OAuth Login', :js, :allow_forgery_protection do
it 'logs the user in' do
login_with_provider(provider, additional_info: additional_info)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
@@ -55,19 +55,19 @@ RSpec.describe 'OAuth Login', :js, :allow_forgery_protection do
it 'logs the user in' do
login_with_provider(provider, additional_info: additional_info, enter_two_factor: true)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
it 'when bypass-two-factor is enabled' do
allow(Gitlab.config.omniauth).to receive_messages(allow_bypass_two_factor: true)
login_via(provider.to_s, user, uid, remember_me: false, additional_info: additional_info)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
it 'when bypass-two-factor is disabled' do
allow(Gitlab.config.omniauth).to receive_messages(allow_bypass_two_factor: false)
login_with_provider(provider, enter_two_factor: true, additional_info: additional_info)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
@@ -81,7 +81,7 @@ RSpec.describe 'OAuth Login', :js, :allow_forgery_protection do
clear_browser_session
visit(root_path)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
@@ -94,7 +94,7 @@ RSpec.describe 'OAuth Login', :js, :allow_forgery_protection do
clear_browser_session
visit(root_path)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
end
@@ -107,7 +107,7 @@ RSpec.describe 'OAuth Login', :js, :allow_forgery_protection do
clear_browser_session
visit(root_path)
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
end
@@ -120,7 +120,7 @@ RSpec.describe 'OAuth Login', :js, :allow_forgery_protection do
clear_browser_session
visit(root_path)
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
end
end
diff --git a/spec/features/password_reset_spec.rb b/spec/features/password_reset_spec.rb
index 322ccc6a0c0..a4e167a3e75 100644
--- a/spec/features/password_reset_spec.rb
+++ b/spec/features/password_reset_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'Password reset' do
forgot_password(user)
expect(page).to have_content(I18n.t('devise.passwords.send_paranoid_instructions'))
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
expect(user.recently_sent_password_reset?).to be_truthy
end
@@ -20,7 +20,7 @@ RSpec.describe 'Password reset' do
expect { forgot_password(user) }.to change { user.reset_password_sent_at }
expect(page).to have_content(I18n.t('devise.passwords.send_paranoid_instructions'))
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
it 'throttles multiple resets in a short timespan' do
@@ -31,7 +31,7 @@ RSpec.describe 'Password reset' do
expect { forgot_password(user) }.not_to change { user.reset_password_sent_at }
expect(page).to have_content(I18n.t('devise.passwords.send_paranoid_instructions'))
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
end
@@ -50,7 +50,7 @@ RSpec.describe 'Password reset' do
click_button 'Change your password'
expect(page).to have_content(I18n.t('devise.passwords.updated_not_active'))
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
end
diff --git a/spec/features/profiles/account_spec.rb b/spec/features/profiles/account_spec.rb
index 2e8d9ef80cd..6a4a1fca008 100644
--- a/spec/features/profiles/account_spec.rb
+++ b/spec/features/profiles/account_spec.rb
@@ -50,14 +50,14 @@ RSpec.describe 'Profile > Account', :js do
it 'the user is accessible via the new path' do
update_username(new_username)
visit new_user_path
- expect(current_path).to eq(new_user_path)
+ expect(page).to have_current_path(new_user_path, ignore_query: true)
expect(find('.user-info')).to have_content(new_username)
end
it 'the old user path redirects to the new path' do
update_username(new_username)
visit old_user_path
- expect(current_path).to eq(new_user_path)
+ expect(page).to have_current_path(new_user_path, ignore_query: true)
expect(find('.user-info')).to have_content(new_username)
end
@@ -77,14 +77,14 @@ RSpec.describe 'Profile > Account', :js do
it 'the project is accessible via the new path' do
update_username(new_username)
visit new_project_path
- expect(current_path).to eq(new_project_path)
+ expect(page).to have_current_path(new_project_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(user.name)
end
it 'the old project path redirects to the new path' do
update_username(new_username)
visit old_project_path
- expect(current_path).to eq(new_project_path)
+ expect(page).to have_current_path(new_project_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(user.name)
end
end
diff --git a/spec/features/profiles/chat_names_spec.rb b/spec/features/profiles/chat_names_spec.rb
index b392d8dfa8e..82134de582a 100644
--- a/spec/features/profiles/chat_names_spec.rb
+++ b/spec/features/profiles/chat_names_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'Profile > Chat' do
end
it 'goes to list of chat names and see chat account' do
- expect(page.current_path).to eq(profile_chat_names_path)
+ expect(page).to have_current_path(profile_chat_names_path, ignore_query: true)
expect(page).to have_content('my_chat_team')
expect(page).to have_content('my_chat_user')
end
@@ -46,7 +46,7 @@ RSpec.describe 'Profile > Chat' do
end
it 'goes to list of chat names and do not see chat account' do
- expect(page.current_path).to eq(profile_chat_names_path)
+ expect(page).to have_current_path(profile_chat_names_path, ignore_query: true)
expect(page).not_to have_content('my_chat_team')
expect(page).not_to have_content('my_chat_user')
end
diff --git a/spec/features/profiles/password_spec.rb b/spec/features/profiles/password_spec.rb
index 898e2c2aa59..2181285f771 100644
--- a/spec/features/profiles/password_spec.rb
+++ b/spec/features/profiles/password_spec.rb
@@ -104,7 +104,7 @@ RSpec.describe 'Profile > Password' do
expect(user.failed_attempts).to eq(1)
expect(user.valid_password?(new_password)).to eq(false)
- expect(current_path).to eq(edit_profile_password_path)
+ expect(page).to have_current_path(edit_profile_password_path, ignore_query: true)
page.within '.flash-container' do
expect(page).to have_content('You must provide a valid current password')
@@ -116,7 +116,7 @@ RSpec.describe 'Profile > Password' do
subject
- expect(current_path).to eq(new_user_session_path)
+ expect(page).to have_current_path(new_user_session_path, ignore_query: true)
page.within '.flash-container' do
expect(page).to have_content('Your account is locked.')
@@ -146,7 +146,7 @@ RSpec.describe 'Profile > Password' do
it 'changes the password, logs the user out and prompts them to sign in again', :aggregate_failures do
expect { subject }.to change { user.reload.valid_password?(new_password) }.to(true)
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
page.within '.flash-container' do
expect(page).to have_content('Password was successfully updated. Please sign in again.')
@@ -167,14 +167,14 @@ RSpec.describe 'Profile > Password' do
it 'needs change user password' do
visit edit_profile_password_path
- expect(current_path).to eq new_profile_password_path
+ expect(page).to have_current_path new_profile_password_path, ignore_query: true
fill_in :user_password, with: user.password
fill_in :user_new_password, with: Gitlab::Password.test_default
fill_in :user_password_confirmation, with: Gitlab::Password.test_default
click_button 'Set new password'
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
context 'when global require_two_factor_authentication is enabled' do
@@ -183,7 +183,7 @@ RSpec.describe 'Profile > Password' do
visit profile_path
- expect(current_path).to eq new_profile_password_path
+ expect(page).to have_current_path new_profile_password_path, ignore_query: true
end
end
end
diff --git a/spec/features/profiles/user_visits_profile_preferences_page_spec.rb b/spec/features/profiles/user_visits_profile_preferences_page_spec.rb
index da63f7c0f41..e19e29bf63a 100644
--- a/spec/features/profiles/user_visits_profile_preferences_page_spec.rb
+++ b/spec/features/profiles/user_visits_profile_preferences_page_spec.rb
@@ -55,12 +55,12 @@ RSpec.describe 'User visits the profile preferences page', :js do
find('#logo').click
expect(page).to have_content("You don't have starred projects yet")
- expect(page.current_path).to eq starred_dashboard_projects_path
+ expect(page).to have_current_path starred_dashboard_projects_path, ignore_query: true
find('.shortcuts-activity').click
expect(page).not_to have_content("You don't have starred projects yet")
- expect(page.current_path).to eq dashboard_projects_path
+ expect(page).to have_current_path dashboard_projects_path, ignore_query: true
end
end
diff --git a/spec/features/profiles/user_visits_profile_spec.rb b/spec/features/profiles/user_visits_profile_spec.rb
index d90ac439eee..7d545711997 100644
--- a/spec/features/profiles/user_visits_profile_spec.rb
+++ b/spec/features/profiles/user_visits_profile_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe 'User visits their profile' do
- let(:user) { create(:user) }
+ let_it_be_with_refind(:user) { create(:user) }
before do
sign_in(user)
@@ -87,4 +87,53 @@ RSpec.describe 'User visits their profile' do
end
end
end
+
+ describe 'storage_enforcement_banner', :js do
+ context 'with storage_enforcement_date set' do
+ let_it_be(:storage_enforcement_date) { Date.today + 30 }
+
+ before do
+ allow_next_found_instance_of(Namespaces::UserNamespace) do |g|
+ allow(g).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
+ end
+ end
+
+ it 'displays the banner in the profile page' do
+ visit(profile_path)
+ expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ end
+
+ it 'does not display the banner if user has previously closed unless threshold has changed' do
+ visit(profile_path)
+ expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ find('.js-storage-enforcement-banner [data-testid="close-icon"]').click
+ page.refresh
+ expect_page_not_to_have_storage_enforcement_banner
+
+ storage_enforcement_date = Date.today + 13
+ allow_next_found_instance_of(Namespaces::UserNamespace) do |g|
+ allow(g).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
+ end
+ page.refresh
+ expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ end
+ end
+
+ context 'with storage_enforcement_date not set' do
+ # This test should break and be rewritten after the implementation of the storage_enforcement_date
+ # TBD: https://gitlab.com/gitlab-org/gitlab/-/issues/350632
+ it 'does not display the banner in the group page' do
+ visit(profile_path)
+ expect_page_not_to_have_storage_enforcement_banner
+ end
+ end
+ end
+
+ def expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ expect(page).to have_text "From #{storage_enforcement_date} storage limits will apply to this namespace"
+ end
+
+ def expect_page_not_to_have_storage_enforcement_banner
+ expect(page).not_to have_text "storage limits will apply to this namespace"
+ end
end
diff --git a/spec/features/projects/artifacts/file_spec.rb b/spec/features/projects/artifacts/file_spec.rb
index b61ee623fec..f97c1b0e543 100644
--- a/spec/features/projects/artifacts/file_spec.rb
+++ b/spec/features/projects/artifacts/file_spec.rb
@@ -73,7 +73,7 @@ RSpec.describe 'Artifact file', :js do
end
it "redirects to new URL" do
- expect(page.current_path).to eq(file_url)
+ expect(page).to have_current_path(file_url, ignore_query: true)
end
end
end
diff --git a/spec/features/projects/artifacts/raw_spec.rb b/spec/features/projects/artifacts/raw_spec.rb
index d580262d48b..c10cb56a44b 100644
--- a/spec/features/projects/artifacts/raw_spec.rb
+++ b/spec/features/projects/artifacts/raw_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe 'Raw artifact' do
end
it "redirects to new URL" do
- expect(page.current_path).to eq(raw_url)
+ expect(page).to have_current_path(raw_url, ignore_query: true)
end
end
end
diff --git a/spec/features/projects/artifacts/user_browses_artifacts_spec.rb b/spec/features/projects/artifacts/user_browses_artifacts_spec.rb
index 77e3c7f972d..2d09f5a4263 100644
--- a/spec/features/projects/artifacts/user_browses_artifacts_spec.rb
+++ b/spec/features/projects/artifacts/user_browses_artifacts_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe "User browses artifacts" do
it "redirects to new URL" do
visit(browse_url.sub("/-/jobs", "/builds"))
- expect(page.current_path).to eq(browse_url)
+ expect(page).to have_current_path(browse_url, ignore_query: true)
end
end
diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb
index 77194fd6ca1..05fd72a8932 100644
--- a/spec/features/projects/blobs/blob_show_spec.rb
+++ b/spec/features/projects/blobs/blob_show_spec.rb
@@ -1009,6 +1009,29 @@ RSpec.describe 'File blob', :js do
stub_application_setting(static_objects_external_storage_url: 'https://cdn.gitlab.com')
end
+ context 'private project' do
+ let_it_be(:project) { create(:project, :repository, :private) }
+ let_it_be(:user) { create(:user, static_object_token: 'ABCD1234') }
+
+ before do
+ project.add_developer(user)
+
+ sign_in(user)
+ visit_blob('README.md')
+ end
+
+ it 'shows open raw and download buttons with external storage URL prepended and user token appended to their href' do
+ path = project_raw_path(project, 'master/README.md')
+ raw_uri = "https://cdn.gitlab.com#{path}?token=#{user.static_object_token}"
+ download_uri = "https://cdn.gitlab.com#{path}?token=#{user.static_object_token}&inline=false"
+
+ aggregate_failures do
+ expect(page).to have_link 'Open raw', href: raw_uri
+ expect(page).to have_link 'Download', href: download_uri
+ end
+ end
+ end
+
context 'public project' do
before do
visit_blob('README.md')
@@ -1033,71 +1056,6 @@ RSpec.describe 'File blob', :js do
stub_feature_flags(refactor_blob_viewer: false)
end
- context 'when ref switch' do
- # We need to unsre that this test runs with the refactor_blob_viewer feature flag enabled
- # This will be addressed in https://gitlab.com/gitlab-org/gitlab/-/issues/351558
-
- def switch_ref_to(ref_name)
- first('.qa-branches-select').click # rubocop:disable QA/SelectorUsage
-
- page.within '.project-refs-form' do
- click_link ref_name
- wait_for_requests
- end
- end
-
- context 'when highlighting lines' do
- it 'displays single highlighted line number of different ref' do
- visit_blob('files/js/application.js', anchor: 'L1')
-
- switch_ref_to('feature')
-
- page.within '.blob-content' do
- expect(find_by_id('LC1')[:class]).to include("hll")
- end
- end
-
- it 'displays multiple highlighted line numbers of different ref' do
- visit_blob('files/js/application.js', anchor: 'L1-3')
-
- switch_ref_to('feature')
-
- page.within '.blob-content' do
- expect(find_by_id('LC1')[:class]).to include("hll")
- expect(find_by_id('LC2')[:class]).to include("hll")
- expect(find_by_id('LC3')[:class]).to include("hll")
- end
- end
- end
- end
-
- context 'visiting with a line number anchor' do
- # We need to unsre that this test runs with the refactor_blob_viewer feature flag enabled
- # This will be addressed in https://gitlab.com/gitlab-org/gitlab/-/issues/351558
-
- before do
- visit_blob('files/markdown/ruby-style-guide.md', anchor: 'L1')
- end
-
- it 'displays the blob using the simple viewer' do
- aggregate_failures do
- # hides the rich viewer
- expect(page).to have_selector('.blob-viewer[data-type="simple"]')
- expect(page).not_to have_selector('.blob-viewer[data-type="rich"]')
-
- # highlights the line in question
- expect(page).to have_selector('#LC1.hll')
-
- # shows highlighted Markdown code
- expect(page).to have_css(".js-syntax-highlight")
- expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)")
-
- # shows an enabled copy button
- expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
- end
- end
- end
-
context 'binary file that appears to be text in the first 1024 bytes' do
# We need to unsre that this test runs with the refactor_blob_viewer feature flag enabled
# This will be addressed in https://gitlab.com/gitlab-org/gitlab/-/issues/351559
@@ -1126,535 +1084,5 @@ RSpec.describe 'File blob', :js do
end
end
end
-
- context 'when static objects external storage is enabled' do
- # We need to unsre that this test runs with the refactor_blob_viewer feature flag enabled
- # This will be addressed in https://gitlab.com/gitlab-org/gitlab/-/issues/351555
-
- before do
- stub_application_setting(static_objects_external_storage_url: 'https://cdn.gitlab.com')
- end
-
- context 'private project' do
- let_it_be(:project) { create(:project, :repository, :private) }
- let_it_be(:user) { create(:user) }
-
- before do
- project.add_developer(user)
-
- sign_in(user)
- visit_blob('README.md')
- end
-
- it 'shows open raw and download buttons with external storage URL prepended and user token appended to their href' do
- path = project_raw_path(project, 'master/README.md')
- raw_uri = "https://cdn.gitlab.com#{path}?token=#{user.static_object_token}"
- download_uri = "https://cdn.gitlab.com#{path}?inline=false&token=#{user.static_object_token}"
-
- aggregate_failures do
- expect(page).to have_link 'Open raw', href: raw_uri
- expect(page).to have_link 'Download', href: download_uri
- end
- end
- end
- end
-
- context 'files with auxiliary viewers' do
- # This context is the same as the other 'files with auxiliary viewers' in this file, we just ensure that the auxiliary viewers still work this the refactor_blob_viewer disabled
- # It should be safe to remove once we rollout the refactored blob viewer
-
- describe '.gitlab-ci.yml' do
- before do
- project.add_maintainer(project.creator)
-
- Files::CreateService.new(
- project,
- project.creator,
- start_branch: 'master',
- branch_name: 'master',
- commit_message: "Add .gitlab-ci.yml",
- file_path: '.gitlab-ci.yml',
- file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
- ).execute
-
- visit_blob('.gitlab-ci.yml')
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows that configuration is valid
- expect(page).to have_content('This GitLab CI configuration is valid.')
-
- # shows a learn more link
- expect(page).to have_link('Learn more')
- end
- end
- end
-
- describe '.gitlab/route-map.yml' do
- before do
- project.add_maintainer(project.creator)
-
- Files::CreateService.new(
- project,
- project.creator,
- start_branch: 'master',
- branch_name: 'master',
- commit_message: "Add .gitlab/route-map.yml",
- file_path: '.gitlab/route-map.yml',
- file_content: <<-MAP.strip_heredoc
- # Team data
- - source: 'data/team.yml'
- public: 'team/'
- MAP
- ).execute
-
- visit_blob('.gitlab/route-map.yml')
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows that map is valid
- expect(page).to have_content('This Route Map is valid.')
-
- # shows a learn more link
- expect(page).to have_link('Learn more')
- end
- end
- end
-
- describe '.gitlab/dashboards/custom-dashboard.yml' do
- before do
- project.add_maintainer(project.creator)
-
- Files::CreateService.new(
- project,
- project.creator,
- start_branch: 'master',
- branch_name: 'master',
- commit_message: "Add .gitlab/dashboards/custom-dashboard.yml",
- file_path: '.gitlab/dashboards/custom-dashboard.yml',
- file_content: file_content
- ).execute
- end
-
- context 'with metrics_dashboard_exhaustive_validations feature flag off' do
- before do
- stub_feature_flags(metrics_dashboard_exhaustive_validations: false)
- visit_blob('.gitlab/dashboards/custom-dashboard.yml')
- end
-
- context 'valid dashboard file' do
- let(:file_content) { File.read(Rails.root.join('config/prometheus/common_metrics.yml')) }
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows that dashboard yaml is valid
- expect(page).to have_content('Metrics Dashboard YAML definition is valid.')
-
- # shows a learn more link
- expect(page).to have_link('Learn more')
- end
- end
- end
-
- context 'invalid dashboard file' do
- let(:file_content) { "dashboard: 'invalid'" }
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows that dashboard yaml is invalid
- expect(page).to have_content('Metrics Dashboard YAML definition is invalid:')
- expect(page).to have_content("panel_groups: should be an array of panel_groups objects")
-
- # shows a learn more link
- expect(page).to have_link('Learn more')
- end
- end
- end
- end
-
- context 'with metrics_dashboard_exhaustive_validations feature flag on' do
- before do
- stub_feature_flags(metrics_dashboard_exhaustive_validations: true)
- visit_blob('.gitlab/dashboards/custom-dashboard.yml')
- end
-
- context 'valid dashboard file' do
- let(:file_content) { File.read(Rails.root.join('config/prometheus/common_metrics.yml')) }
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows that dashboard yaml is valid
- expect(page).to have_content('Metrics Dashboard YAML definition is valid.')
-
- # shows a learn more link
- expect(page).to have_link('Learn more')
- end
- end
- end
-
- context 'invalid dashboard file' do
- let(:file_content) { "dashboard: 'invalid'" }
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows that dashboard yaml is invalid
- expect(page).to have_content('Metrics Dashboard YAML definition is invalid:')
- expect(page).to have_content("root is missing required keys: panel_groups")
-
- # shows a learn more link
- expect(page).to have_link('Learn more')
- end
- end
- end
- end
- end
-
- context 'LICENSE' do
- before do
- visit_blob('LICENSE')
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows license
- expect(page).to have_content('This project is licensed under the MIT License.')
-
- # shows a learn more link
- expect(page).to have_link('Learn more', href: 'http://choosealicense.com/licenses/mit/')
- end
- end
- end
-
- context '*.gemspec' do
- before do
- project.add_maintainer(project.creator)
-
- Files::CreateService.new(
- project,
- project.creator,
- start_branch: 'master',
- branch_name: 'master',
- commit_message: "Add activerecord.gemspec",
- file_path: 'activerecord.gemspec',
- file_content: <<-SPEC.strip_heredoc
- Gem::Specification.new do |s|
- s.platform = Gem::Platform::RUBY
- s.name = "activerecord"
- end
- SPEC
- ).execute
-
- visit_blob('activerecord.gemspec')
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows names of dependency manager and package
- expect(page).to have_content('This project manages its dependencies using RubyGems.')
-
- # shows a learn more link
- expect(page).to have_link('Learn more', href: 'https://rubygems.org/')
- end
- end
- end
-
- context 'CONTRIBUTING.md' do
- before do
- file_name = 'CONTRIBUTING.md'
-
- create_file(file_name, '## Contribution guidelines')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("After you've reviewed these contribution guidelines, you'll be all set to contribute to this project.")
- end
- end
- end
-
- context 'CHANGELOG.md' do
- before do
- file_name = 'CHANGELOG.md'
-
- create_file(file_name, '## Changelog for v1.0.0')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("To find the state of this project's repository at the time of any of these versions, check out the tags.")
- end
- end
- end
-
- context 'Cargo.toml' do
- before do
- file_name = 'Cargo.toml'
-
- create_file(file_name, '
- [package]
- name = "hello_world" # the name of the package
- version = "0.1.0" # the current version, obeying semver
- authors = ["Alice <a@example.com>", "Bob <b@example.com>"]
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using Cargo.")
- end
- end
- end
-
- context 'Cartfile' do
- before do
- file_name = 'Cartfile'
-
- create_file(file_name, '
- gitlab "Alamofire/Alamofire" == 4.9.0
- gitlab "Alamofire/AlamofireImage" ~> 3.4
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using Carthage.")
- end
- end
- end
-
- context 'composer.json' do
- before do
- file_name = 'composer.json'
-
- create_file(file_name, '
- {
- "license": "MIT"
- }
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using Composer.")
- end
- end
- end
-
- context 'Gemfile' do
- before do
- file_name = 'Gemfile'
-
- create_file(file_name, '
- source "https://rubygems.org"
-
- # Gems here
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using Bundler.")
- end
- end
- end
-
- context 'Godeps.json' do
- before do
- file_name = 'Godeps.json'
-
- create_file(file_name, '
- {
- "GoVersion": "go1.6"
- }
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using godep.")
- end
- end
- end
-
- context 'go.mod' do
- before do
- file_name = 'go.mod'
-
- create_file(file_name, '
- module example.com/mymodule
-
- go 1.14
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using Go Modules.")
- end
- end
- end
-
- context 'package.json' do
- before do
- file_name = 'package.json'
-
- create_file(file_name, '
- {
- "name": "my-awesome-package",
- "version": "1.0.0"
- }
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using npm.")
- end
- end
- end
-
- context 'podfile' do
- before do
- file_name = 'podfile'
-
- create_file(file_name, 'platform :ios, "8.0"')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using CocoaPods.")
- end
- end
- end
-
- context 'test.podspec' do
- before do
- file_name = 'test.podspec'
-
- create_file(file_name, '
- Pod::Spec.new do |s|
- s.name = "TensorFlowLiteC"
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using CocoaPods.")
- end
- end
- end
-
- context 'JSON.podspec.json' do
- before do
- file_name = 'JSON.podspec.json'
-
- create_file(file_name, '
- {
- "name": "JSON"
- }
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using CocoaPods.")
- end
- end
- end
-
- context 'requirements.txt' do
- before do
- file_name = 'requirements.txt'
-
- create_file(file_name, 'Project requirements')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using pip.")
- end
- end
- end
-
- context 'yarn.lock' do
- before do
- file_name = 'yarn.lock'
-
- create_file(file_name, '
- # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
- # yarn lockfile v1
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using Yarn.")
- end
- end
- end
-
- context 'openapi.yml' do
- before do
- file_name = 'openapi.yml'
-
- create_file(file_name, '
- swagger: \'2.0\'
- info:
- title: Classic API Resource Documentation
- description: |
- <div class="foo-bar" style="background-color: red;" data-foo-bar="baz">
- <h1>Swagger API documentation</h1>
- </div>
- version: production
- basePath: /JSSResource/
- produces:
- - application/xml
- - application/json
- consumes:
- - application/xml
- - application/json
- security:
- - basicAuth: []
- paths:
- /accounts:
- get:
- responses:
- \'200\':
- description: No response was specified
- tags:
- - accounts
- operationId: findAccounts
- summary: Finds all accounts
- ')
- visit_blob(file_name, useUnsafeMarkdown: '1')
- click_button('Display rendered file')
-
- wait_for_requests
- end
-
- it 'removes `style`, `class`, and `data-*`` attributes from HTML' do
- expect(page).to have_css('h1', text: 'Swagger API documentation')
- expect(page).not_to have_css('.foo-bar')
- expect(page).not_to have_css('[style="background-color: red;"]')
- expect(page).not_to have_css('[data-foo-bar="baz"]')
- end
- end
- end
end
end
diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb
index 3f1c10b3688..54176378de8 100644
--- a/spec/features/projects/blobs/edit_spec.rb
+++ b/spec/features/projects/blobs/edit_spec.rb
@@ -183,7 +183,7 @@ RSpec.describe 'Editing file blob', :js do
freeze_time do
visit project_edit_blob_path(project, tree_join(protected_branch, file_path))
- epoch = Time.now.strftime('%s%L').last(5)
+ epoch = Time.zone.now.strftime('%s%L').last(5)
expect(find('.js-branch-name').value).to eq "#{user.username}-protected-branch-patch-#{epoch}"
end
diff --git a/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb b/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb
index b872fa701c8..15e7a495e60 100644
--- a/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb
+++ b/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb
@@ -19,14 +19,14 @@ RSpec.describe 'User views pipeline editor button on root ci config file', :js d
project.repository.create_file(user, project.ci_config_path_or_default, 'test', message: 'testing', branch_name: 'master')
visit project_blob_path(project, File.join('master', '.my-config.yml'))
- expect(page).to have_content('Pipeline Editor')
+ expect(page).to have_content('Edit in pipeline editor')
end
it 'does not shows the Pipeline Editor button' do
project.repository.create_file(user, '.my-sub-config.yml', 'test', message: 'testing', branch_name: 'master')
visit project_blob_path(project, File.join('master', '.my-sub-config.yml'))
- expect(page).not_to have_content('Pipeline Editor')
+ expect(page).not_to have_content('Edit in pipeline editor')
end
end
@@ -36,7 +36,7 @@ RSpec.describe 'User views pipeline editor button on root ci config file', :js d
end
it 'does not shows the Pipeline Editor button' do
visit project_blob_path(project, File.join('master', '.my-config.yml'))
- expect(page).not_to have_content('Pipeline Editor')
+ expect(page).not_to have_content('Edit in pipeline editor')
end
end
end
diff --git a/spec/features/projects/ci/editor_spec.rb b/spec/features/projects/ci/editor_spec.rb
index daf5ac61d73..ad4381a526a 100644
--- a/spec/features/projects/ci/editor_spec.rb
+++ b/spec/features/projects/ci/editor_spec.rb
@@ -55,6 +55,10 @@ RSpec.describe 'Pipeline Editor', :js do
it 'displays new branch as selected after commiting on a new branch' do
find('#target-branch-field').set('new_branch', clear: :backspace)
+ page.within('#source-editor-') do
+ find('textarea').send_keys '123'
+ end
+
click_button 'Commit changes'
page.within('[data-testid="branch-selector"]') do
@@ -77,8 +81,6 @@ RSpec.describe 'Pipeline Editor', :js do
context 'when a change is made' do
before do
- click_button 'Collapse'
-
page.within('#source-editor-') do
find('textarea').send_keys '123'
# It takes some time after sending keys for the vue
@@ -123,8 +125,6 @@ RSpec.describe 'Pipeline Editor', :js do
describe 'Editor content' do
it 'user can reset their CI configuration' do
- click_button 'Collapse'
-
page.within('#source-editor-') do
find('textarea').send_keys '123'
end
@@ -147,8 +147,6 @@ RSpec.describe 'Pipeline Editor', :js do
end
it 'user can cancel reseting their CI configuration' do
- click_button 'Collapse'
-
page.within('#source-editor-') do
find('textarea').send_keys '123'
end
diff --git a/spec/features/projects/ci/secure_files_spec.rb b/spec/features/projects/ci/secure_files_spec.rb
new file mode 100644
index 00000000000..65c41eaf2ac
--- /dev/null
+++ b/spec/features/projects/ci/secure_files_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Secure Files', :js do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
+
+ visit project_ci_secure_files_path(project)
+ end
+
+ it 'user sees the Secure Files list component' do
+ expect(page).to have_content('There are no records to show')
+ end
+end
diff --git a/spec/features/projects/cluster_agents_spec.rb b/spec/features/projects/cluster_agents_spec.rb
index d2b07bbc1de..e9162359940 100644
--- a/spec/features/projects/cluster_agents_spec.rb
+++ b/spec/features/projects/cluster_agents_spec.rb
@@ -27,7 +27,7 @@ RSpec.describe 'ClusterAgents', :js do
end
it 'displays empty state', :aggregate_failures do
- expect(page).to have_content('Install new Agent')
+ expect(page).to have_content('Install a new agent')
expect(page).to have_selector('.empty-state')
end
end
diff --git a/spec/features/projects/clusters/eks_spec.rb b/spec/features/projects/clusters/eks_spec.rb
index a925e3a72f8..0dd6effe551 100644
--- a/spec/features/projects/clusters/eks_spec.rb
+++ b/spec/features/projects/clusters/eks_spec.rb
@@ -19,8 +19,8 @@ RSpec.describe 'AWS EKS Cluster', :js do
before do
visit project_clusters_path(project)
- click_link 'Certificate'
- click_link 'Connect with a certificate'
+ click_button(class: 'dropdown-toggle-split')
+ click_link 'Create a new cluster'
end
context 'when user creates a cluster on AWS EKS' do
@@ -28,10 +28,6 @@ RSpec.describe 'AWS EKS Cluster', :js do
click_link 'Amazon EKS'
end
- it 'user sees a form to create an EKS cluster' do
- expect(page).to have_content('Create new cluster on EKS')
- end
-
it 'highlights Amazon EKS logo' do
expect(page).to have_css('.js-create-aws-cluster-button.active')
end
diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb
index 0c9db24f1d8..90d7e2d02e9 100644
--- a/spec/features/projects/clusters/gcp_spec.rb
+++ b/spec/features/projects/clusters/gcp_spec.rb
@@ -33,9 +33,7 @@ RSpec.describe 'Gcp Cluster', :js do
before do
visit project_clusters_path(project)
- click_link 'Certificate'
- click_link 'Connect with a certificate'
- click_link 'Create new cluster'
+ visit_create_cluster_page
click_link 'Google GKE'
end
@@ -118,16 +116,7 @@ RSpec.describe 'Gcp Cluster', :js do
expect(page.find(:css, '.cluster-name').value).to eq(cluster.name)
end
- context 'when user disables the cluster' do
- before do
- page.find(:css, '.js-cluster-enable-toggle-area .js-project-feature-toggle').click
- page.within('.js-cluster-details-form') { click_button 'Save changes' }
- end
-
- it 'user sees the successful message' do
- expect(page).to have_content('Kubernetes cluster was successfully updated.')
- end
- end
+ include_examples "user disables a cluster"
context 'when user changes cluster parameters' do
before do
@@ -145,7 +134,6 @@ RSpec.describe 'Gcp Cluster', :js do
before do
visit project_clusters_path(project)
- click_link 'Certificate'
click_button(class: 'dropdown-toggle-split')
click_link 'Connect with a certificate'
end
@@ -175,7 +163,6 @@ RSpec.describe 'Gcp Cluster', :js do
context 'when user has not dismissed GCP signup offer' do
before do
visit project_clusters_path(project)
- click_link 'Certificate'
end
it 'user sees offer on cluster index page' do
@@ -183,7 +170,7 @@ RSpec.describe 'Gcp Cluster', :js do
end
it 'user sees offer on cluster create page' do
- click_link 'Connect with a certificate'
+ visit_create_cluster_page
expect(page).to have_css('.gcp-signup-offer')
end
@@ -201,7 +188,7 @@ RSpec.describe 'Gcp Cluster', :js do
find('.gcp-signup-offer .js-close').click
wait_for_requests
- click_link 'Connect with a certificate'
+ visit_create_cluster_page
expect(page).not_to have_css('.gcp-signup-offer')
end
@@ -230,4 +217,9 @@ RSpec.describe 'Gcp Cluster', :js do
expect(page).not_to have_css('.gcp-signup-offer')
end
end
+
+ def visit_create_cluster_page
+ click_button(class: 'dropdown-toggle-split')
+ click_link 'Create a new cluster'
+ end
end
diff --git a/spec/features/projects/clusters/user_spec.rb b/spec/features/projects/clusters/user_spec.rb
index d9887ea4fe0..3fd78d338da 100644
--- a/spec/features/projects/clusters/user_spec.rb
+++ b/spec/features/projects/clusters/user_spec.rb
@@ -27,7 +27,6 @@ RSpec.describe 'User Cluster', :js do
click_link 'Certificate'
click_link 'Connect with a certificate'
- click_link 'Connect existing cluster'
end
context 'when user filled form with valid parameters' do
@@ -82,16 +81,7 @@ RSpec.describe 'User Cluster', :js do
expect(page).to have_button('Save changes')
end
- context 'when user disables the cluster' do
- before do
- page.find(:css, '.js-cluster-enable-toggle-area .js-project-feature-toggle').click
- page.within('.js-cluster-details-form') { click_button 'Save changes' }
- end
-
- it 'user sees the successful message' do
- expect(page).to have_content('Kubernetes cluster was successfully updated.')
- end
- end
+ include_examples "user disables a cluster"
context 'when user changes cluster parameters' do
before do
diff --git a/spec/features/projects/clusters_spec.rb b/spec/features/projects/clusters_spec.rb
index b0406e1f3c4..b9a544144c3 100644
--- a/spec/features/projects/clusters_spec.rb
+++ b/spec/features/projects/clusters_spec.rb
@@ -34,17 +34,12 @@ RSpec.describe 'Clusters', :js do
before do
create(:cluster, :provided_by_user, name: 'default-cluster', environment_scope: '*', projects: [project])
visit project_clusters_path(project)
- click_link 'Certificate'
- click_button(class: 'dropdown-toggle-split')
- end
-
- it 'user sees an add cluster button' do
- expect(page).to have_content('Connect with a certificate')
end
context 'when user filled form with environment scope' do
before do
- click_link 'Connect with a certificate'
+ visit_connect_cluster_page
+
fill_in 'cluster_name', with: 'staging-cluster'
fill_in 'cluster_environment_scope', with: 'staging/*'
click_button 'Add Kubernetes cluster'
@@ -72,7 +67,8 @@ RSpec.describe 'Clusters', :js do
context 'when user updates duplicated environment scope' do
before do
- click_link 'Connect with a certificate'
+ visit_connect_cluster_page
+
fill_in 'cluster_name', with: 'staging-cluster'
fill_in 'cluster_environment_scope', with: '*'
fill_in 'cluster_platform_kubernetes_attributes_api_url', with: 'https://0.0.0.0'
@@ -115,8 +111,7 @@ RSpec.describe 'Clusters', :js do
context 'when user filled form with environment scope' do
before do
- click_button(class: 'dropdown-toggle-split')
- click_link 'Create a new cluster'
+ visit_create_cluster_page
click_link 'Google GKE'
sleep 2 # wait for ajax
@@ -160,8 +155,7 @@ RSpec.describe 'Clusters', :js do
context 'when user updates duplicated environment scope' do
before do
- click_button(class: 'dropdown-toggle-split')
- click_link 'Create a new cluster'
+ visit_create_cluster_page
click_link 'Google GKE'
sleep 2 # wait for ajax
@@ -212,11 +206,7 @@ RSpec.describe 'Clusters', :js do
context 'user visits create cluster page' do
before do
- visit project_clusters_path(project)
-
- click_link 'Certificate'
- click_link 'Connect with a certificate'
- click_link 'Create new cluster'
+ visit_create_cluster_page
end
it 'user sees a link to create a GKE cluster' do
@@ -227,4 +217,16 @@ RSpec.describe 'Clusters', :js do
expect(page).to have_link('Amazon EKS')
end
end
+
+ def visit_create_cluster_page
+ visit project_clusters_path(project)
+
+ click_button(class: 'dropdown-toggle-split')
+ click_link 'Create a new cluster'
+ end
+
+ def visit_connect_cluster_page
+ click_button(class: 'dropdown-toggle-split')
+ click_link 'Connect with a certificate'
+ end
end
diff --git a/spec/features/projects/commits/multi_view_diff_spec.rb b/spec/features/projects/commits/multi_view_diff_spec.rb
new file mode 100644
index 00000000000..ecdd398c739
--- /dev/null
+++ b/spec/features/projects/commits/multi_view_diff_spec.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.shared_examples "no multiple viewers" do |commit_ref|
+ let(:ref) { commit_ref }
+
+ it "does not display multiple diff viewers" do
+ expect(page).not_to have_selector '[data-diff-toggle-entity]'
+ end
+end
+
+RSpec.describe 'Multiple view Diffs', :js do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ let(:ref) { '5d6ed1503801ca9dc28e95eeb85a7cf863527aee' }
+ let(:path) { project_commit_path(project, ref) }
+ 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
+ include_examples "no multiple viewers", 'ddd0f15ae83993f5cb66a927a28673882e99100b'
+ end
+
+ context 'and diff has ipynb' do
+ include_examples "no multiple viewers", '5d6ed1503801ca9dc28e95eeb85a7cf863527aee'
+
+ it 'shows the transformed 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
+ end
+ end
+
+ context 'when :rendered_diffs_viewer is on' do
+ let(:feature_flag_on) { true }
+
+ context 'and diff does not include ipynb' do
+ include_examples "no multiple viewers", 'ddd0f15ae83993f5cb66a927a28673882e99100b'
+ end
+
+ context 'and opening a diff with ipynb' do
+ context 'but the changes are not renderable' do
+ include_examples "no multiple viewers", 'a867a602d2220e5891b310c07d174fbe12122830'
+ end
+
+ 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"]'
+
+ expect(classes_for_element(diff, 'toHide', visible: false)).to include('hidden')
+ expect(classes_for_element(diff, 'toShow')).not_to include('hidden')
+
+ expect(classes_for_element(diff, 'toShowBtn')).to include('selected')
+ expect(classes_for_element(diff, 'toHideBtn')).not_to include('selected')
+ 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"]'
+
+ expect(classes_for_element(diff, 'toHideBtn')).not_to include('selected')
+ expect(classes_for_element(diff, 'toShowBtn')).to include('selected')
+ end
+ end
+ end
+
+ def classes_for_element(node, data_diff_entity, visible: true)
+ node.find("[data-diff-toggle-entity=\"#{data_diff_entity}\"]", visible: visible)[:class]
+ end
+end
diff --git a/spec/features/projects/container_registry_spec.rb b/spec/features/projects/container_registry_spec.rb
index 4ebcb69592b..17eb421191f 100644
--- a/spec/features/projects/container_registry_spec.rb
+++ b/spec/features/projects/container_registry_spec.rb
@@ -103,6 +103,8 @@ RSpec.describe 'Container Registry', :js do
find('.modal .modal-footer .btn-danger').click
end
+ it_behaves_like 'rejecting tags destruction for an importing repository on', tags: ['1']
+
it('pagination navigate to the second page') do
visit_next_page
diff --git a/spec/features/projects/environments/environment_metrics_spec.rb b/spec/features/projects/environments/environment_metrics_spec.rb
index 0f858c627bc..f5f4d13dd58 100644
--- a/spec/features/projects/environments/environment_metrics_spec.rb
+++ b/spec/features/projects/environments/environment_metrics_spec.rb
@@ -18,7 +18,6 @@ RSpec.describe 'Environment > Metrics' do
stub_any_prometheus_request
sign_in(user)
- visit_environment(environment)
end
around do |example|
@@ -27,6 +26,7 @@ RSpec.describe 'Environment > Metrics' do
shared_examples 'has environment selector' do
it 'has a working environment selector', :js do
+ visit_environment(environment)
click_link 'Monitoring'
expect(page).to have_current_path(project_metrics_dashboard_path(project, environment: environment.id))
@@ -56,6 +56,7 @@ RSpec.describe 'Environment > Metrics' do
end
it 'shows metrics', :js do
+ visit_environment(environment)
click_link 'Monitoring'
expect(page).to have_css('[data-qa-selector="prometheus_graphs"]') # rubocop:disable QA/SelectorUsage
diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb
index 3b83c25b629..99137018d6b 100644
--- a/spec/features/projects/environments/environments_spec.rb
+++ b/spec/features/projects/environments/environments_spec.rb
@@ -3,12 +3,13 @@
require 'spec_helper'
RSpec.describe 'Environments page', :js do
+ include Spec::Support::Helpers::ModalHelpers
+
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:role) { :developer }
before do
- stub_feature_flags(new_environments_table: false)
project.add_role(user, role)
sign_in(user)
end
@@ -33,24 +34,18 @@ RSpec.describe 'Environments page', :js do
it 'shows "Available" and "Stopped" tab with links' do
visit_environments(project)
- expect(page).to have_selector('.js-environments-tab-available')
- expect(page).to have_content('Available')
- expect(page).to have_selector('.js-environments-tab-stopped')
- expect(page).to have_content('Stopped')
+ expect(page).to have_link(_('Available'))
+ expect(page).to have_link(_('Stopped'))
end
describe 'with one available environment' do
- before do
- create(:environment, project: project, state: :available)
- end
+ let!(:environment) { create(:environment, project: project, state: :available) }
describe 'in available tab page' do
it 'shows one environment' do
visit_environments(project, scope: 'available')
- expect(page).to have_css('.environments-container')
- expect(page.all('.environment-name').length).to eq(1)
- expect(page.all('[data-testid="stop-icon"]').length).to eq(1)
+ expect(page).to have_link(environment.name, href: project_environment_path(project, environment))
end
end
@@ -75,7 +70,6 @@ RSpec.describe 'Environments page', :js do
it 'shows no environments' do
visit_environments(project, scope: 'stopped')
- expect(page).to have_css('.environments-container')
expect(page).to have_content('You don\'t have any environments right now')
end
end
@@ -93,22 +87,18 @@ RSpec.describe 'Environments page', :js do
it 'shows one environment without error' do
visit_environments(project, scope: 'available')
- expect(page).to have_css('.environments-container')
- expect(page.all('.environment-name').length).to eq(1)
+ expect(page).to have_link(environment.name, href: project_environment_path(project, environment))
end
end
end
describe 'with one stopped environment' do
- before do
- create(:environment, project: project, state: :stopped)
- end
+ let!(:environment) { create(:environment, project: project, state: :stopped) }
describe 'in available tab page' do
it 'shows no environments' do
visit_environments(project, scope: 'available')
- expect(page).to have_css('.environments-container')
expect(page).to have_content('You don\'t have any environments right now')
end
end
@@ -117,8 +107,7 @@ RSpec.describe 'Environments page', :js do
it 'shows one environment' do
visit_environments(project, scope: 'stopped')
- expect(page).to have_css('.environments-container')
- expect(page.all('.environment-name').length).to eq(1)
+ expect(page).to have_link(environment.name, href: project_environment_path(project, environment))
expect(page.all('[data-testid="stop-icon"]').length).to eq(0)
end
end
@@ -133,8 +122,8 @@ RSpec.describe 'Environments page', :js do
it 'does not show environments and counters are set to zero' do
expect(page).to have_content('You don\'t have any environments right now')
- expect(page.find('.js-environments-tab-available .badge').text).to eq('0')
- expect(page.find('.js-environments-tab-stopped .badge').text).to eq('0')
+ expect(page).to have_link("#{_('Available')} 0")
+ expect(page).to have_link("#{_('Stopped')} 0")
end
end
@@ -148,21 +137,23 @@ RSpec.describe 'Environments page', :js do
context 'when there are no deployments' do
before do
visit_environments(project)
+
+ page.click_button _('Expand')
end
it 'shows environments names and counters' do
- expect(page).to have_link(environment.name)
+ expect(page).to have_link(environment.name, href: project_environment_path(project, environment))
- expect(page.find('.js-environments-tab-available .badge').text).to eq('1')
- expect(page.find('.js-environments-tab-stopped .badge').text).to eq('0')
+ expect(page).to have_link("#{_('Available')} 1")
+ expect(page).to have_link("#{_('Stopped')} 0")
end
it 'does not show deployments' do
- expect(page).to have_content('No deployments yet')
+ expect(page).to have_content(s_('Environments|There are no deployments for this environment yet. Learn more about setting up deployments.'))
end
it 'shows stop button when environment is not stoppable' do
- expect(page).to have_selector(stop_button_selector)
+ expect(page).to have_button('Stop')
end
end
@@ -177,8 +168,10 @@ RSpec.describe 'Environments page', :js do
it 'shows deployment SHA and internal ID' do
visit_environments(project)
+ page.click_button _('Expand')
- expect(page).to have_link(deployment.short_sha)
+ expect(page).to have_text(deployment.short_sha)
+ expect(page).to have_link(deployment.commit.full_title)
expect(page).to have_content(deployment.iid)
end
@@ -216,10 +209,6 @@ RSpec.describe 'Environments page', :js do
.not_to change { Ci::Pipeline.count }
end
- it 'shows build name and id' do
- expect(page).to have_link("#{build.name} ##{build.id}")
- end
-
it 'shows a stop button' do
expect(page).to have_selector(stop_button_selector)
end
@@ -346,7 +335,9 @@ RSpec.describe 'Environments page', :js do
context 'when user played a delayed job immediately' do
before do
find(actions_button_selector).click
- accept_confirm { find(action_link_selector).click }
+ accept_gl_confirm do
+ find(action_link_selector).click
+ end
wait_for_requests
end
@@ -369,7 +360,8 @@ RSpec.describe 'Environments page', :js do
it 'does not show deployments' do
visit_environments(project)
- expect(page).to have_content('No deployments yet')
+ page.click_button _('Expand')
+ expect(page).to have_content(s_('Environments|There are no deployments for this environment yet. Learn more about setting up deployments.'))
end
end
@@ -385,9 +377,10 @@ RSpec.describe 'Environments page', :js do
it "renders the upcoming deployment", :aggregate_failures do
visit_environments(project)
+ page.click_button _('Expand')
+
within(upcoming_deployment_content_selector) do
expect(page).to have_content("##{deployment.iid}")
- expect(page).to have_selector("a[href=\"#{project_job_path(project, deployment.deployable)}\"]")
expect(page).to have_link(href: /#{deployment.user.username}/)
end
end
@@ -409,15 +402,15 @@ RSpec.describe 'Environments page', :js do
let(:role) { :developer }
it 'developer creates a new environment with a valid name' do
- within(".environments-section") { click_link 'New environment' }
+ click_link 'New environment'
fill_in('Name', with: 'production')
click_on 'Save'
expect(page).to have_content('production')
end
- it 'developer creates a new environmetn with invalid name' do
- within(".environments-section") { click_link 'New environment' }
+ it 'developer creates a new environment with invalid name' do
+ click_link 'New environment'
fill_in('Name', with: 'name,with,commas')
click_on 'Save'
@@ -454,20 +447,11 @@ RSpec.describe 'Environments page', :js do
expect(page).not_to have_content 'review-2'
expect(page).to have_content 'staging 2'
- within('.folder-row') do
- find('.folder-name', text: 'staging').click
- end
+ page.click_button _('Expand')
expect(page).to have_content 'review-1'
expect(page).to have_content 'review-2'
- within('.ci-table') do
- within('[data-qa-selector="environment_item"]', text: 'review-1') do # rubocop:disable QA/SelectorUsage
- expect(find('.js-auto-stop').text).not_to be_empty
- end
- within('[data-qa-selector="environment_item"]', text: 'review-2') do # rubocop:disable QA/SelectorUsage
- expect(find('.js-auto-stop').text).not_to be_empty
- end
- end
+ expect(page).to have_content 'Auto stop in'
end
end
@@ -490,9 +474,7 @@ RSpec.describe 'Environments page', :js do
expect(page).not_to have_content 'review-2'
expect(page).to have_content 'staging 2'
- within('.folder-row') do
- find('.folder-name', text: 'staging').click
- end
+ page.click_button _('Expand')
expect(page).to have_content 'review-1'
expect(page).to have_content 'review-2'
diff --git a/spec/features/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/projects/files/project_owner_creates_license_file_spec.rb
index 4a0b1f4c548..c9ba8cbd2bb 100644
--- a/spec/features/projects/files/project_owner_creates_license_file_spec.rb
+++ b/spec/features/projects/files/project_owner_creates_license_file_spec.rb
@@ -26,23 +26,23 @@ RSpec.describe 'Projects > Files > Project owner creates a license file', :js do
file_content = first('.file-editor')
expect(file_content).to have_content('MIT License')
- expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
+ expect(file_content).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
fill_in :commit_message, with: 'Add a LICENSE file', visible: true
click_button 'Commit changes'
- expect(current_path).to eq(
- project_blob_path(project, 'master/LICENSE'))
+ expect(page).to have_current_path(
+ project_blob_path(project, 'master/LICENSE'), ignore_query: true)
expect(page).to have_content('MIT License')
- expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
+ expect(page).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
end
it 'project maintainer creates a license file from the "Add license" link' do
click_link 'Add LICENSE'
expect(page).to have_content('New file')
- expect(current_path).to eq(
- project_new_blob_path(project, 'master'))
+ expect(page).to have_current_path(
+ project_new_blob_path(project, 'master'), ignore_query: true)
expect(find('#file_name').value).to eq('LICENSE')
expect(page).to have_selector('.license-selector')
@@ -50,15 +50,15 @@ RSpec.describe 'Projects > Files > Project owner creates a license file', :js do
file_content = first('.file-editor')
expect(file_content).to have_content('MIT License')
- expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
+ expect(file_content).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
fill_in :commit_message, with: 'Add a LICENSE file', visible: true
click_button 'Commit changes'
- expect(current_path).to eq(
- project_blob_path(project, 'master/LICENSE'))
+ expect(page).to have_current_path(
+ project_blob_path(project, 'master/LICENSE'), ignore_query: true)
expect(page).to have_content('MIT License')
- expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
+ expect(page).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
end
def select_template(template)
diff --git a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
index ca384291c12..0e87622d3c2 100644
--- a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
+++ b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
@@ -16,24 +16,24 @@ RSpec.describe 'Projects > Files > Project owner sees a link to create a license
visit project_path(project)
click_on 'Add LICENSE'
- expect(current_path).to eq("/-/ide/project/#{project.full_path}/edit/master/-/LICENSE")
+ expect(page).to have_current_path("/-/ide/project/#{project.full_path}/edit/master/-/LICENSE", ignore_query: true)
expect(page).to have_selector('.qa-file-templates-bar') # rubocop:disable QA/SelectorUsage
select_template('MIT License')
expect(ide_editor_value).to have_content('MIT License')
- expect(ide_editor_value).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
+ expect(ide_editor_value).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
ide_commit
- expect(current_path).to eq("/-/ide/project/#{project.full_path}/tree/master/-/LICENSE/")
+ expect(page).to have_current_path("/-/ide/project/#{project.full_path}/tree/master/-/LICENSE/", ignore_query: true)
expect(page).to have_content('All changes are committed')
license_file = project.repository.blob_at('master', 'LICENSE').data
expect(license_file).to have_content('MIT License')
- expect(license_file).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
+ expect(license_file).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
end
def select_template(template)
diff --git a/spec/features/projects/files/user_browses_files_spec.rb b/spec/features/projects/files/user_browses_files_spec.rb
index 9b4d1502bc8..53fdd5a15dd 100644
--- a/spec/features/projects/files/user_browses_files_spec.rb
+++ b/spec/features/projects/files/user_browses_files_spec.rb
@@ -76,7 +76,7 @@ RSpec.describe "User browses files", :js do
permalink_path = project_blob_path(project, "#{project.repository.commit.sha}/.gitignore")
- expect(current_path).to eq(permalink_path)
+ expect(page).to have_current_path(permalink_path, ignore_query: true)
end
end
@@ -87,7 +87,7 @@ RSpec.describe "User browses files", :js do
end
it "shows correct files and links" do
- expect(current_path).to eq(project_tree_path(project, "markdown"))
+ expect(page).to have_current_path(project_tree_path(project, "markdown"), ignore_query: true)
expect(page).to have_content("README.md")
.and have_content("CHANGELOG")
.and have_content("Welcome to GitLab GitLab is a free project and repository management application")
@@ -108,7 +108,7 @@ RSpec.describe "User browses files", :js do
it "shows correct content of file" do
click_link("GitLab API doc")
- expect(current_path).to eq(project_blob_path(project, "markdown/doc/api/README.md"))
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/api/README.md"), ignore_query: true)
expect(page).to have_content("All API requests require authentication")
.and have_content("Contents")
.and have_link("Users")
@@ -117,19 +117,19 @@ RSpec.describe "User browses files", :js do
click_link("Users")
- expect(current_path).to eq(project_blob_path(project, "markdown/doc/api/users.md"))
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/api/users.md"), ignore_query: true)
expect(page).to have_content("Get a list of users.")
page.go_back
click_link("Rake tasks")
- expect(current_path).to eq(project_tree_path(project, "markdown/doc/raketasks"))
+ expect(page).to have_current_path(project_tree_path(project, "markdown/doc/raketasks"), ignore_query: true)
expect(page).to have_content("backup_restore.md").and have_content("maintenance.md")
click_link("maintenance.md")
- expect(current_path).to eq(project_blob_path(project, "markdown/doc/raketasks/maintenance.md"))
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/raketasks/maintenance.md"), ignore_query: true)
expect(page).to have_content("bundle exec rake gitlab:env:info RAILS_ENV=production")
click_link("shop")
@@ -156,12 +156,12 @@ RSpec.describe "User browses files", :js do
it "shows correct content of directory" do
click_link("GitLab API doc directory")
- expect(current_path).to eq(project_tree_path(project, "markdown/doc/api"))
+ expect(page).to have_current_path(project_tree_path(project, "markdown/doc/api"), ignore_query: true)
expect(page).to have_content("README.md").and have_content("users.md")
click_link("Users")
- expect(current_path).to eq(project_blob_path(project, "markdown/doc/api/users.md"))
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/api/users.md"), ignore_query: true)
expect(page).to have_content("List users").and have_content("Get a list of users.")
end
end
@@ -267,7 +267,7 @@ RSpec.describe "User browses files", :js do
end
it "shows files from a repository for `6d39438`" do
- expect(current_path).to eq(ref)
+ expect(page).to have_current_path(ref, ignore_query: true)
expect(page).to have_content(".gitignore").and have_content("LICENSE")
end
diff --git a/spec/features/projects/files/user_browses_lfs_files_spec.rb b/spec/features/projects/files/user_browses_lfs_files_spec.rb
index 3976df849fa..56e18871810 100644
--- a/spec/features/projects/files/user_browses_lfs_files_spec.rb
+++ b/spec/features/projects/files/user_browses_lfs_files_spec.rb
@@ -72,24 +72,7 @@ RSpec.describe 'Projects > Files > User browses LFS files' do
expect(page).not_to have_content('Blame')
expect(page).not_to have_selector(:link_or_button, text: /^Edit$/)
- expect(page).to have_selector(:link_or_button, 'Edit in Web IDE')
- end
- end
-
- context 'when feature flag :consolidated_edit_button is off' do
- before do
- stub_feature_flags(consolidated_edit_button: false)
-
- click_link('files')
- click_link('lfs')
- click_link('lfs_object.iso')
- end
-
- it 'does not show single file edit link' do
- page.within('.content') do
- expect(page).to have_selector(:link_or_button, 'Web IDE')
- expect(page).not_to have_css('button[data-testid="edit"')
- end
+ expect(page).to have_selector(:link_or_button, 'Open in Web IDE')
end
end
end
diff --git a/spec/features/projects/files/user_creates_directory_spec.rb b/spec/features/projects/files/user_creates_directory_spec.rb
index 5ad7641a5be..9e0168d7ef3 100644
--- a/spec/features/projects/files/user_creates_directory_spec.rb
+++ b/spec/features/projects/files/user_creates_directory_spec.rb
@@ -42,7 +42,7 @@ RSpec.describe 'Projects > Files > User creates a directory', :js do
click_button('Create directory')
expect(page).to have_content('A directory with this name already exists')
- expect(current_path).to eq(project_tree_path(project, 'master'))
+ expect(page).to have_current_path(project_tree_path(project, 'master'), ignore_query: true)
end
end
@@ -81,7 +81,7 @@ RSpec.describe 'Projects > Files > User creates a directory', :js do
expect(page).to have_content('From new-feature into master')
expect(page).to have_content('Add new directory')
- expect(current_path).to eq(project_new_merge_request_path(project))
+ expect(page).to have_current_path(project_new_merge_request_path(project), ignore_query: true)
end
end
@@ -107,7 +107,7 @@ RSpec.describe 'Projects > Files > User creates a directory', :js do
fork = user.fork_of(project2.reload)
wait_for_requests
- expect(current_path).to eq(project_new_merge_request_path(fork))
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
end
end
end
diff --git a/spec/features/projects/files/user_creates_files_spec.rb b/spec/features/projects/files/user_creates_files_spec.rb
index 7159418deda..7344c91b6dc 100644
--- a/spec/features/projects/files/user_creates_files_spec.rb
+++ b/spec/features/projects/files/user_creates_files_spec.rb
@@ -97,7 +97,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
new_file_path = project_blob_path(project, 'master/not_a_file.md')
- expect(current_path).to eq(new_file_path)
+ expect(page).to have_current_path(new_file_path, ignore_query: true)
wait_for_requests
@@ -115,7 +115,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
new_file_path = project_blob_path(project, 'master/not_a_file.md')
- expect(current_path).to eq(new_file_path)
+ expect(page).to have_current_path(new_file_path, ignore_query: true)
click_link('Edit')
@@ -133,7 +133,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
fill_in(:commit_message, with: 'New commit message', visible: true)
click_button('Commit changes')
- expect(current_path).to eq(project_blob_path(project, 'master/foo/bar/baz.txt'))
+ expect(page).to have_current_path(project_blob_path(project, 'master/foo/bar/baz.txt'), ignore_query: true)
wait_for_requests
@@ -150,7 +150,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
fill_in(:branch_name, with: 'new_branch_name', visible: true)
click_button('Commit changes')
- expect(current_path).to eq(project_new_merge_request_path(project))
+ expect(page).to have_current_path(project_new_merge_request_path(project), ignore_query: true)
click_link('Changes')
@@ -187,7 +187,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
fork = user.fork_of(project2.reload)
- expect(current_path).to eq(project_new_merge_request_path(fork))
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
expect(page).to have_content('New commit message')
end
end
diff --git a/spec/features/projects/files/user_deletes_files_spec.rb b/spec/features/projects/files/user_deletes_files_spec.rb
index c508b2ddba9..806f1e8e9ed 100644
--- a/spec/features/projects/files/user_deletes_files_spec.rb
+++ b/spec/features/projects/files/user_deletes_files_spec.rb
@@ -15,7 +15,6 @@ RSpec.describe 'Projects > Files > User deletes files', :js do
let(:user) { create(:user) }
before do
- stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/349953
sign_in(user)
end
@@ -35,7 +34,7 @@ RSpec.describe 'Projects > Files > User deletes files', :js do
fill_in(:commit_message, with: 'New commit message', visible: true)
click_button('Delete file')
- expect(current_path).to eq(project_tree_path(project, 'master/'))
+ expect(page).to have_current_path(project_tree_path(project, 'master/'), ignore_query: true)
expect(page).not_to have_content('.gitignore')
end
end
@@ -67,7 +66,7 @@ RSpec.describe 'Projects > Files > User deletes files', :js do
fork = user.fork_of(project2.reload)
- expect(current_path).to eq(project_new_merge_request_path(fork))
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
expect(page).to have_content('New commit message')
end
end
diff --git a/spec/features/projects/files/user_edits_files_spec.rb b/spec/features/projects/files/user_edits_files_spec.rb
index 2b4ac3dc1d8..1ac45970828 100644
--- a/spec/features/projects/files/user_edits_files_spec.rb
+++ b/spec/features/projects/files/user_edits_files_spec.rb
@@ -77,7 +77,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
fill_in(:commit_message, with: 'New commit message', visible: true)
click_button('Commit changes')
- expect(current_path).to eq(project_blob_path(project, 'master/.gitignore'))
+ expect(page).to have_current_path(project_blob_path(project, 'master/.gitignore'), ignore_query: true)
wait_for_requests
@@ -97,7 +97,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
fill_in(:branch_name, with: 'new_branch_name', visible: true)
click_button('Commit changes')
- expect(current_path).to eq(project_new_merge_request_path(project))
+ expect(page).to have_current_path(project_new_merge_request_path(project), ignore_query: true)
click_link('Changes')
@@ -194,7 +194,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
fork = user.fork_of(project2.reload)
- expect(current_path).to eq(project_new_merge_request_path(fork))
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
wait_for_requests
@@ -223,7 +223,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
fork = user.fork_of(project2)
- expect(current_path).to eq(project_new_merge_request_path(fork))
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
wait_for_requests
@@ -236,116 +236,5 @@ RSpec.describe 'Projects > Files > User edits files', :js do
let(:project) { project2 }
end
end
-
- context 'when feature flag :consolidated_edit_button is off' do
- before do
- stub_feature_flags(consolidated_edit_button: false)
- end
-
- context 'when an user does not have write access', :js do
- before do
- project2.add_reporter(user)
- visit(project2_tree_path_root_ref)
- wait_for_requests
- end
-
- it 'inserts a content of a file in a forked project', :sidekiq_might_not_need_inline do
- set_default_button('edit')
- click_link('.gitignore')
- click_link_or_button('Edit')
-
- expect_fork_prompt
-
- click_link_or_button('Fork')
-
- expect_fork_status
-
- find('.file-editor', match: :first)
-
- find('#editor')
- set_editor_value('*.rbca')
-
- expect(editor_value).to eq('*.rbca')
- end
-
- it 'opens the Web IDE in a forked project', :sidekiq_might_not_need_inline do
- set_default_button('webide')
- click_link('.gitignore')
- click_link_or_button('Web IDE')
-
- expect_fork_prompt
-
- click_link_or_button('Fork')
-
- expect_fork_status
-
- expect(page).to have_css('.ide-sidebar-project-title', text: "#{project2.name} #{user.namespace.full_path}/#{project2.path}")
- expect(page).to have_css('.ide .multi-file-tab', text: '.gitignore')
- end
-
- it 'commits an edited file in a forked project', :sidekiq_might_not_need_inline do
- set_default_button('edit')
- click_link('.gitignore')
- click_link_or_button('Edit')
-
- expect_fork_prompt
-
- click_link_or_button('Fork')
-
- expect_fork_status
-
- find('.file-editor', match: :first)
-
- find('#editor')
- set_editor_value('*.rbca')
- fill_in(:commit_message, with: 'New commit message', visible: true)
- click_button('Commit changes')
-
- fork = user.fork_of(project2.reload)
-
- expect(current_path).to eq(project_new_merge_request_path(fork))
-
- wait_for_requests
-
- expect(page).to have_content('New commit message')
- end
-
- context 'when the user already had a fork of the project', :js do
- let!(:forked_project) { fork_project(project2, user, namespace: user.namespace, repository: true) }
-
- before do
- visit(project2_tree_path_root_ref)
- wait_for_requests
- end
-
- it 'links to the forked project for editing', :sidekiq_might_not_need_inline do
- set_default_button('edit')
- click_link('.gitignore')
- click_link_or_button('Edit')
-
- expect(page).not_to have_link('Fork')
-
- find('#editor')
- set_editor_value('*.rbca')
- fill_in(:commit_message, with: 'Another commit', visible: true)
- click_button('Commit changes')
-
- fork = user.fork_of(project2)
-
- expect(current_path).to eq(project_new_merge_request_path(fork))
-
- wait_for_requests
-
- expect(page).to have_content('Another commit')
- expect(page).to have_content("From #{forked_project.full_path}")
- expect(page).to have_content("into #{project2.full_path}")
- end
-
- it_behaves_like 'unavailable for an archived project' do
- let(:project) { project2 }
- end
- end
- end
- end
end
end
diff --git a/spec/features/projects/files/user_replaces_files_spec.rb b/spec/features/projects/files/user_replaces_files_spec.rb
index fe9520fffc8..1ecd50b6463 100644
--- a/spec/features/projects/files/user_replaces_files_spec.rb
+++ b/spec/features/projects/files/user_replaces_files_spec.rb
@@ -17,7 +17,6 @@ RSpec.describe 'Projects > Files > User replaces files', :js do
let(:user) { create(:user) }
before do
- stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/349953
sign_in(user)
end
@@ -34,9 +33,9 @@ RSpec.describe 'Projects > Files > User replaces files', :js do
expect(page).to have_content('.gitignore')
click_on('Replace')
- drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
+ find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
- page.within('#modal-upload-blob') do
+ page.within('#modal-replace-blob') do
fill_in(:commit_message, with: 'Replacement file commit message')
end
@@ -70,9 +69,9 @@ RSpec.describe 'Projects > Files > User replaces files', :js do
expect(page).to have_content(fork_message)
click_on('Replace')
- drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
+ find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
- page.within('#modal-upload-blob') do
+ page.within('#modal-replace-blob') do
fill_in(:commit_message, with: 'Replacement file commit message')
end
@@ -82,7 +81,7 @@ RSpec.describe 'Projects > Files > User replaces files', :js do
fork = user.fork_of(project2.reload)
- expect(current_path).to eq(project_new_merge_request_path(fork))
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
click_link('Changes')
diff --git a/spec/features/projects/fork_spec.rb b/spec/features/projects/fork_spec.rb
index f9a6b67e469..fb27f0961b6 100644
--- a/spec/features/projects/fork_spec.rb
+++ b/spec/features/projects/fork_spec.rb
@@ -164,199 +164,4 @@ RSpec.describe 'Project fork' do
end
end
end
-
- context 'with fork_project_form feature flag disabled' do
- before do
- stub_feature_flags(fork_project_form: false)
- sign_in(user)
- end
-
- it_behaves_like 'fork button on project page'
-
- context 'user has exceeded personal project limit' do
- before do
- user.update!(projects_limit: 0)
- end
-
- context 'with a group to fork to' do
- let!(:group) { create(:group).tap { |group| group.add_owner(user) } }
-
- it 'allows user to fork only to the group on fork page', :js do
- visit new_project_fork_path(project)
-
- to_personal_namespace = find('[data-qa-selector=fork_namespace_button].disabled') # rubocop:disable QA/SelectorUsage
- to_group = find(".fork-groups button[data-qa-name=#{group.name}]") # rubocop:disable QA/SelectorUsage
-
- expect(to_personal_namespace).not_to be_nil
- expect(to_group).not_to be_disabled
- end
- end
- end
-
- it_behaves_like 'create fork page', ' Select a namespace to fork the project '
-
- it 'forks the project', :sidekiq_might_not_need_inline do
- visit project_path(project)
-
- click_link 'Fork'
-
- page.within '.fork-thumbnail-container' do
- click_link 'Select'
- end
-
- expect(page).to have_content 'Forked from'
-
- visit project_path(project)
-
- expect(page).to have_content(/new merge request/i)
-
- page.within '.nav-sidebar' do
- first(:link, 'Merge requests').click
- end
-
- expect(page).to have_content(/new merge request/i)
-
- page.within '#content-body' do
- click_link('New merge request')
- end
-
- expect(current_path).to have_content(/#{user.namespace.path}/i)
- end
-
- it 'shows avatars when Gravatar is disabled' do
- stub_application_setting(gravatar_enabled: false)
-
- visit project_path(project)
-
- click_link 'Fork'
-
- page.within('.fork-thumbnail-container') do
- expect(page).to have_css('span.identicon')
- end
- end
-
- it 'shows the forked project on the list' do
- visit project_path(project)
-
- click_link 'Fork'
-
- page.within '.fork-thumbnail-container' do
- click_link 'Select'
- end
-
- visit project_forks_path(project)
-
- forked_project = user.fork_of(project.reload)
-
- page.within('.js-projects-list-holder') do
- expect(page).to have_content("#{forked_project.namespace.human_name} / #{forked_project.name}")
- end
-
- forked_project.update!(path: 'test-crappy-path')
-
- visit project_forks_path(project)
-
- page.within('.js-projects-list-holder') do
- expect(page).to have_content("#{forked_project.namespace.human_name} / #{forked_project.name}")
- end
- end
-
- context 'when the project is private' do
- let(:project) { create(:project, :repository) }
- let(:another_user) { create(:user, name: 'Mike') }
-
- before do
- project.add_reporter(user)
- project.add_reporter(another_user)
- end
-
- it 'renders private forks of the project' do
- visit project_path(project)
-
- another_project_fork = Projects::ForkService.new(project, another_user).execute
-
- click_link 'Fork'
-
- page.within '.fork-thumbnail-container' do
- click_link 'Select'
- end
-
- visit project_forks_path(project)
-
- page.within('.js-projects-list-holder') do
- user_project_fork = user.fork_of(project.reload)
- expect(page).to have_content("#{user_project_fork.namespace.human_name} / #{user_project_fork.name}")
- end
-
- expect(page).not_to have_content("#{another_project_fork.namespace.human_name} / #{another_project_fork.name}")
- end
- end
-
- context 'when the user already forked the project' do
- before do
- create(:project, :repository, name: project.name, namespace: user.namespace)
- end
-
- it 'renders error' do
- visit project_path(project)
-
- click_link 'Fork'
-
- page.within '.fork-thumbnail-container' do
- click_link 'Select'
- end
-
- expect(page).to have_content "Name has already been taken"
- end
- end
-
- context 'maintainer in group' do
- let(:group) { create(:group) }
-
- before do
- group.add_maintainer(user)
- end
-
- it 'allows user to fork project to group or to user namespace', :js do
- visit project_path(project)
- wait_for_requests
-
- expect(page).not_to have_css('a.disabled', text: 'Fork')
-
- click_link 'Fork'
-
- expect(page).to have_css('.fork-thumbnail')
- expect(page).to have_css('.group-row')
- expect(page).not_to have_css('.fork-thumbnail.disabled')
- end
-
- it 'allows user to fork project to group and not user when exceeded project limit', :js do
- user.projects_limit = 0
- user.save!
-
- visit project_path(project)
- wait_for_requests
-
- expect(page).not_to have_css('a.disabled', text: 'Fork')
-
- click_link 'Fork'
-
- expect(page).to have_css('.fork-thumbnail.disabled')
- expect(page).to have_css('.group-row')
- end
-
- it 'links to the fork if the project was already forked within that namespace', :sidekiq_might_not_need_inline, :js do
- forked_project = fork_project(project, user, namespace: group, repository: true)
-
- visit new_project_fork_path(project)
- wait_for_requests
-
- expect(page).to have_css('.group-row a.btn', text: 'Go to fork')
-
- click_link 'Go to fork'
-
- expect(current_path).to eq(project_path(forked_project))
- end
- 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 b9c2c539899..2821f35f6a6 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(current_path).to eq(edit_project_integration_path(project, tracker.parameterize(separator: '_')))
+ expect(page).to have_current_path(edit_project_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(current_path).to eq(edit_project_integration_path(project, tracker.parameterize(separator: '_')))
+ expect(page).to have_current_path(edit_project_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(current_path).to eq(edit_project_integration_path(project, tracker.parameterize(separator: '_')))
+ expect(page).to have_current_path(edit_project_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_jetbrains_teamcity_ci_spec.rb b/spec/features/projects/integrations/user_activates_jetbrains_teamcity_ci_spec.rb
index e6f2e462b8c..f86a1b8a0a4 100644
--- a/spec/features/projects/integrations/user_activates_jetbrains_teamcity_ci_spec.rb
+++ b/spec/features/projects/integrations/user_activates_jetbrains_teamcity_ci_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe 'User activates JetBrains TeamCity CI' do
it 'activates integration', :js do
visit_project_integration('JetBrains TeamCity')
check('Push')
- check('Merge Request')
+ check('Merge request')
fill_in('TeamCity server URL', with: 'http://teamcity.example.com')
fill_in('Build type', with: 'GitlabTest_Build')
fill_in('Username', with: 'user')
diff --git a/spec/features/projects/integrations/user_activates_jira_spec.rb b/spec/features/projects/integrations/user_activates_jira_spec.rb
index 7562dc00092..f855d6befe7 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(current_path).to eq(edit_project_integration_path(project, :jira))
+ expect(page).to have_current_path(edit_project_integration_path(project, :jira), ignore_query: true)
end
unless Gitlab.ee?
@@ -55,7 +55,7 @@ RSpec.describe 'User activates Jira', :js do
click_test_then_save_integration
expect(page).to have_content('Jira settings saved and active.')
- expect(current_path).to eq(edit_project_integration_path(project, :jira))
+ expect(page).to have_current_path(edit_project_integration_path(project, :jira), ignore_query: true)
end
end
end
@@ -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(current_path).to eq(edit_project_integration_path(project, :jira))
+ expect(page).to have_current_path(edit_project_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_slack_slash_command_spec.rb b/spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb
index 7ec469070ea..0b4c9620bdf 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,7 @@ RSpec.describe 'Slack slash commands', :js do
click_active_checkbox
click_on 'Save'
- expect(current_path).to eq(edit_project_integration_path(project, :slack_slash_commands))
+ expect(page).to have_current_path(edit_project_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 +32,7 @@ RSpec.describe 'Slack slash commands', :js do
fill_in 'Token', with: 'token'
click_on 'Save'
- expect(current_path).to eq(edit_project_integration_path(project, :slack_slash_commands))
+ expect(page).to have_current_path(edit_project_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/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb
index 12e88bbf6a5..e2dc760beda 100644
--- a/spec/features/projects/jobs/user_browses_job_spec.rb
+++ b/spec/features/projects/jobs/user_browses_job_spec.rb
@@ -15,11 +15,10 @@ RSpec.describe 'User browses a job', :js do
stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
-
- visit(project_job_path(project, build))
end
it 'erases the job log', :js do
+ visit(project_job_path(project, build))
wait_for_requests
expect(page).to have_content("Job #{build.name}")
@@ -41,6 +40,7 @@ RSpec.describe 'User browses a job', :js do
let!(:build) { create(:ci_build, :success, :unarchived_trace_artifact, :coverage, pipeline: pipeline) }
it 'shows no trace message', :js do
+ visit(project_job_path(project, build))
wait_for_requests
expect(page).to have_content('This job does not have a trace.')
@@ -51,6 +51,7 @@ RSpec.describe 'User browses a job', :js do
let!(:build) { create(:ci_build, :failed, :trace_live, pipeline: pipeline) }
it 'displays the failure reason' do
+ visit(project_job_path(project, build))
wait_for_all_requests
within('.builds-container') do
expect(page).to have_selector(
@@ -62,6 +63,7 @@ RSpec.describe 'User browses a job', :js do
let!(:artifact) { create(:ci_job_artifact, :unarchived_trace_artifact, job: build) }
it 'displays the failure reason from the live trace' do
+ visit(project_job_path(project, build))
wait_for_all_requests
within('.builds-container') do
expect(page).to have_selector(
@@ -75,6 +77,7 @@ RSpec.describe 'User browses a job', :js do
let!(:build_retried) { create(:ci_build, :failed, :retried, :trace_artifact, pipeline: pipeline) }
it 'displays the failure reason and retried label' do
+ visit(project_job_path(project, build))
wait_for_all_requests
within('.builds-container') do
expect(page).to have_selector(
diff --git a/spec/features/projects/jobs/user_browses_jobs_spec.rb b/spec/features/projects/jobs/user_browses_jobs_spec.rb
index a47aab1ec70..fde6240d373 100644
--- a/spec/features/projects/jobs/user_browses_jobs_spec.rb
+++ b/spec/features/projects/jobs/user_browses_jobs_spec.rb
@@ -270,7 +270,7 @@ RSpec.describe 'User browses jobs' do
wait_for_requests
expect(page).to have_content 'You need to sign in'
- expect(page.current_path).to eq("/users/sign_in")
+ expect(page).to have_current_path("/users/sign_in")
end
end
end
diff --git a/spec/features/projects/jobs/user_triggers_manual_job_with_variables_spec.rb b/spec/features/projects/jobs/user_triggers_manual_job_with_variables_spec.rb
index e8a14694d88..eea7e070a35 100644
--- a/spec/features/projects/jobs/user_triggers_manual_job_with_variables_spec.rb
+++ b/spec/features/projects/jobs/user_triggers_manual_job_with_variables_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'User triggers manual job with variables', :js do
wait_for_requests
- expect(build.job_variables.as_json).to contain_exactly(
+ expect(build.job_variables.as_json(only: [:key, :value])).to contain_exactly(
hash_including('key' => 'key_name', 'value' => 'key_value'))
end
end
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index a65d2d15c12..b34a615e651 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -103,7 +103,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
it "redirects to new URL" do
- expect(page.current_path).to eq(jobs_url)
+ expect(page).to have_current_path(jobs_url, ignore_query: true)
end
end
end
@@ -313,9 +313,9 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
context 'job is cancelable' do
it 'shows cancel button' do
- click_link 'Cancel'
+ find('[data-testid="cancel-button"]').click
- expect(page.current_path).to eq(job_url)
+ expect(page).to have_current_path(job_url, ignore_query: true)
end
end
end
@@ -384,7 +384,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
context 'when expire date is defined' do
- let(:expire_at) { Time.now + 7.days }
+ let(:expire_at) { Time.zone.now + 7.days }
context 'when user has ability to update job' do
context 'when artifacts are unlocked' do
@@ -423,7 +423,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
context 'when artifacts expired' do
- let(:expire_at) { Time.now - 7.days }
+ let(:expire_at) { Time.zone.now - 7.days }
context 'when artifacts are unlocked' do
before do
@@ -459,7 +459,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
it "redirects to new URL" do
- expect(page.current_path).to eq(job_url)
+ expect(page).to have_current_path(job_url, ignore_query: true)
end
end
@@ -1031,7 +1031,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
it 'loads the page and shows all needed controls' do
- expect(page).to have_content 'Retry'
+ expect(page).to have_selector('[data-testid="retry-button"')
end
end
end
@@ -1049,7 +1049,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
it 'shows the right status and buttons' do
page.within('aside.right-sidebar') do
- expect(page).to have_content 'Cancel'
+ expect(page).to have_selector('[data-testid="cancel-button"')
end
end
end
@@ -1179,7 +1179,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
it "redirects to new URL" do
- expect(page.current_path).to eq(raw_job_url)
+ expect(page).to have_current_path(raw_job_url, ignore_query: true)
end
end
end
diff --git a/spec/features/projects/labels/sort_labels_spec.rb b/spec/features/projects/labels/sort_labels_spec.rb
index 26b3d08253c..ecbc4b524dc 100644
--- a/spec/features/projects/labels/sort_labels_spec.rb
+++ b/spec/features/projects/labels/sort_labels_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'Sort labels', :js do
it 'sorts by date' do
click_button 'Name'
- sort_options = find('ul.dropdown-menu-sort li').all('a').collect(&:text)
+ sort_options = find('ul.dropdown-menu').all('li').collect(&:text)
expect(sort_options[0]).to eq('Name')
expect(sort_options[1]).to eq('Name, descending')
@@ -37,7 +37,7 @@ RSpec.describe 'Sort labels', :js do
expect(sort_options[4]).to eq('Updated date')
expect(sort_options[5]).to eq('Oldest updated')
- click_link 'Name, descending'
+ click_button 'Name, descending'
# assert default sorting
within '.other-labels' do
diff --git a/spec/features/projects/members/group_members_spec.rb b/spec/features/projects/members/group_members_spec.rb
index 94ce18fef93..6aa6acbdae4 100644
--- a/spec/features/projects/members/group_members_spec.rb
+++ b/spec/features/projects/members/group_members_spec.rb
@@ -92,7 +92,6 @@ RSpec.describe 'Projects members', :js do
context 'with a group requester' do
before do
- stub_feature_flags(invite_members_group_modal: false)
group.request_access(group_requester)
visit project_project_members_path(project)
end
diff --git a/spec/features/projects/members/invite_group_spec.rb b/spec/features/projects/members/invite_group_spec.rb
index 066e0b0d20f..9c256504934 100644
--- a/spec/features/projects/members/invite_group_spec.rb
+++ b/spec/features/projects/members/invite_group_spec.rb
@@ -3,47 +3,33 @@
require 'spec_helper'
RSpec.describe 'Project > Members > Invite group', :js do
- include Select2Helper
include ActionView::Helpers::DateHelper
include Spec::Support::Helpers::Features::MembersHelpers
include Spec::Support::Helpers::Features::InviteMembersModalHelper
let_it_be(:maintainer) { create(:user) }
- using RSpec::Parameterized::TableSyntax
+ it 'displays the invite group button' do
+ project = create(:project, namespace: create(:group))
- where(:invite_members_group_modal_enabled, :expected_invite_group_selector) do
- true | 'button[data-qa-selector="invite_a_group_button"]' # rubocop:disable QA/SelectorUsage
- false | '#invite-group-tab'
- end
-
- with_them do
- before do
- stub_feature_flags(invite_members_group_modal: invite_members_group_modal_enabled)
- end
+ project.add_maintainer(maintainer)
+ sign_in(maintainer)
- it 'displays either the invite group button or the form with tabs based on the feature flag' do
- project = create(:project, namespace: create(:group))
+ visit project_project_members_path(project)
- project.add_maintainer(maintainer)
- sign_in(maintainer)
+ expect(page).to have_selector('button[data-test-id="invite-group-button"]')
+ end
- visit project_project_members_path(project)
+ it 'does not display the button when visiting the page not signed in' do
+ project = create(:project, namespace: create(:group))
- expect(page).to have_selector(expected_invite_group_selector)
- end
+ visit project_project_members_path(project)
- it 'does not display either the form or the button when visiting the page not signed in' do
- project = create(:project, namespace: create(:group))
-
- visit project_project_members_path(project)
-
- expect(page).not_to have_selector(expected_invite_group_selector)
- end
+ expect(page).not_to have_selector('button[data-test-id="invite-group-button"]')
end
describe 'Share with group lock' do
- let(:invite_group_selector) { 'button[data-qa-selector="invite_a_group_button"]' } # rubocop:disable QA/SelectorUsage
+ let(:invite_group_selector) { 'button[data-test-id="invite-group-button"]' }
shared_examples 'the project can be shared with groups' do
it 'the "Invite a group" button exists' do
@@ -72,27 +58,7 @@ RSpec.describe 'Project > Members > Invite group', :js do
context 'when the group has "Share with group lock" disabled' do
it_behaves_like 'the project can be shared with groups'
- it 'the project can be shared with another group when the feature flag invite_members_group_modal is disabled' do
- stub_feature_flags(invite_members_group_modal: false)
-
- visit project_project_members_path(project)
-
- expect(page).not_to have_link 'Groups'
-
- click_on 'invite-group-tab'
-
- select2 group_to_share_with.id, from: '#link_group_id'
- page.find('body').click
- find('.btn-confirm').click
-
- click_link 'Groups'
-
- expect(members_table).to have_content(group_to_share_with.name)
- end
-
- it 'the project can be shared with another group when the feature flag invite_members_group_modal is enabled' do
- stub_feature_flags(invite_members_group_modal: true)
-
+ it 'the project can be shared with another group' do
visit project_project_members_path(project)
expect(page).not_to have_link 'Groups'
@@ -250,51 +216,6 @@ RSpec.describe 'Project > Members > Invite group', :js do
end
end
- context 'when invite_members_group_modal feature disabled' do
- let(:group_invite_dropdown) { find('#select2-results-2') }
-
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- it 'does not show the groups inherited from projects', :aggregate_failures do
- project.add_maintainer(maintainer)
- public_sibbling_group.add_maintainer(maintainer)
-
- visit project_project_members_path(project)
-
- click_on 'Invite group'
- click_on 'Search for a group'
- wait_for_requests
-
- expect(group_invite_dropdown).to have_text(public_membership_group.full_path)
- expect(group_invite_dropdown).to have_text(public_sibbling_group.full_path)
- expect(group_invite_dropdown).to have_text(private_membership_group.full_path)
- expect(group_invite_dropdown).not_to have_text(public_sub_subgroup.full_path)
- expect(group_invite_dropdown).not_to have_text(private_sibbling_group.full_path)
- expect(group_invite_dropdown).not_to have_text(parent_group.full_path, exact: true)
- expect(group_invite_dropdown).not_to have_text(project_group.full_path, exact: true)
- end
-
- it 'does not show the ancestors or project group', :aggregate_failures do
- parent_group.add_maintainer(maintainer)
-
- visit project_project_members_path(project)
-
- click_on 'Invite group'
- click_on 'Search for a group'
- wait_for_requests
-
- expect(group_invite_dropdown).to have_text(public_membership_group.full_path)
- expect(group_invite_dropdown).to have_text(public_sub_subgroup.full_path)
- expect(group_invite_dropdown).to have_text(public_sibbling_group.full_path)
- expect(group_invite_dropdown).to have_text(private_sibbling_group.full_path)
- expect(group_invite_dropdown).to have_text(private_membership_group.full_path)
- expect(group_invite_dropdown).not_to have_text(parent_group.full_path, exact: true)
- expect(group_invite_dropdown).not_to have_text(project_group.full_path, exact: true)
- end
- end
-
def expect_to_have_group(group)
expect(page).to have_selector("[entity-id='#{group.id}']")
end
diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb
index c38292f81bf..78a0a384d2c 100644
--- a/spec/features/projects/members/member_leaves_project_spec.rb
+++ b/spec/features/projects/members/member_leaves_project_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe 'Projects > Members > Member leaves project' do
click_link 'Leave project'
- expect(current_path).to eq(dashboard_projects_path)
+ expect(page).to have_current_path(dashboard_projects_path, ignore_query: true)
expect(project.users.exists?(user.id)).to be_falsey
end
@@ -29,7 +29,7 @@ RSpec.describe 'Projects > Members > Member leaves project' do
page.accept_confirm
wait_for_all_requests
- expect(current_path).to eq(dashboard_projects_path)
+ expect(page).to have_current_path(dashboard_projects_path, ignore_query: true)
sign_in(project.first_owner)
diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb
index 0b00656f87b..370d7b49832 100644
--- a/spec/features/projects/members/user_requests_access_spec.rb
+++ b/spec/features/projects/members/user_requests_access_spec.rb
@@ -4,12 +4,14 @@ require 'spec_helper'
RSpec.describe 'Projects > Members > User requests access', :js do
let_it_be(:user) { create(:user) }
+ let_it_be(:maintainer) { create(:user) }
let_it_be(:project) { create(:project, :public, :repository) }
- let(:maintainer) { project.first_owner }
+ let(:owner) { project.first_owner }
before do
sign_in(user)
+ project.add_maintainer(maintainer)
visit project_path(project)
stub_feature_flags(bootstrap_confirmation_modals: false)
end
@@ -24,7 +26,7 @@ RSpec.describe 'Projects > Members > User requests access', :js do
it 'user can request access to a project' do
perform_enqueued_jobs { click_link 'Request Access' }
- expect(ActionMailer::Base.deliveries.last.to).to eq [maintainer.notification_email_or_default]
+ expect(ActionMailer::Base.deliveries.map(&:to)).to match_array([[owner.notification_email_or_default], [maintainer.notification_email_or_default]])
expect(ActionMailer::Base.deliveries.last.subject).to eq "Request to join the #{project.full_name} project"
expect(project.requesters.exists?(user_id: user)).to be_truthy
diff --git a/spec/features/projects/navbar_spec.rb b/spec/features/projects/navbar_spec.rb
index 91e643ff258..5098908857a 100644
--- a/spec/features/projects/navbar_spec.rb
+++ b/spec/features/projects/navbar_spec.rb
@@ -16,6 +16,7 @@ RSpec.describe 'Project navbar' do
sign_in(user)
stub_config(registry: { enabled: false })
+ stub_feature_flags(harbor_registry_integration: false)
insert_package_nav(_('Infrastructure'))
insert_infrastructure_registry_nav
insert_infrastructure_google_cloud_nav
@@ -76,4 +77,16 @@ RSpec.describe 'Project navbar' do
it_behaves_like 'verified navigation bar'
end
+
+ context 'when harbor registry is available' do
+ before do
+ stub_feature_flags(harbor_registry_integration: true)
+
+ insert_harbor_registry_nav(_('Infrastructure Registry'))
+
+ visit project_path(project)
+ end
+
+ it_behaves_like 'verified navigation bar'
+ end
end
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index b3fbf5d356e..c57e39b6508 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -372,7 +372,7 @@ RSpec.describe 'New project', :js do
it 'shows import instructions' do
expect(page).to have_content('Authenticate with GitHub')
- expect(current_path).to eq new_import_github_path
+ expect(page).to have_current_path new_import_github_path, ignore_query: true
end
end
@@ -383,7 +383,7 @@ RSpec.describe 'New project', :js do
it 'shows import instructions' do
expect(page).to have_content('Manifest file import')
- expect(current_path).to eq new_import_manifest_path
+ expect(page).to have_current_path new_import_manifest_path, ignore_query: true
end
end
end
@@ -405,46 +405,62 @@ RSpec.describe 'New project', :js do
end
end
- context 'from Bitbucket', :js do
- shared_examples 'has a link to bitbucket cloud' do
- context 'when bitbucket is not configured' do
- before do
- allow(Gitlab::Auth::OAuth::Provider).to receive(:enabled?).and_call_original
- allow(Gitlab::Auth::OAuth::Provider)
- .to receive(:enabled?).with(:bitbucket)
- .and_return(false)
+ shared_examples 'has instructions to enable OAuth' do
+ context 'when OAuth is not configured' do
+ before do
+ sign_in(user)
- visit new_project_path
- click_link 'Import project'
- click_link 'Bitbucket Cloud'
- end
+ allow(Gitlab::Auth::OAuth::Provider).to receive(:enabled?).and_call_original
+ allow(Gitlab::Auth::OAuth::Provider)
+ .to receive(:enabled?).with(provider)
+ .and_return(false)
- it 'shows import instructions' do
- expect(find('.modal-body')).to have_content(bitbucket_link_content)
- end
+ visit new_project_path
+ click_link 'Import project'
+ click_link target_link
+ end
+
+ it 'shows import instructions' do
+ expect(find('.modal-body')).to have_content(oauth_config_instructions)
end
end
+ end
+
+ context 'from Bitbucket', :js do
+ let(:target_link) { 'Bitbucket Cloud' }
+ let(:provider) { :bitbucket }
context 'as a user' do
let(:user) { create(:user) }
- let(:bitbucket_link_content) { 'To enable importing projects from Bitbucket, ask your GitLab administrator to configure OAuth integration' }
+ let(:oauth_config_instructions) { 'To enable importing projects from Bitbucket, ask your GitLab administrator to configure OAuth integration' }
- before do
- sign_in(user)
- end
-
- it_behaves_like 'has a link to bitbucket cloud'
+ it_behaves_like 'has instructions to enable OAuth'
end
context 'as an admin' do
let(:user) { create(:admin) }
- let(:bitbucket_link_content) { 'To enable importing projects from Bitbucket, as administrator you need to configure OAuth integration' }
+ let(:oauth_config_instructions) { 'To enable importing projects from Bitbucket, as administrator you need to configure OAuth integration' }
- before do
- sign_in(user)
- end
+ it_behaves_like 'has instructions to enable OAuth'
+ end
+ end
+
+ context 'from GitLab.com', :js do
+ let(:target_link) { 'GitLab.com' }
+ let(:provider) { :gitlab }
+
+ context 'as a user' do
+ let(:user) { create(:user) }
+ let(:oauth_config_instructions) { 'To enable importing projects from GitLab.com, ask your GitLab administrator to configure OAuth integration' }
+
+ it_behaves_like 'has instructions to enable OAuth'
+ end
+
+ context 'as an admin' do
+ let(:user) { create(:admin) }
+ let(:oauth_config_instructions) { 'To enable importing projects from GitLab.com, as administrator you need to configure OAuth integration' }
- it_behaves_like 'has a link to bitbucket cloud'
+ it_behaves_like 'has instructions to enable OAuth'
end
end
end
diff --git a/spec/features/projects/pages/user_adds_domain_spec.rb b/spec/features/projects/pages/user_adds_domain_spec.rb
index bd4cb1aa39b..71bf1c24655 100644
--- a/spec/features/projects/pages/user_adds_domain_spec.rb
+++ b/spec/features/projects/pages/user_adds_domain_spec.rb
@@ -95,7 +95,7 @@ RSpec.describe 'User adds pages domain', :js do
fill_in 'Domain', with: 'my.test.domain.com'
- find('.js-auto-ssl-toggle-container .project-feature-toggle').click
+ find('.js-auto-ssl-toggle-container .js-project-feature-toggle').click
fill_in 'Certificate (PEM)', with: certificate_pem
fill_in 'Key (PEM)', with: certificate_key
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 a3fc5804e13..bdf280f4fe4 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
@@ -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 .project-feature-toggle').click
+ find('.js-auto-ssl-toggle-container .js-project-feature-toggle').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 .project-feature-toggle').click
+ find('.js-auto-ssl-toggle-container .js-project-feature-toggle').click
expect(find("#pages_domain_auto_ssl_enabled", visible: false).value).to eq 'false'
expect(page).to have_field 'Certificate (PEM)', type: 'textarea'
diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb
index aae5ab58b5d..63867a7e900 100644
--- a/spec/features/projects/pipeline_schedules_spec.rb
+++ b/spec/features/projects/pipeline_schedules_spec.rb
@@ -135,8 +135,8 @@ RSpec.describe 'Pipeline Schedules', :js do
end
it 'shows the pipeline schedule with default ref' do
- page.within('.js-target-branch-dropdown') do
- expect(first('.dropdown-toggle-text').text).to eq('master')
+ page.within('[data-testid="schedule-target-ref"]') do
+ expect(first('.gl-new-dropdown-button-text').text).to eq('master')
end
end
end
@@ -148,8 +148,8 @@ RSpec.describe 'Pipeline Schedules', :js do
end
it 'shows the pipeline schedule with default ref' do
- page.within('.js-target-branch-dropdown') do
- expect(first('.dropdown-toggle-text').text).to eq('master')
+ page.within('[data-testid="schedule-target-ref"]') do
+ expect(first('.gl-new-dropdown-button-text').text).to eq('master')
end
end
end
@@ -293,8 +293,8 @@ RSpec.describe 'Pipeline Schedules', :js do
end
def select_target_branch
- find('.js-target-branch-dropdown').click
- click_link 'master'
+ find('[data-testid="schedule-target-ref"] .dropdown-toggle').click
+ click_button 'master'
end
def save_pipeline_schedule
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index 01c942aec4c..6b9dfdf3a7b 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -477,7 +477,7 @@ RSpec.describe 'Pipeline', :js do
it 'redirects to pipeline overview page', :sidekiq_inline do
expect(page).to have_content('The pipeline has been deleted')
- expect(current_path).to eq(project_pipelines_path(project))
+ expect(page).to have_current_path(project_pipelines_path(project), ignore_query: true)
end
end
@@ -916,111 +916,7 @@ RSpec.describe 'Pipeline', :js do
end
end
- describe 'GET /:project/-/pipelines/:id/builds with jobs_tab_vue feature flag turned off' 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
- stub_feature_flags(jobs_tab_vue: false)
- 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_link('Play')
- end
-
- it 'shows jobs tab pane as active' do
- expect(page).to have_css('#js-tab-builds.active')
- 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
-
- it 'shows Jobs tab as active' do
- expect(page).to have_css('li.js-builds-tab-link .active')
- end
- end
-
- context 'retrying jobs' do
- it { expect(page).not_to have_content('retried') }
-
- context 'when retrying' do
- before do
- find('[data-testid="retryPipeline"]').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 '.pipeline-holder' do
- click_link('Play')
- end
- end
-
- it { expect(build_manual.reload).to be_pending }
- end
-
- context 'when user unschedules a delayed job' do
- before do
- within '.pipeline-holder' do
- click_link('Unschedule')
- end
- end
-
- it 'unschedules the delayed job and shows play button as a manual job' do
- expect(page).to have_content('Trigger this manual action')
- end
- end
-
- context 'failed jobs' do
- it 'displays a tooltip with the failure reason' do
- page.within('.ci-table') do
- failed_job_link = page.find('.ci-failed')
- expect(failed_job_link[:title]).to eq('Failed - (unknown failure)')
- end
- end
- end
- end
-
- describe 'GET /:project/-/pipelines/:id/builds with jobs_tab_vue feature flag turned on' do
+ describe 'GET /:project/-/pipelines/:id/builds' do
include_context 'pipeline builds'
let_it_be(:project) { create(:project, :repository) }
@@ -1228,7 +1124,7 @@ RSpec.describe 'Pipeline', :js do
it 'displays the pipeline graph' do
subject
- expect(current_path).to eq(pipeline_path(pipeline))
+ expect(page).to have_current_path(pipeline_path(pipeline), ignore_query: true)
expect(page).not_to have_content('Failed Jobs')
expect(page).to have_selector('.js-pipeline-graph')
end
@@ -1413,7 +1309,7 @@ RSpec.describe 'Pipeline', :js do
it 'contains badge that indicates detached merge request pipeline' do
page.within(all('.well-segment')[1]) do
- expect(page).to have_content 'detached'
+ expect(page).to have_content 'merge request'
end
end
end
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 37ac5a9d5a2..0e1728858ec 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -7,6 +7,7 @@ RSpec.describe 'Pipelines', :js do
include Spec::Support::Helpers::ModalHelpers
let(:project) { create(:project) }
+ let(:expected_detached_mr_tag) {'merge request'}
context 'when user is logged in' do
let(:user) { create(:user) }
@@ -160,51 +161,7 @@ RSpec.describe 'Pipelines', :js do
end
end
- context 'when pipeline is detached merge request pipeline, with rearrange_pipelines_table feature flag turned off' do
- let(:merge_request) do
- create(:merge_request,
- :with_detached_merge_request_pipeline,
- source_project: source_project,
- target_project: target_project)
- end
-
- let!(:pipeline) { merge_request.all_pipelines.first }
- let(:source_project) { project }
- let(:target_project) { project }
-
- before do
- stub_feature_flags(rearrange_pipelines_table: false)
-
- visit project_pipelines_path(source_project)
- end
-
- shared_examples_for 'detached merge request pipeline' do
- it 'shows pipeline information without pipeline ref', :sidekiq_might_not_need_inline do
- within '.pipeline-tags' do
- expect(page).to have_content('detached')
- end
-
- within '.branch-commit' do
- expect(page).to have_link(merge_request.iid,
- href: project_merge_request_path(project, merge_request))
- end
-
- within '.branch-commit' do
- expect(page).not_to have_link(pipeline.ref)
- end
- end
- end
-
- it_behaves_like 'detached merge request pipeline'
-
- context 'when source project is a forked project' do
- let(:source_project) { fork_project(project, user, repository: true) }
-
- it_behaves_like 'detached merge request pipeline'
- end
- end
-
- context 'when pipeline is detached merge request pipeline, with rearrange_pipelines_table feature flag turned on' do
+ context 'when pipeline is detached merge request pipeline' do
let(:merge_request) do
create(:merge_request,
:with_detached_merge_request_pipeline,
@@ -217,15 +174,13 @@ RSpec.describe 'Pipelines', :js do
let(:target_project) { project }
before do
- stub_feature_flags(rearrange_pipelines_table: true)
-
visit project_pipelines_path(source_project)
end
shared_examples_for 'detached merge request pipeline' do
it 'shows pipeline information without pipeline ref', :sidekiq_might_not_need_inline do
within '.pipeline-tags' do
- expect(page).to have_content('detached')
+ expect(page).to have_content(expected_detached_mr_tag)
expect(page).to have_link(merge_request.iid,
href: project_merge_request_path(project, merge_request))
@@ -244,52 +199,7 @@ RSpec.describe 'Pipelines', :js do
end
end
- context 'when pipeline is merge request pipeline, with rearrange_pipelines_table feature flag turned off' do
- let(:merge_request) do
- create(:merge_request,
- :with_merge_request_pipeline,
- source_project: source_project,
- target_project: target_project,
- merge_sha: target_project.commit.sha)
- end
-
- let!(:pipeline) { merge_request.all_pipelines.first }
- let(:source_project) { project }
- let(:target_project) { project }
-
- before do
- stub_feature_flags(rearrange_pipelines_table: false)
-
- visit project_pipelines_path(source_project)
- end
-
- shared_examples_for 'Correct merge request pipeline information' do
- it 'does not show detached tag for the pipeline, and shows the link of the merge request, and does not show the ref of the pipeline', :sidekiq_might_not_need_inline do
- within '.pipeline-tags' do
- expect(page).not_to have_content('detached')
- end
-
- within '.branch-commit' do
- expect(page).to have_link(merge_request.iid,
- href: project_merge_request_path(project, merge_request))
- end
-
- within '.branch-commit' do
- expect(page).not_to have_link(pipeline.ref)
- end
- end
- end
-
- it_behaves_like 'Correct merge request pipeline information'
-
- context 'when source project is a forked project' do
- let(:source_project) { fork_project(project, user, repository: true) }
-
- it_behaves_like 'Correct merge request pipeline information'
- end
- end
-
- context 'when pipeline is merge request pipeline, with rearrange_pipelines_table feature flag turned on' do
+ context 'when pipeline is merge request pipeline' do
let(:merge_request) do
create(:merge_request,
:with_merge_request_pipeline,
@@ -303,15 +213,13 @@ RSpec.describe 'Pipelines', :js do
let(:target_project) { project }
before do
- stub_feature_flags(rearrange_pipelines_table: true)
-
visit project_pipelines_path(source_project)
end
shared_examples_for 'Correct merge request pipeline information' do
it 'does not show detached tag for the pipeline, and shows the link of the merge request, and does not show the ref of the pipeline', :sidekiq_might_not_need_inline do
within '.pipeline-tags' do
- expect(page).not_to have_content('detached')
+ expect(page).not_to have_content(expected_detached_mr_tag)
expect(page).to have_link(merge_request.iid,
href: project_merge_request_path(project, merge_request))
@@ -414,7 +322,7 @@ RSpec.describe 'Pipelines', :js do
it "has link to the delayed job's action" do
find('[data-testid="pipelines-manual-actions-dropdown"]').click
- time_diff = [0, delayed_job.scheduled_at - Time.now].max
+ time_diff = [0, delayed_job.scheduled_at - Time.zone.now].max
expect(page).to have_button('delayed job 1')
expect(page).to have_content(Time.at(time_diff).utc.strftime("%H:%M:%S"))
end
@@ -675,28 +583,6 @@ RSpec.describe 'Pipelines', :js do
context 'with pipeline key selection' do
before do
- stub_feature_flags(rearrange_pipelines_table: false)
- visit project_pipelines_path(project)
- wait_for_requests
- end
-
- it 'changes the Pipeline ID column for Pipeline IID' do
- page.find('[data-testid="pipeline-key-dropdown"]').click
-
- within '.gl-new-dropdown-contents' do
- dropdown_options = page.find_all '.gl-new-dropdown-item'
-
- dropdown_options[1].click
- end
-
- expect(page.find('[data-testid="pipeline-th"]')).to have_content 'Pipeline IID'
- expect(page.find('[data-testid="pipeline-url-link"]')).to have_content "##{pipeline.iid}"
- end
- end
-
- context 'with pipeline key selection and rearrange_pipelines_table ff on' do
- before do
- stub_feature_flags(rearrange_pipelines_table: true)
visit project_pipelines_path(project)
wait_for_requests
end
@@ -912,7 +798,7 @@ RSpec.describe 'Pipelines', :js do
end
it 'renders empty state' do
- expect(page).to have_content 'Use a sample CI/CD template'
+ expect(page).to have_content 'Try test template'
end
end
end
@@ -936,7 +822,7 @@ RSpec.describe 'Pipelines', :js do
it 'redirects the user to sign_in and displays the flash alert' do
expect(page).to have_content 'You need to sign in'
- expect(page.current_path).to eq("/users/sign_in")
+ expect(page).to have_current_path("/users/sign_in")
end
end
end
diff --git a/spec/features/projects/releases/user_views_edit_release_spec.rb b/spec/features/projects/releases/user_views_edit_release_spec.rb
index 561b283ee15..f08f5529472 100644
--- a/spec/features/projects/releases/user_views_edit_release_spec.rb
+++ b/spec/features/projects/releases/user_views_edit_release_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe 'User edits Release', :js do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
- let(:release) { create(:release, :with_milestones, milestones_count: 1, project: project, name: 'The first release' ) }
+ let(:release) { create(:release, :with_milestones, milestones_count: 1, project: project, name: 'The first release', tag: "v1.1.0" ) }
let(:release_link) { create(:release_link, release: release) }
before do
diff --git a/spec/features/projects/remote_mirror_spec.rb b/spec/features/projects/remote_mirror_spec.rb
index 7bbffe627f6..2c8e895d43d 100644
--- a/spec/features/projects/remote_mirror_spec.rb
+++ b/spec/features/projects/remote_mirror_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe 'Project remote mirror', :feature do
context 'when last_error and last_update_at are present' do
it 'renders error message with timestamp' do
- remote_mirror.update!(last_error: 'Some new error', last_update_at: Time.now - 5.minutes)
+ remote_mirror.update!(last_error: 'Some new error', last_update_at: Time.zone.now - 5.minutes)
visit project_mirror_path(project)
diff --git a/spec/features/projects/settings/registry_settings_spec.rb b/spec/features/projects/settings/registry_settings_spec.rb
index 509729d526d..ff28d59ed08 100644
--- a/spec/features/projects/settings/registry_settings_spec.rb
+++ b/spec/features/projects/settings/registry_settings_spec.rb
@@ -3,8 +3,6 @@
require 'spec_helper'
RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration policy', :js do
- using RSpec::Parameterized::TableSyntax
-
let_it_be(:user) { create(:user) }
let_it_be(:project, reload: true) { create(:project, namespace: user.namespace) }
@@ -63,31 +61,34 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
end
context 'with a project without expiration policy' do
- where(:application_setting, :feature_flag, :result) do
- true | true | :available_section
- true | false | :available_section
- false | true | :available_section
- false | false | :disabled_message
+ before do
+ project.container_expiration_policy.destroy!
+ end
+
+ context 'with container_expiration_policies_enable_historic_entries enabled' do
+ before do
+ stub_application_setting(container_expiration_policies_enable_historic_entries: true)
+ end
+
+ it 'displays the related section' do
+ subject
+
+ within '[data-testid="registry-settings-app"]' do
+ expect(find('[data-testid="enable-toggle"]')).to have_content('Disabled - Tags will not be automatically deleted.')
+ end
+ end
end
- with_them do
+ context 'with container_expiration_policies_enable_historic_entries disabled' do
before do
- project.container_expiration_policy.destroy!
- stub_feature_flags(container_expiration_policies_historic_entry: false)
- stub_application_setting(container_expiration_policies_enable_historic_entries: application_setting)
- stub_feature_flags(container_expiration_policies_historic_entry: project) if feature_flag
+ stub_application_setting(container_expiration_policies_enable_historic_entries: false)
end
- it 'displays the expected result' do
+ it 'does not display the related section' do
subject
within '[data-testid="registry-settings-app"]' do
- case result
- when :available_section
- expect(find('[data-testid="enable-toggle"]')).to have_content('Disabled - Tags will not be automatically deleted.')
- when :disabled_message
- expect(find('.gl-alert-title')).to have_content('Cleanup policy for tags is disabled')
- end
+ expect(find('.gl-alert-title')).to have_content('Cleanup policy for tags is disabled')
end
end
end
diff --git a/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb b/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb
index d16295aedbe..0fc12f93850 100644
--- a/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb
+++ b/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe "User interacts with deploy keys", :js do
click_button("Enable")
expect(page).not_to have_selector(".gl-spinner")
- expect(current_path).to eq(project_settings_repository_path(project))
+ expect(page).to have_current_path(project_settings_repository_path(project), ignore_query: true)
find(".js-deployKeys-tab-enabled_keys").click
@@ -96,7 +96,7 @@ RSpec.describe "User interacts with deploy keys", :js do
click_button("Add key")
- expect(current_path).to eq(project_settings_repository_path(project))
+ expect(page).to have_current_path(project_settings_repository_path(project), ignore_query: true)
page.within(".deploy-keys") do
expect(page).to have_content(deploy_key_title)
diff --git a/spec/features/projects/settings/user_manages_project_members_spec.rb b/spec/features/projects/settings/user_manages_project_members_spec.rb
index 31dc939e6b8..2fe06414b32 100644
--- a/spec/features/projects/settings/user_manages_project_members_spec.rb
+++ b/spec/features/projects/settings/user_manages_project_members_spec.rb
@@ -4,7 +4,6 @@ require 'spec_helper'
RSpec.describe 'Projects > Settings > User manages project members' do
include Spec::Support::Helpers::Features::MembersHelpers
- include Select2Helper
include Spec::Support::Helpers::ModalHelpers
let(:group) { create(:group, name: 'OpenSource') }
@@ -57,28 +56,6 @@ RSpec.describe 'Projects > Settings > User manages project members' do
expect(find_member_row(user_mike)).to have_content('Reporter')
end
- describe 'when the :invite_members_group_modal is disabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- it 'imports a team from another project', :js do
- project2.add_maintainer(user)
- project2.add_reporter(user_mike)
-
- visit(project_project_members_path(project))
-
- page.within('.invite-users-form') do
- click_link('Import')
- end
-
- select2(project2.id, from: '#source_project_id')
- click_button('Import project members')
-
- expect(find_member_row(user_mike)).to have_content('Reporter')
- end
- end
-
it 'shows all members of project shared group', :js do
group.add_owner(user)
group.add_developer(user_dmitriy)
diff --git a/spec/features/projects/settings/user_renames_a_project_spec.rb b/spec/features/projects/settings/user_renames_a_project_spec.rb
index 1ff976eb800..2e2d7119e2e 100644
--- a/spec/features/projects/settings/user_renames_a_project_spec.rb
+++ b/spec/features/projects/settings/user_renames_a_project_spec.rb
@@ -82,7 +82,7 @@ RSpec.describe 'Projects > Settings > User renames a project' do
new_path = namespace_project_path(project.namespace, 'bar')
visit new_path
- expect(current_path).to eq(new_path)
+ expect(page).to have_current_path(new_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(project.name)
end
@@ -92,7 +92,7 @@ RSpec.describe 'Projects > Settings > User renames a project' do
new_path = namespace_project_path(project.namespace, 'bar')
visit old_path
- expect(current_path).to eq(new_path)
+ expect(page).to have_current_path(new_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(project.name)
end
@@ -103,7 +103,7 @@ RSpec.describe 'Projects > Settings > User renames a project' do
new_project = create(:project, namespace: user.namespace, path: 'gitlabhq', name: 'quz')
visit old_path
- expect(current_path).to eq(old_path)
+ expect(page).to have_current_path(old_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(new_project.name)
end
end
diff --git a/spec/features/projects/settings/user_transfers_a_project_spec.rb b/spec/features/projects/settings/user_transfers_a_project_spec.rb
index a88b9101869..6041dca305b 100644
--- a/spec/features/projects/settings/user_transfers_a_project_spec.rb
+++ b/spec/features/projects/settings/user_transfers_a_project_spec.rb
@@ -51,13 +51,13 @@ RSpec.describe 'Projects > Settings > User transfers a project', :js do
visit new_path
wait_for_requests
- expect(current_path).to eq(new_path)
+ expect(page).to have_current_path(new_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(project.name)
visit old_path
wait_for_requests
- expect(current_path).to eq(new_path)
+ expect(page).to have_current_path(new_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(project.name)
end
@@ -69,7 +69,7 @@ RSpec.describe 'Projects > Settings > User transfers a project', :js do
new_project = create(:project, namespace: user.namespace, path: project_path)
visit old_path
- expect(current_path).to eq(old_path)
+ expect(page).to have_current_path(old_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(new_project.name)
end
end
diff --git a/spec/features/projects/settings/webhooks_settings_spec.rb b/spec/features/projects/settings/webhooks_settings_spec.rb
index 8d73ffecd46..c84de7fc03f 100644
--- a/spec/features/projects/settings/webhooks_settings_spec.rb
+++ b/spec/features/projects/settings/webhooks_settings_spec.rb
@@ -86,7 +86,7 @@ RSpec.describe 'Projects > Settings > Webhook Settings' do
find('.hook-test-button.dropdown').click
click_link 'Push events'
- expect(current_path).to eq(webhooks_path)
+ expect(page).to have_current_path(webhooks_path, ignore_query: true)
end
context 'delete existing webhook' do
@@ -137,7 +137,7 @@ RSpec.describe 'Projects > Settings > Webhook Settings' do
click_link 'View details'
click_link 'Resend Request'
- expect(current_path).to eq(edit_project_hook_path(project, hook))
+ expect(page).to have_current_path(edit_project_hook_path(project, hook), ignore_query: true)
end
end
end
diff --git a/spec/features/projects/show/redirects_spec.rb b/spec/features/projects/show/redirects_spec.rb
index 3ac82244ded..55069cdd6c5 100644
--- a/spec/features/projects/show/redirects_spec.rb
+++ b/spec/features/projects/show/redirects_spec.rb
@@ -22,13 +22,13 @@ RSpec.describe 'Projects > Show > Redirects' do
it 'redirects to sign in page when project is private' do
visit project_path(private_project)
- expect(current_path).to eq(new_user_session_path)
+ expect(page).to have_current_path(new_user_session_path, ignore_query: true)
end
it 'redirects to sign in page when project does not exist' do
visit project_path(build(:project, :public))
- expect(current_path).to eq(new_user_session_path)
+ expect(page).to have_current_path(new_user_session_path, ignore_query: true)
end
it 'redirects to public project page after signing in' do
@@ -41,7 +41,7 @@ RSpec.describe 'Projects > Show > Redirects' do
click_button 'Sign in'
expect(status_code).to eq(200)
- expect(current_path).to eq("/#{public_project.full_path}")
+ expect(page).to have_current_path("/#{public_project.full_path}", ignore_query: true)
end
it 'redirects to private project page after sign in' do
@@ -53,7 +53,7 @@ RSpec.describe 'Projects > Show > Redirects' do
click_button 'Sign in'
expect(status_code).to eq(200)
- expect(current_path).to eq("/#{private_project.full_path}")
+ expect(page).to have_current_path("/#{private_project.full_path}", ignore_query: true)
end
context 'when signed in' do
diff --git a/spec/features/projects/show/user_interacts_with_stars_spec.rb b/spec/features/projects/show/user_interacts_with_stars_spec.rb
index 99f84c19bf3..aa61b629d92 100644
--- a/spec/features/projects/show/user_interacts_with_stars_spec.rb
+++ b/spec/features/projects/show/user_interacts_with_stars_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe 'Projects > Show > User interacts with project stars' do
find('.star-btn').click
- expect(current_path).to eq(new_user_session_path)
+ expect(page).to have_current_path(new_user_session_path, ignore_query: true)
end
end
end
diff --git a/spec/features/projects/show/user_sees_git_instructions_spec.rb b/spec/features/projects/show/user_sees_git_instructions_spec.rb
index 5270939f681..608bb4c5997 100644
--- a/spec/features/projects/show/user_sees_git_instructions_spec.rb
+++ b/spec/features/projects/show/user_sees_git_instructions_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe 'Projects > Show > User sees Git instructions' do
shared_examples_for 'redirects to the sign in page' do
it 'redirects to the sign in page' do
- expect(current_path).to eq(new_user_session_path)
+ expect(page).to have_current_path(new_user_session_path, ignore_query: true)
end
end
diff --git a/spec/features/projects/tags/user_views_tags_spec.rb b/spec/features/projects/tags/user_views_tags_spec.rb
index ef363ab6158..e1962ad3df5 100644
--- a/spec/features/projects/tags/user_views_tags_spec.rb
+++ b/spec/features/projects/tags/user_views_tags_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe 'User views tags', :feature do
it do
visit project_tags_path(project, format: :atom)
- expect(page.current_path).to eq("/users/sign_in")
+ expect(page).to have_current_path("/users/sign_in")
end
end
diff --git a/spec/features/projects/tracings_spec.rb b/spec/features/projects/tracings_spec.rb
index c4a4f1382ed..b79a0427ef6 100644
--- a/spec/features/projects/tracings_spec.rb
+++ b/spec/features/projects/tracings_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Tracings Content Security Policy' do
+ include ContentSecurityPolicyHelpers
+
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
@@ -18,10 +20,7 @@ RSpec.describe 'Tracings Content Security Policy' do
context 'when there is no global config' do
before do
- expect_next_instance_of(Projects::TracingsController) do |controller|
- expect(controller).to receive(:current_content_security_policy)
- .and_return(ActionDispatch::ContentSecurityPolicy.new)
- end
+ setup_csp_for_controller(Projects::TracingsController)
end
it 'does not add CSP directives' do
@@ -37,9 +36,7 @@ RSpec.describe 'Tracings Content Security Policy' do
p.frame_src 'https://global-policy.com'
end
- expect_next_instance_of(Projects::TracingsController) do |controller|
- expect(controller).to receive(:current_content_security_policy).and_return(csp)
- end
+ setup_existing_csp_for_controller(Projects::TracingsController, csp)
end
context 'when external_url is set' do
diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb
index c4e2e3353a4..6491a7425f7 100644
--- a/spec/features/projects/user_creates_project_spec.rb
+++ b/spec/features/projects/user_creates_project_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe 'User creates a project', :js do
project = Project.last
- expect(current_path).to eq(project_path(project))
+ expect(page).to have_current_path(project_path(project), ignore_query: true)
expect(page).to have_content('Empty')
expect(page).to have_content('git init')
expect(page).to have_content('git remote')
@@ -47,7 +47,7 @@ RSpec.describe 'User creates a project', :js do
project = Project.last
- expect(current_path).to eq(project_path(project))
+ expect(page).to have_current_path(project_path(project), ignore_query: true)
expect(page).to have_content('With initial commits')
expect(page).to have_content('Configure SAST in `.gitlab-ci.yml`, creating this file if it does not already exist')
expect(page).to have_content('README.md Initial commit')
@@ -72,7 +72,7 @@ RSpec.describe 'User creates a project', :js do
project = Project.last
- expect(current_path).to eq(project_path(project))
+ expect(page).to have_current_path(project_path(project), ignore_query: true)
expect(page).to have_content('With initial commits')
expect(page).to have_content('Configure SAST in `.gitlab-ci.yml`, creating this file if it does not already exist')
expect(page).to have_content('README.md Initial commit')
diff --git a/spec/features/projects/wikis_spec.rb b/spec/features/projects/wikis_spec.rb
index 621f8c71b20..879ffd2932b 100644
--- a/spec/features/projects/wikis_spec.rb
+++ b/spec/features/projects/wikis_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-RSpec.describe 'Project wikis' do
+RSpec.describe 'Project wikis', :js do
let_it_be(:user) { create(:user) }
let(:wiki) { create(:project_wiki, user: user, project: project) }
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/balsamiq_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/balsamiq_spec.rb
new file mode 100644
index 00000000000..3638e98a08a
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/balsamiq_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Balsamiq file blob', :js do
+ let(:project) { create(:project, :public, :repository) }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ visit project_blob_path(project, 'add-balsamiq-file/files/images/balsamiq.bmpr')
+
+ wait_for_requests
+ end
+
+ it 'displays Balsamiq file content' do
+ expect(page).to have_content("Mobile examples")
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_line_permalink_updater_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_line_permalink_updater_spec.rb
new file mode 100644
index 00000000000..e8c026a254e
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_line_permalink_updater_spec.rb
@@ -0,0 +1,103 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Blob button line permalinks (BlobLinePermalinkUpdater)', :js do
+ include TreeHelper
+
+ let(:project) { create(:project, :public, :repository) }
+ let(:path) { 'CHANGELOG' }
+ let(:sha) { project.repository.commit.sha }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ end
+
+ describe 'On a file(blob)' do
+ def get_absolute_url(path = "")
+ "http://#{page.server.host}:#{page.server.port}#{path}"
+ end
+
+ def visit_blob(fragment = nil)
+ visit project_blob_path(project, tree_join('master', path), anchor: fragment)
+ end
+
+ describe 'Click "Permalink" button' do
+ it 'works with no initial line number fragment hash' do
+ visit_blob
+
+ expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path))))
+ end
+
+ it 'maintains intitial fragment hash' do
+ fragment = "L3"
+
+ visit_blob(fragment)
+
+ expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: fragment)))
+ end
+
+ it 'changes fragment hash if line number clicked' do
+ ending_fragment = "L5"
+
+ visit_blob
+
+ find('#L3').click
+ find("##{ending_fragment}").click
+
+ expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: ending_fragment)))
+ end
+
+ it 'with initial fragment hash, changes fragment hash if line number clicked' do
+ fragment = "L1"
+ ending_fragment = "L5"
+
+ visit_blob(fragment)
+
+ find('#L3').click
+ find("##{ending_fragment}").click
+
+ expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: ending_fragment)))
+ end
+ end
+
+ describe 'Click "Blame" button' do
+ it 'works with no initial line number fragment hash' do
+ visit_blob
+
+ expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path))))
+ end
+
+ it 'maintains intitial fragment hash' do
+ fragment = "L3"
+
+ visit_blob(fragment)
+
+ expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: fragment)))
+ end
+
+ it 'changes fragment hash if line number clicked' do
+ ending_fragment = "L5"
+
+ visit_blob
+
+ find('#L3').click
+ find("##{ending_fragment}").click
+
+ expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: ending_fragment)))
+ end
+
+ it 'with initial fragment hash, changes fragment hash if line number clicked' do
+ fragment = "L1"
+ ending_fragment = "L5"
+
+ visit_blob(fragment)
+
+ find('#L3').click
+ find("##{ending_fragment}").click
+
+ expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: ending_fragment)))
+ end
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_show_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_show_spec.rb
new file mode 100644
index 00000000000..659014c922b
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_show_spec.rb
@@ -0,0 +1,1154 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'File blob', :js do
+ include MobileHelpers
+
+ let(:project) { create(:project, :public, :repository) }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ end
+
+ def visit_blob(path, anchor: nil, ref: 'master', **additional_args)
+ visit project_blob_path(project, File.join(ref, path), anchor: anchor, **additional_args)
+
+ wait_for_requests
+ end
+
+ def create_file(file_name, content)
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add #{file_name}",
+ file_path: file_name,
+ file_content: <<-SPEC.strip_heredoc
+ #{content}
+ SPEC
+ ).execute
+ end
+
+ context 'Ruby file' do
+ before do
+ visit_blob('files/ruby/popen.rb')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows highlighted Ruby code
+ expect(page).to have_css(".js-syntax-highlight")
+ expect(page).to have_content("require 'fileutils'")
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+ end
+ end
+
+ it 'displays file actions on all screen sizes' do
+ file_actions_selector = '.file-actions'
+
+ resize_screen_sm
+ expect(page).to have_selector(file_actions_selector, visible: true)
+
+ resize_screen_xs
+ expect(page).to have_selector(file_actions_selector, visible: true)
+ end
+ end
+
+ context 'Markdown file' do
+ context 'visiting directly' do
+ before do
+ visit_blob('files/markdown/ruby-style-guide.md')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob using the rich viewer' do
+ aggregate_failures do
+ # hides the simple viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false)
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]')
+
+ # shows rendered Markdown
+ expect(page).to have_link("PEP-8")
+
+ # shows a viewer switcher
+ expect(page).to have_selector('.js-blob-viewer-switcher')
+
+ # shows a disabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn.disabled')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+ end
+ end
+
+ context 'switching to the simple viewer' do
+ before do
+ find('.js-blob-viewer-switch-btn[data-viewer=simple]').click
+
+ wait_for_requests
+ end
+
+ it 'displays the blob using the simple viewer' do
+ aggregate_failures do
+ # hides the rich viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]')
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false)
+
+ # shows highlighted Markdown code
+ expect(page).to have_css(".js-syntax-highlight")
+ expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)")
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+ end
+ end
+
+ context 'switching to the rich viewer again' do
+ before do
+ find('.js-blob-viewer-switch-btn[data-viewer=rich]').click
+
+ wait_for_requests
+ end
+
+ it 'displays the blob using the rich viewer' do
+ aggregate_failures do
+ # hides the simple viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false)
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]')
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+ end
+ end
+ end
+ end
+ end
+
+ context 'when ref switch' do
+ def switch_ref_to(ref_name)
+ first('.qa-branches-select').click # rubocop:disable QA/SelectorUsage
+
+ page.within '.project-refs-form' do
+ click_link ref_name
+ wait_for_requests
+ end
+ end
+
+ it 'displays single highlighted line number of different ref' do
+ visit_blob('files/js/application.js', anchor: 'L1')
+
+ switch_ref_to('feature')
+
+ page.within '.blob-content' do
+ expect(find_by_id('LC1')[:class]).to include("hll")
+ end
+ end
+
+ it 'displays multiple highlighted line numbers of different ref' do
+ visit_blob('files/js/application.js', anchor: 'L1-3')
+
+ switch_ref_to('feature')
+
+ page.within '.blob-content' do
+ expect(find_by_id('LC1')[:class]).to include("hll")
+ expect(find_by_id('LC2')[:class]).to include("hll")
+ expect(find_by_id('LC3')[:class]).to include("hll")
+ end
+ end
+
+ it 'displays no highlighted number of different ref' do
+ Files::UpdateService.new(
+ project,
+ project.first_owner,
+ commit_message: 'Update',
+ start_branch: 'feature',
+ branch_name: 'feature',
+ file_path: 'files/js/application.js',
+ file_content: 'new content'
+ ).execute
+
+ project.commit('feature').diffs.diff_files.first
+
+ visit_blob('files/js/application.js', anchor: 'L3')
+ switch_ref_to('feature')
+
+ page.within '.blob-content' do
+ expect(page).not_to have_css('.hll')
+ end
+ end
+
+ context 'successfully change ref of similar name' do
+ before do
+ project.repository.create_branch('dev')
+ project.repository.create_branch('development')
+ end
+
+ it 'switch ref from longer to shorter ref name' do
+ visit_blob('files/js/application.js', ref: 'development')
+ switch_ref_to('dev')
+
+ aggregate_failures do
+ expect(page.find('.file-title-name').text).to eq('application.js')
+ expect(page).not_to have_css('flash-container')
+ end
+ end
+
+ it 'switch ref from shorter to longer ref name' do
+ visit_blob('files/js/application.js', ref: 'dev')
+ switch_ref_to('development')
+
+ aggregate_failures do
+ expect(page.find('.file-title-name').text).to eq('application.js')
+ expect(page).not_to have_css('flash-container')
+ end
+ end
+ end
+
+ it 'successfully changes ref when the ref name matches the project name' do
+ project.repository.create_branch(project.name)
+
+ visit_blob('files/js/application.js', ref: project.name)
+ switch_ref_to('master')
+
+ aggregate_failures do
+ expect(page.find('.file-title-name').text).to eq('application.js')
+ expect(page).not_to have_css('flash-container')
+ end
+ end
+ end
+
+ context 'visiting with a line number anchor' do
+ before do
+ visit_blob('files/markdown/ruby-style-guide.md', anchor: 'L1')
+ end
+
+ it 'displays the blob using the simple viewer' do
+ aggregate_failures do
+ # hides the rich viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]')
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false)
+
+ # highlights the line in question
+ expect(page).to have_selector('#LC1.hll')
+
+ # shows highlighted Markdown code
+ expect(page).to have_css(".js-syntax-highlight")
+ expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)")
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+ end
+ end
+ end
+ end
+
+ context 'Markdown rendering' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add RedCarpet and CommonMark Markdown ",
+ file_path: 'files/commonmark/file.md',
+ file_content: "1. one\n - sublist\n"
+ ).execute
+ end
+
+ context 'when rendering default markdown' do
+ before do
+ visit_blob('files/commonmark/file.md')
+
+ wait_for_requests
+ end
+
+ it 'renders using CommonMark' do
+ aggregate_failures do
+ expect(page).to have_content("sublist")
+ expect(page).not_to have_xpath("//ol//li//ul")
+ end
+ end
+ end
+ end
+
+ context 'Markdown file (stored in LFS)' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add Markdown in LFS",
+ file_path: 'files/lfs/file.md',
+ file_content: project.repository.blob_at('master', 'files/lfs/lfs_object.iso').data
+ ).execute
+ end
+
+ context 'when LFS is enabled on the project' do
+ before do
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+ project.update_attribute(:lfs_enabled, true)
+
+ visit_blob('files/lfs/file.md')
+
+ wait_for_requests
+ end
+
+ it 'displays an error' do
+ aggregate_failures do
+ # hides the simple viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false)
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]')
+
+ # shows an error message
+ expect(page).to have_content('The rendered file could not be displayed because it is stored in LFS. You can download it instead.')
+
+ # shows a viewer switcher
+ expect(page).to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+ end
+ end
+
+ context 'switching to the simple viewer' do
+ before do
+ find('.js-blob-viewer-switcher .js-blob-viewer-switch-btn[data-viewer=simple]').click
+
+ wait_for_requests
+ end
+
+ it 'displays an error' do
+ aggregate_failures do
+ # hides the rich viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]')
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false)
+
+ # shows an error message
+ expect(page).to have_content('The source could not be displayed because it is stored in LFS. You can download it instead.')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+ end
+ end
+ end
+ end
+
+ context 'when LFS is disabled on the project' do
+ before do
+ visit_blob('files/lfs/file.md')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows text
+ expect(page).to have_content('size 1575078')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+ end
+ end
+ end
+ end
+
+ context 'PDF file' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add PDF",
+ file_path: 'files/test.pdf',
+ file_content: project.repository.blob_at('add-pdf-file', 'files/pdf/test.pdf').data
+ ).execute
+
+ visit_blob('files/test.pdf')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows rendered PDF
+ expect(page).to have_selector('.js-pdf-viewer')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+ end
+ end
+ end
+
+ context 'Jupiter Notebook file' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add Jupiter Notebook",
+ file_path: 'files/basic.ipynb',
+ file_content: project.repository.blob_at('add-ipython-files', 'files/ipython/basic.ipynb').data
+ ).execute
+
+ visit_blob('files/basic.ipynb')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows rendered notebook
+ expect(page).to have_selector('.js-notebook-viewer-mounted')
+
+ # does show a viewer switcher
+ expect(page).to have_selector('.js-blob-viewer-switcher')
+
+ # show a disabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn.disabled')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+
+ # shows the rendered notebook
+ expect(page).to have_content('test')
+ end
+ end
+ end
+
+ context 'ISO file (stored in LFS)' do
+ context 'when LFS is enabled on the project' do
+ before do
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+ project.update_attribute(:lfs_enabled, true)
+
+ visit_blob('files/lfs/lfs_object.iso')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows a download link
+ expect(page).to have_link('Download (1.5 MB)')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+ end
+ end
+ end
+
+ context 'when LFS is disabled on the project' do
+ before do
+ visit_blob('files/lfs/lfs_object.iso')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows text
+ expect(page).to have_content('size 1575078')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+ end
+ end
+ end
+ end
+
+ context 'ZIP file' do
+ before do
+ visit_blob('Gemfile.zip')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows a download link
+ expect(page).to have_link('Download (2.11 KB)')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+ end
+ end
+ end
+
+ context 'empty file' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add empty file",
+ file_path: 'files/empty.md',
+ file_content: ''
+ ).execute
+
+ visit_blob('files/empty.md')
+
+ wait_for_requests
+ end
+
+ it 'displays an error' do
+ aggregate_failures do
+ # shows an error message
+ expect(page).to have_content('Empty file')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # does not show a download or raw button
+ expect(page).not_to have_link('Download')
+ expect(page).not_to have_link('Open raw')
+ end
+ end
+ end
+
+ context 'binary file that appears to be text in the first 1024 bytes' do
+ before do
+ visit_blob('encoding/binary-1.bin', ref: 'binary-encoding')
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows a download link
+ expect(page).to have_link('Download (23.8 KB)')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # The specs below verify an arguably incorrect result, but since we only
+ # learn that the file is not actually text once the text viewer content
+ # is loaded asynchronously, there is no straightforward way to get these
+ # synchronously loaded elements to display correctly.
+ #
+ # Clicking the copy button will result in nothing being copied.
+ # Clicking the raw button will result in the binary file being downloaded,
+ # as expected.
+
+ # shows an enabled copy button, incorrectly
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+
+ # shows a raw button, incorrectly
+ expect(page).to have_link('Open raw')
+ end
+ end
+ end
+
+ context 'files with auxiliary viewers' do
+ describe '.gitlab-ci.yml' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab-ci.yml",
+ file_path: '.gitlab-ci.yml',
+ file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
+ ).execute
+
+ visit_blob('.gitlab-ci.yml')
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that configuration is valid
+ expect(page).to have_content('This GitLab CI configuration is valid.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+
+ describe '.gitlab/route-map.yml' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab/route-map.yml",
+ file_path: '.gitlab/route-map.yml',
+ file_content: <<-MAP.strip_heredoc
+ # Team data
+ - source: 'data/team.yml'
+ public: 'team/'
+ MAP
+ ).execute
+
+ visit_blob('.gitlab/route-map.yml')
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that map is valid
+ expect(page).to have_content('This Route Map is valid.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+
+ describe '.gitlab/dashboards/custom-dashboard.yml' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab/dashboards/custom-dashboard.yml",
+ file_path: '.gitlab/dashboards/custom-dashboard.yml',
+ file_content: file_content
+ ).execute
+ end
+
+ context 'with metrics_dashboard_exhaustive_validations feature flag off' do
+ before do
+ stub_feature_flags(metrics_dashboard_exhaustive_validations: false)
+ visit_blob('.gitlab/dashboards/custom-dashboard.yml')
+ end
+
+ context 'valid dashboard file' do
+ let(:file_content) { File.read(Rails.root.join('config/prometheus/common_metrics.yml')) }
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that dashboard yaml is valid
+ expect(page).to have_content('Metrics Dashboard YAML definition is valid.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+
+ context 'invalid dashboard file' do
+ let(:file_content) { "dashboard: 'invalid'" }
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that dashboard yaml is invalid
+ expect(page).to have_content('Metrics Dashboard YAML definition is invalid:')
+ expect(page).to have_content("panel_groups: should be an array of panel_groups objects")
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+ end
+
+ context 'with metrics_dashboard_exhaustive_validations feature flag on' do
+ before do
+ stub_feature_flags(metrics_dashboard_exhaustive_validations: true)
+ visit_blob('.gitlab/dashboards/custom-dashboard.yml')
+ end
+
+ context 'valid dashboard file' do
+ let(:file_content) { File.read(Rails.root.join('config/prometheus/common_metrics.yml')) }
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that dashboard yaml is valid
+ expect(page).to have_content('Metrics Dashboard YAML definition is valid.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+
+ context 'invalid dashboard file' do
+ let(:file_content) { "dashboard: 'invalid'" }
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that dashboard yaml is invalid
+ expect(page).to have_content('Metrics Dashboard YAML definition is invalid:')
+ expect(page).to have_content("root is missing required keys: panel_groups")
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+ end
+ end
+
+ context 'LICENSE' do
+ before do
+ visit_blob('LICENSE')
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows license
+ expect(page).to have_content('This project is licensed under the MIT License.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more', href: 'http://choosealicense.com/licenses/mit/')
+ end
+ end
+ end
+
+ context '*.gemspec' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add activerecord.gemspec",
+ file_path: 'activerecord.gemspec',
+ file_content: <<-SPEC.strip_heredoc
+ Gem::Specification.new do |s|
+ s.platform = Gem::Platform::RUBY
+ s.name = "activerecord"
+ end
+ SPEC
+ ).execute
+
+ visit_blob('activerecord.gemspec')
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows names of dependency manager and package
+ expect(page).to have_content('This project manages its dependencies using RubyGems.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more', href: 'https://rubygems.org/')
+ end
+ end
+ end
+
+ context 'CONTRIBUTING.md' do
+ before do
+ file_name = 'CONTRIBUTING.md'
+
+ create_file(file_name, '## Contribution guidelines')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("After you've reviewed these contribution guidelines, you'll be all set to contribute to this project.")
+ end
+ end
+ end
+
+ context 'CHANGELOG.md' do
+ before do
+ file_name = 'CHANGELOG.md'
+
+ create_file(file_name, '## Changelog for v1.0.0')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("To find the state of this project's repository at the time of any of these versions, check out the tags.")
+ end
+ end
+ end
+
+ context 'Cargo.toml' do
+ before do
+ file_name = 'Cargo.toml'
+
+ create_file(file_name, '
+ [package]
+ name = "hello_world" # the name of the package
+ version = "0.1.0" # the current version, obeying semver
+ authors = ["Alice <a@example.com>", "Bob <b@example.com>"]
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Cargo.")
+ end
+ end
+ end
+
+ context 'Cartfile' do
+ before do
+ file_name = 'Cartfile'
+
+ create_file(file_name, '
+ gitlab "Alamofire/Alamofire" == 4.9.0
+ gitlab "Alamofire/AlamofireImage" ~> 3.4
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Carthage.")
+ end
+ end
+ end
+
+ context 'composer.json' do
+ before do
+ file_name = 'composer.json'
+
+ create_file(file_name, '
+ {
+ "license": "MIT"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Composer.")
+ end
+ end
+ end
+
+ context 'Gemfile' do
+ before do
+ file_name = 'Gemfile'
+
+ create_file(file_name, '
+ source "https://rubygems.org"
+
+ # Gems here
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Bundler.")
+ end
+ end
+ end
+
+ context 'Godeps.json' do
+ before do
+ file_name = 'Godeps.json'
+
+ create_file(file_name, '
+ {
+ "GoVersion": "go1.6"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using godep.")
+ end
+ end
+ end
+
+ context 'go.mod' do
+ before do
+ file_name = 'go.mod'
+
+ create_file(file_name, '
+ module example.com/mymodule
+
+ go 1.14
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Go Modules.")
+ end
+ end
+ end
+
+ context 'package.json' do
+ before do
+ file_name = 'package.json'
+
+ create_file(file_name, '
+ {
+ "name": "my-awesome-package",
+ "version": "1.0.0"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using npm.")
+ end
+ end
+ end
+
+ context 'podfile' do
+ before do
+ file_name = 'podfile'
+
+ create_file(file_name, 'platform :ios, "8.0"')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using CocoaPods.")
+ end
+ end
+ end
+
+ context 'test.podspec' do
+ before do
+ file_name = 'test.podspec'
+
+ create_file(file_name, '
+ Pod::Spec.new do |s|
+ s.name = "TensorFlowLiteC"
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using CocoaPods.")
+ end
+ end
+ end
+
+ context 'JSON.podspec.json' do
+ before do
+ file_name = 'JSON.podspec.json'
+
+ create_file(file_name, '
+ {
+ "name": "JSON"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using CocoaPods.")
+ end
+ end
+ end
+
+ context 'requirements.txt' do
+ before do
+ file_name = 'requirements.txt'
+
+ create_file(file_name, 'Project requirements')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using pip.")
+ end
+ end
+ end
+
+ context 'yarn.lock' do
+ before do
+ file_name = 'yarn.lock'
+
+ create_file(file_name, '
+ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+ # yarn lockfile v1
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Yarn.")
+ end
+ end
+ end
+ end
+
+ context 'realtime pipelines' do
+ before do
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'feature',
+ branch_name: 'feature',
+ commit_message: "Add ruby file",
+ file_path: 'files/ruby/test.rb',
+ file_content: "# Awesome content"
+ ).execute
+
+ create(:ci_pipeline, status: 'running', project: project, ref: 'feature', sha: project.commit('feature').sha)
+ visit_blob('files/ruby/test.rb', ref: 'feature')
+ end
+
+ it 'shows the realtime pipeline status' do
+ page.within('.commit-actions') do
+ expect(page).to have_css('.ci-status-icon')
+ expect(page).to have_css('.ci-status-icon-running')
+ expect(page).to have_css('.js-ci-status-icon-running')
+ end
+ end
+ end
+
+ context 'for subgroups' do
+ let(:group) { create(:group) }
+ let(:subgroup) { create(:group, parent: group) }
+ let(:project) { create(:project, :public, :repository, group: subgroup) }
+
+ it 'renders tree table without errors' do
+ visit_blob('README.md')
+
+ expect(page).to have_selector('.file-content')
+ expect(page).not_to have_selector('[data-testid="alert-danger"]')
+ end
+
+ it 'displays a GPG badge' do
+ visit_blob('CONTRIBUTING.md', ref: '33f3729a45c02fc67d00adb1b8bca394b0e761d9')
+
+ expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge'
+ expect(page).to have_selector '.gpg-status-box.invalid'
+ end
+ end
+
+ context 'on signed merge commit' do
+ it 'displays a GPG badge' do
+ visit_blob('conflicting-file.md', ref: '6101e87e575de14b38b4e1ce180519a813671e10')
+
+ expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge'
+ expect(page).to have_selector '.gpg-status-box.invalid'
+ end
+ end
+
+ context 'when static objects external storage is enabled' do
+ before do
+ stub_application_setting(static_objects_external_storage_url: 'https://cdn.gitlab.com')
+ end
+
+ context 'private project' do
+ let_it_be(:project) { create(:project, :repository, :private) }
+ let_it_be(:user) { create(:user) }
+
+ before do
+ project.add_developer(user)
+
+ sign_in(user)
+ visit_blob('README.md')
+ end
+
+ it 'shows open raw and download buttons with external storage URL prepended and user token appended to their href' do
+ path = project_raw_path(project, 'master/README.md')
+ raw_uri = "https://cdn.gitlab.com#{path}?token=#{user.static_object_token}"
+ download_uri = "https://cdn.gitlab.com#{path}?inline=false&token=#{user.static_object_token}"
+
+ aggregate_failures do
+ expect(page).to have_link 'Open raw', href: raw_uri
+ expect(page).to have_link 'Download', href: download_uri
+ end
+ end
+ end
+
+ context 'public project' do
+ before do
+ visit_blob('README.md')
+ end
+
+ it 'shows open raw and download buttons with external storage URL prepended to their href' do
+ path = project_raw_path(project, 'master/README.md')
+ raw_uri = "https://cdn.gitlab.com#{path}"
+ download_uri = "https://cdn.gitlab.com#{path}?inline=false"
+
+ aggregate_failures do
+ expect(page).to have_link 'Open raw', href: raw_uri
+ expect(page).to have_link 'Download', href: download_uri
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/edit_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/edit_spec.rb
new file mode 100644
index 00000000000..f5b9947b29e
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/edit_spec.rb
@@ -0,0 +1,213 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Editing file blob', :js do
+ include TreeHelper
+ include BlobSpecHelpers
+
+ let(:project) { create(:project, :public, :repository) }
+ let(:merge_request) { create(:merge_request, source_project: project, source_branch: 'feature', target_branch: 'master') }
+ let(:branch) { 'master' }
+ let(:file_path) { project.repository.ls_files(project.repository.root_ref)[1] }
+ let(:readme_file_path) { 'README.md' }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ end
+
+ context 'as a developer' do
+ let(:user) { create(:user) }
+ let(:role) { :developer }
+
+ before do
+ project.add_role(user, role)
+ sign_in(user)
+ end
+
+ def edit_and_commit(commit_changes: true, is_diff: false)
+ set_default_button('edit')
+ refresh
+ wait_for_requests
+
+ if is_diff
+ first('.js-diff-more-actions').click
+ click_link('Edit in single-file editor')
+ else
+ click_link('Edit')
+ end
+
+ fill_editor(content: 'class NextFeature\\nend\\n')
+
+ if commit_changes
+ click_button 'Commit changes'
+ end
+ end
+
+ def fill_editor(content: 'class NextFeature\\nend\\n')
+ wait_for_requests
+ execute_script("monaco.editor.getModels()[0].setValue('#{content}')")
+ end
+
+ context 'from MR diff' do
+ before do
+ visit diffs_project_merge_request_path(project, merge_request)
+ edit_and_commit(is_diff: true)
+ end
+
+ it 'returns me to the mr' do
+ expect(page).to have_content(merge_request.title)
+ end
+ end
+
+ it 'updates the content of file with a number as file path' do
+ project.repository.create_file(user, '1', 'test', message: 'testing', branch_name: branch)
+ visit project_blob_path(project, tree_join(branch, '1'))
+
+ edit_and_commit
+
+ expect(page).to have_content 'NextFeature'
+ end
+
+ it 'editing a template file in a sub directory does not change path' do
+ project.repository.create_file(user, 'ci/.gitlab-ci.yml', 'test', message: 'testing', branch_name: branch)
+ visit project_edit_blob_path(project, tree_join(branch, 'ci/.gitlab-ci.yml'))
+
+ expect(find_by_id('file_path').value).to eq('ci/.gitlab-ci.yml')
+ end
+
+ it 'updating file path updates syntax highlighting' do
+ visit project_edit_blob_path(project, tree_join(branch, readme_file_path))
+ expect(find('#editor')['data-mode-id']).to eq('markdown')
+
+ find('#file_path').send_keys('foo.txt') do
+ expect(find('#editor')['data-mode-id']).to eq('plaintext')
+ end
+ end
+
+ context 'from blob file path' do
+ before do
+ visit project_blob_path(project, tree_join(branch, file_path))
+ end
+
+ it 'updates content' do
+ edit_and_commit
+
+ expect(page).to have_content 'successfully committed'
+ expect(page).to have_content 'NextFeature'
+ end
+
+ it 'previews content' do
+ edit_and_commit(commit_changes: false)
+ click_link 'Preview changes'
+ wait_for_requests
+
+ old_line_count = page.all('.line_holder.old').size
+ new_line_count = page.all('.line_holder.new').size
+
+ expect(old_line_count).to be > 0
+ expect(new_line_count).to be > 0
+ end
+ end
+
+ context 'when rendering the preview' do
+ it 'renders content with CommonMark' do
+ visit project_edit_blob_path(project, tree_join(branch, readme_file_path))
+ fill_editor(content: '1. one\\n - sublist\\n')
+ click_link 'Preview'
+ wait_for_requests
+
+ # the above generates two separate lists (not embedded) in CommonMark
+ expect(page).to have_content('sublist')
+ expect(page).not_to have_xpath('//ol//li//ul')
+ end
+ end
+ end
+
+ context 'visit blob edit' do
+ context 'redirects to sign in and returns' do
+ context 'as developer' do
+ let(:user) { create(:user) }
+
+ before do
+ project.add_developer(user)
+ visit project_edit_blob_path(project, tree_join(branch, file_path))
+ end
+
+ it 'redirects to sign in and returns' do
+ expect(page).to have_current_path(new_user_session_path)
+
+ gitlab_sign_in(user)
+
+ expect(page).to have_current_path(project_edit_blob_path(project, tree_join(branch, file_path)))
+ end
+ end
+
+ context 'as guest' do
+ let(:user) { create(:user) }
+
+ before do
+ visit project_edit_blob_path(project, tree_join(branch, file_path))
+ end
+
+ it 'redirects to sign in and returns' do
+ expect(page).to have_current_path(new_user_session_path)
+
+ gitlab_sign_in(user)
+
+ expect(page).to have_current_path(project_blob_path(project, tree_join(branch, file_path)))
+ end
+ end
+ end
+
+ context 'as developer' do
+ let(:user) { create(:user) }
+ let(:protected_branch) { 'protected-branch' }
+
+ before do
+ project.add_developer(user)
+ project.repository.add_branch(user, protected_branch, 'master')
+ create(:protected_branch, project: project, name: protected_branch)
+ sign_in(user)
+ end
+
+ context 'on some branch' do
+ before do
+ visit project_edit_blob_path(project, tree_join(branch, file_path))
+ end
+
+ it 'shows blob editor with same branch' do
+ expect(page).to have_current_path(project_edit_blob_path(project, tree_join(branch, file_path)))
+ expect(find('.js-branch-name').value).to eq(branch)
+ end
+ end
+
+ context 'with protected branch' do
+ it 'shows blob editor with patch branch' do
+ freeze_time do
+ visit project_edit_blob_path(project, tree_join(protected_branch, file_path))
+
+ epoch = Time.zone.now.strftime('%s%L').last(5)
+
+ expect(find('.js-branch-name').value).to eq "#{user.username}-protected-branch-patch-#{epoch}"
+ end
+ end
+ end
+ end
+
+ context 'as maintainer' do
+ let(:user) { create(:user) }
+
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
+ visit project_edit_blob_path(project, tree_join(branch, file_path))
+ end
+
+ it 'shows blob editor with same branch' do
+ expect(page).to have_current_path(project_edit_blob_path(project, tree_join(branch, file_path)))
+ expect(find('.js-branch-name').value).to eq(branch)
+ end
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/shortcuts_blob_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/shortcuts_blob_spec.rb
new file mode 100644
index 00000000000..fe0b217992e
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/shortcuts_blob_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Blob shortcuts', :js do
+ include TreeHelper
+ let(:project) { create(:project, :public, :repository) }
+ let(:path) { project.repository.ls_files(project.repository.root_ref)[0] }
+ let(:sha) { project.repository.commit.sha }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ end
+
+ describe 'On a file(blob)', :js do
+ def get_absolute_url(path = "")
+ "http://#{page.server.host}:#{page.server.port}#{path}"
+ end
+
+ def visit_blob(fragment = nil)
+ visit project_blob_path(project, tree_join('master', path), anchor: fragment)
+ end
+
+ describe 'pressing "y"' do
+ it 'redirects to permalink with commit sha' do
+ visit_blob
+ wait_for_requests
+
+ find('body').native.send_key('y')
+
+ expect(page).to have_current_path(get_absolute_url(project_blob_path(project, tree_join(sha, path))), url: true)
+ end
+
+ it 'maintains fragment hash when redirecting' do
+ fragment = "L1"
+ visit_blob(fragment)
+ wait_for_requests
+
+ find('body').native.send_key('y')
+
+ expect(page).to have_current_path(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: fragment)), url: true)
+ end
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_creates_new_blob_in_new_project_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_creates_new_blob_in_new_project_spec.rb
new file mode 100644
index 00000000000..fe38659f60b
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_creates_new_blob_in_new_project_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User creates new blob', :js do
+ include WebIdeSpecHelpers
+
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :empty_repo) }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ end
+
+ shared_examples 'creating a file' do
+ it 'allows the user to add a new file in Web IDE' do
+ visit project_path(project)
+
+ click_link 'New file'
+
+ wait_for_requests
+
+ ide_create_new_file('dummy-file', content: "Hello world\n")
+
+ ide_commit
+
+ expect(page).to have_content('All changes are committed')
+ expect(project.repository.blob_at('master', 'dummy-file').data).to eql("Hello world\n")
+ end
+ end
+
+ describe 'as a maintainer' do
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
+ end
+
+ it_behaves_like 'creating a file'
+ end
+
+ describe 'as an admin' do
+ let(:user) { create(:user, :admin) }
+
+ before do
+ sign_in(user)
+ gitlab_enable_admin_mode_sign_in(user)
+ end
+
+ it_behaves_like 'creating a file'
+ end
+
+ describe 'as a developer' do
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ visit project_path(project)
+ end
+
+ it 'does not allow pushing to the default branch' do
+ expect(page).not_to have_content('New file')
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb
new file mode 100644
index 00000000000..4290df08e66
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User follows pipeline suggest nudge spec when feature is enabled', :js do
+ include CookieHelper
+
+ let(:project) { create(:project, :empty_repo) }
+ let(:user) { project.first_owner }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ end
+
+ describe 'viewing the new blob page' do
+ before do
+ sign_in(user)
+ end
+
+ context 'when the page is loaded from the link using the suggest_gitlab_ci_yml param' do
+ before do
+ visit namespace_project_new_blob_path(namespace_id: project.namespace, project_id: project, id: 'master', suggest_gitlab_ci_yml: 'true')
+ end
+
+ it 'pre-fills .gitlab-ci.yml for file name' do
+ file_name = page.find_by_id('file_name')
+
+ expect(file_name.value).to have_content('.gitlab-ci.yml')
+ end
+
+ it 'chooses the .gitlab-ci.yml Template Type' do
+ template_type = page.find(:css, '.template-type-selector .dropdown-toggle-text')
+
+ expect(template_type.text).to have_content('.gitlab-ci.yml')
+ end
+
+ it 'displays suggest_gitlab_ci_yml popover' do
+ page.find(:css, '.gitlab-ci-yml-selector').click
+
+ popover_selector = '.suggest-gitlab-ci-yml'
+
+ expect(page).to have_css(popover_selector, visible: true)
+
+ page.within(popover_selector) do
+ expect(page).to have_content('1/2: Choose a template')
+ end
+ end
+
+ it 'sets the commit cookie when the Commit button is clicked' do
+ click_button 'Commit changes'
+
+ expect(get_cookie("suggest_gitlab_ci_yml_commit_#{project.id}")).to be_present
+ end
+ end
+
+ context 'when the page is visited without the param' do
+ before do
+ visit namespace_project_new_blob_path(namespace_id: project.namespace, project_id: project, id: 'master')
+ end
+
+ it 'does not pre-fill .gitlab-ci.yml for file name' do
+ file_name = page.find_by_id('file_name')
+
+ expect(file_name.value).not_to have_content('.gitlab-ci.yml')
+ end
+
+ it 'does not choose the .gitlab-ci.yml Template Type' do
+ template_type = page.find(:css, '.template-type-selector .dropdown-toggle-text')
+
+ expect(template_type.text).to have_content('Select a template type')
+ end
+
+ it 'does not display suggest_gitlab_ci_yml popover' do
+ popover_selector = '.b-popover.suggest-gitlab-ci-yml'
+
+ expect(page).not_to have_css(popover_selector, visible: true)
+ end
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_views_pipeline_editor_button_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_views_pipeline_editor_button_spec.rb
new file mode 100644
index 00000000000..a00e1eaa551
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_views_pipeline_editor_button_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User views pipeline editor button on root ci config file', :js do
+ include BlobSpecHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :public, :repository) }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ end
+
+ context "when the ci config is the root file" do
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ it 'shows the button to the Pipeline Editor' do
+ project.update!(ci_config_path: '.my-config.yml')
+ project.repository.create_file(user, project.ci_config_path_or_default, 'test', message: 'testing', branch_name: 'master')
+ visit project_blob_path(project, File.join('master', '.my-config.yml'))
+
+ expect(page).to have_content('Edit in pipeline editor')
+ end
+
+ it 'does not shows the Pipeline Editor button' do
+ project.repository.create_file(user, '.my-sub-config.yml', 'test', message: 'testing', branch_name: 'master')
+ visit project_blob_path(project, File.join('master', '.my-sub-config.yml'))
+
+ expect(page).not_to have_content('Edit in pipeline editor')
+ end
+ end
+
+ context "when user cannot collaborate" do
+ before do
+ sign_in(user)
+ end
+ it 'does not shows the Pipeline Editor button' do
+ visit project_blob_path(project, File.join('master', '.my-config.yml'))
+ expect(page).not_to have_content('Edit in pipeline editor')
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/editing_a_file_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/editing_a_file_spec.rb
new file mode 100644
index 00000000000..c32fb1aa4d3
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/editing_a_file_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Files > User wants to edit a file' do
+ let(:project) { create(:project, :repository) }
+ let(:user) { project.first_owner }
+ let(:commit_params) do
+ {
+ start_branch: project.default_branch,
+ branch_name: project.default_branch,
+ commit_message: "Committing First Update",
+ file_path: ".gitignore",
+ file_content: "First Update",
+ last_commit_sha: Gitlab::Git::Commit.last_for_path(project.repository, project.default_branch,
+ ".gitignore").sha
+ }
+ end
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ sign_in user
+ visit project_edit_blob_path(project,
+ File.join(project.default_branch, '.gitignore'))
+ end
+
+ it 'file has been updated since the user opened the edit page' do
+ Files::UpdateService.new(project, user, commit_params).execute
+
+ click_button 'Commit changes'
+
+ expect(page).to have_content 'Someone edited the file the same time you did.'
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/find_file_keyboard_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/find_file_keyboard_spec.rb
new file mode 100644
index 00000000000..9ba5f5a9b57
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/find_file_keyboard_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Files > Find file keyboard shortcuts', :js do
+ let(:project) { create(:project, :repository) }
+ let(:user) { project.first_owner }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ sign_in user
+
+ visit project_find_file_path(project, project.repository.root_ref)
+
+ wait_for_requests
+ end
+
+ it 'opens file when pressing enter key' do
+ fill_in 'file_find', with: 'CHANGELOG'
+
+ find('#file_find').native.send_keys(:enter)
+
+ expect(page).to have_selector('.blob-content-holder')
+
+ page.within('.js-file-title') do
+ expect(page).to have_content('CHANGELOG')
+ end
+ end
+
+ it 'navigates files with arrow keys' do
+ fill_in 'file_find', with: 'application.'
+
+ find('#file_find').native.send_keys(:down)
+ find('#file_find').native.send_keys(:enter)
+
+ expect(page).to have_selector('.blob-content-holder')
+
+ page.within('.js-file-title') do
+ expect(page).to have_content('application.js')
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/project_owner_creates_license_file_spec.rb
new file mode 100644
index 00000000000..ab920504100
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/project_owner_creates_license_file_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Files > Project owner creates a license file', :js do
+ let(:project) { create(:project, :repository) }
+ let(:project_maintainer) { project.first_owner }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ project.repository.delete_file(project_maintainer, 'LICENSE',
+ message: 'Remove LICENSE', branch_name: 'master')
+ sign_in(project_maintainer)
+ visit project_path(project)
+ end
+
+ it 'project maintainer creates a license file manually from a template' do
+ visit project_tree_path(project, project.repository.root_ref)
+ find('.add-to-tree').click
+ click_link 'New file'
+
+ fill_in :file_name, with: 'LICENSE'
+
+ expect(page).to have_selector('.license-selector')
+
+ select_template('MIT License')
+
+ file_content = first('.file-editor')
+ expect(file_content).to have_content('MIT License')
+ expect(file_content).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
+
+ fill_in :commit_message, with: 'Add a LICENSE file', visible: true
+ click_button 'Commit changes'
+
+ expect(page).to have_current_path(
+ project_blob_path(project, 'master/LICENSE'), ignore_query: true)
+ expect(page).to have_content('MIT License')
+ expect(page).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
+ end
+
+ it 'project maintainer creates a license file from the "Add license" link' do
+ click_link 'Add LICENSE'
+
+ expect(page).to have_content('New file')
+ expect(page).to have_current_path(
+ project_new_blob_path(project, 'master'), ignore_query: true)
+ expect(find('#file_name').value).to eq('LICENSE')
+ expect(page).to have_selector('.license-selector')
+
+ select_template('MIT License')
+
+ file_content = first('.file-editor')
+ expect(file_content).to have_content('MIT License')
+ expect(file_content).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
+
+ fill_in :commit_message, with: 'Add a LICENSE file', visible: true
+ click_button 'Commit changes'
+
+ expect(page).to have_current_path(
+ project_blob_path(project, 'master/LICENSE'), ignore_query: true)
+ expect(page).to have_content('MIT License')
+ expect(page).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
+ end
+
+ def select_template(template)
+ page.within('.js-license-selector-wrap') do
+ click_button 'Apply a template'
+ click_link template
+ wait_for_requests
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_files_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_files_spec.rb
new file mode 100644
index 00000000000..5abdad905fd
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_files_spec.rb
@@ -0,0 +1,377 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe "User browses files", :js do
+ include RepoHelpers
+
+ 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(:tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
+ let(:user) { project.first_owner }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ sign_in(user)
+ end
+
+ it "shows last commit for current directory", :js do
+ visit(tree_path_root_ref)
+
+ click_link("files")
+
+ last_commit = project.repository.last_commit_for_path(project.default_branch, "files")
+
+ page.within(".commit-detail") do
+ expect(page).to have_content(last_commit.short_id).and have_content(last_commit.author_name)
+ end
+ end
+
+ context "when browsing the master branch", :js do
+ before do
+ visit(tree_path_root_ref)
+ end
+
+ it "shows files from a repository" do
+ expect(page).to have_content("VERSION")
+ .and have_content(".gitignore")
+ .and have_content("LICENSE")
+ end
+
+ it "shows the `Browse Directory` link" do
+ click_link("files")
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('files')
+ end
+
+ click_link("History")
+
+ expect(page).to have_link("Browse Directory").and have_no_link("Browse Code")
+ end
+
+ it "shows the `Browse File` link" do
+ page.within(".tree-table") do
+ click_link("README.md")
+ end
+
+ click_link("History")
+
+ expect(page).to have_link("Browse File").and have_no_link("Browse Files")
+ end
+
+ it "shows the `Browse Files` link" do
+ click_link("History")
+
+ expect(page).to have_link("Browse Files").and have_no_link("Browse Directory")
+ end
+
+ it "redirects to the permalink URL" do
+ click_link(".gitignore")
+ click_link("Permalink")
+
+ permalink_path = project_blob_path(project, "#{project.repository.commit.sha}/.gitignore")
+
+ expect(page).to have_current_path(permalink_path, ignore_query: true)
+ end
+ end
+
+ context "when browsing the `markdown` branch", :js do
+ context "when browsing the root" do
+ before do
+ visit(project_tree_path(project, "markdown"))
+ end
+
+ it "shows correct files and links" do
+ expect(page).to have_current_path(project_tree_path(project, "markdown"), ignore_query: true)
+ expect(page).to have_content("README.md")
+ .and have_content("CHANGELOG")
+ .and have_content("Welcome to GitLab GitLab is a free project and repository management application")
+ .and have_link("GitLab API doc")
+ .and have_link("GitLab API website")
+ .and have_link("Rake tasks")
+ .and have_link("backup and restore procedure")
+ .and have_link("GitLab API doc directory")
+ .and have_link("Maintenance")
+ .and have_header_with_correct_id_and_link(2, "Application details", "application-details")
+ .and have_link("empty", href: "")
+ .and have_link("#id", href: "#id")
+ .and have_link("/#id", href: project_blob_path(project, "markdown/README.md", anchor: "id"))
+ .and have_link("README.md#id", href: project_blob_path(project, "markdown/README.md", anchor: "id"))
+ .and have_link("d/README.md#id", href: project_blob_path(project, "markdown/db/README.md", anchor: "id"))
+ end
+
+ it "shows correct content of file" do
+ click_link("GitLab API doc")
+
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/api/README.md"), ignore_query: true)
+ expect(page).to have_content("All API requests require authentication")
+ .and have_content("Contents")
+ .and have_link("Users")
+ .and have_link("Rake tasks")
+ .and have_header_with_correct_id_and_link(1, "GitLab API", "gitlab-api")
+
+ click_link("Users")
+
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/api/users.md"), ignore_query: true)
+ expect(page).to have_content("Get a list of users.")
+
+ page.go_back
+
+ click_link("Rake tasks")
+
+ expect(page).to have_current_path(project_tree_path(project, "markdown/doc/raketasks"), ignore_query: true)
+ expect(page).to have_content("backup_restore.md").and have_content("maintenance.md")
+
+ click_link("maintenance.md")
+
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/raketasks/maintenance.md"), ignore_query: true)
+ expect(page).to have_content("bundle exec rake gitlab:env:info RAILS_ENV=production")
+
+ click_link("shop")
+
+ page.within(".tree-table") do
+ click_link("README.md")
+ end
+
+ page.go_back
+
+ page.within(".tree-table") do
+ click_link("d")
+ end
+
+ expect(page).to have_link("..", href: project_tree_path(project, "markdown/"))
+
+ page.within(".tree-table") do
+ click_link("README.md")
+ end
+
+ expect(page).to have_link("empty", href: "")
+ end
+
+ it "shows correct content of directory" do
+ click_link("GitLab API doc directory")
+
+ expect(page).to have_current_path(project_tree_path(project, "markdown/doc/api"), ignore_query: true)
+ expect(page).to have_content("README.md").and have_content("users.md")
+
+ click_link("Users")
+
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/api/users.md"), ignore_query: true)
+ expect(page).to have_content("List users").and have_content("Get a list of users.")
+ end
+ end
+ end
+
+ context 'when commit message has markdown', :js do
+ before do
+ project.repository.create_file(user, 'index', 'test', message: ':star: testing', branch_name: 'master')
+
+ visit(project_tree_path(project, "master"))
+ end
+
+ it 'renders emojis' do
+ expect(page).to have_selector('gl-emoji', count: 2)
+ end
+ end
+
+ context "when browsing a `improve/awesome` branch", :js do
+ before do
+ visit(project_tree_path(project, "improve/awesome"))
+ end
+
+ it "shows files from a repository" do
+ expect(page).to have_content("VERSION")
+ .and have_content(".gitignore")
+ .and have_content("LICENSE")
+
+ click_link("files")
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('files')
+ end
+
+ click_link("html")
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('html')
+ end
+
+ expect(page).to have_link('500.html')
+ end
+ end
+
+ context "when browsing a `Ääh-test-utf-8` branch", :js do
+ before do
+ project.repository.create_branch('Ääh-test-utf-8', project.repository.root_ref)
+ visit(project_tree_path(project, "Ääh-test-utf-8"))
+ end
+
+ it "shows files from a repository" do
+ expect(page).to have_content("VERSION")
+ .and have_content(".gitignore")
+ .and have_content("LICENSE")
+
+ click_link("files")
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('files')
+ end
+
+ click_link("html")
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('html')
+ end
+
+ expect(page).to have_link('500.html')
+ end
+ end
+
+ context "when browsing a `test-#` branch", :js do
+ before do
+ project.repository.create_branch('test-#', project.repository.root_ref)
+ visit(project_tree_path(project, "test-#"))
+ end
+
+ it "shows files from a repository" do
+ expect(page).to have_content("VERSION")
+ .and have_content(".gitignore")
+ .and have_content("LICENSE")
+
+ click_link("files")
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('files')
+ end
+
+ click_link("html")
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('html')
+ end
+
+ expect(page).to have_link('500.html')
+ end
+ end
+
+ context "when browsing a specific ref", :js do
+ let(:ref) { project_tree_path(project, "6d39438") }
+
+ before do
+ visit(ref)
+ end
+
+ it "shows files from a repository for `6d39438`" do
+ expect(page).to have_current_path(ref, ignore_query: true)
+ expect(page).to have_content(".gitignore").and have_content("LICENSE")
+ end
+
+ it "shows files from a repository with apostroph in its name" do
+ first(".js-project-refs-dropdown").click
+
+ page.within(".project-refs-form") do
+ click_link("'test'")
+ end
+
+ expect(page).to have_selector(".dropdown-toggle-text", text: "'test'")
+
+ visit(project_tree_path(project, "'test'"))
+
+ expect(page).not_to have_selector(".tree-commit .animation-container")
+ end
+
+ it "shows the code with a leading dot in the directory" do
+ first(".js-project-refs-dropdown").click
+
+ page.within(".project-refs-form") do
+ click_link("fix")
+ end
+
+ visit(project_tree_path(project, "fix/.testdir"))
+
+ expect(page).not_to have_selector(".tree-commit .animation-container")
+ end
+
+ it "does not show the permalink link" do
+ click_link(".gitignore")
+
+ expect(page).not_to have_link("permalink")
+ end
+ end
+
+ context "when browsing a file content", :js do
+ before do
+ visit(tree_path_root_ref)
+ wait_for_requests
+
+ click_link(".gitignore")
+ end
+
+ it "shows a file content" do
+ expect(page).to have_content("*.rbc")
+ end
+
+ it "is possible to blame" do
+ click_link("Blame")
+
+ expect(page).to have_content("*.rb")
+ .and have_content("Dmitriy Zaporozhets")
+ .and have_content("Initial commit")
+ .and have_content("Ignore DS files")
+
+ previous_commit_anchor = "//a[@title='Ignore DS files']/parent::span/following-sibling::span/a"
+ find(:xpath, previous_commit_anchor).click
+
+ expect(page).to have_content("*.rb")
+ .and have_content("Dmitriy Zaporozhets")
+ .and have_content("Initial commit")
+
+ expect(page).not_to have_content("Ignore DS files")
+ end
+ end
+
+ context "when browsing a file with pathspec characters" do
+ let(:filename) { ':wq' }
+ let(:newrev) { project.repository.commit('master').sha }
+
+ before do
+ create_file_in_repo(project, 'master', 'master', filename, 'Test file')
+ path = File.join('master', filename)
+
+ visit(project_blob_path(project, path))
+ wait_for_requests
+ end
+
+ it "shows raw file content in a new tab" do
+ new_tab = window_opened_by {click_link 'Open raw'}
+
+ within_window new_tab do
+ expect(page).to have_content("Test file")
+ end
+ end
+ end
+
+ context "when browsing a raw file" do
+ before do
+ visit(tree_path_root_ref)
+ wait_for_requests
+
+ click_link(".gitignore")
+ wait_for_requests
+ end
+
+ it "shows raw file content in a new tab" do
+ new_tab = window_opened_by {click_link 'Open raw'}
+
+ within_window new_tab do
+ expect(page).to have_content("*.rbc")
+ end
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_lfs_files_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_lfs_files_spec.rb
new file mode 100644
index 00000000000..2d9b6b3a903
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_lfs_files_spec.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Files > User browses LFS files' do
+ let(:project) { create(:project, :repository) }
+ let(:user) { project.first_owner }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ sign_in(user)
+ end
+
+ context 'when LFS is disabled', :js do
+ before do
+ allow_next_found_instance_of(Project) do |project|
+ allow(project).to receive(:lfs_enabled?).and_return(false)
+ end
+
+ visit project_tree_path(project, 'lfs')
+ wait_for_requests
+ end
+
+ it 'is possible to see raw content of LFS pointer' do
+ click_link 'files'
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('files')
+ end
+
+ click_link 'lfs'
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('lfs')
+ end
+
+ click_link 'lfs_object.iso'
+
+ expect(page).to have_content 'version https://git-lfs.github.com/spec/v1'
+ expect(page).to have_content 'oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897'
+ expect(page).to have_content 'size 1575078'
+ expect(page).not_to have_content 'Download (1.5 MB)'
+ end
+ end
+
+ context 'when LFS is enabled', :js do
+ before do
+ allow_next_found_instance_of(Project) do |project|
+ allow(project).to receive(:lfs_enabled?).and_return(true)
+ end
+
+ visit project_tree_path(project, 'lfs')
+ wait_for_requests
+ end
+
+ it 'shows an LFS object' do
+ click_link('files')
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('files')
+ end
+
+ click_link('lfs')
+ click_link('lfs_object.iso')
+
+ expect(page).to have_content('Download (1.5 MB)')
+ expect(page).not_to have_content('version https://git-lfs.github.com/spec/v1')
+ expect(page).not_to have_content('oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897')
+ expect(page).not_to have_content('size 1575078')
+
+ page.within('.content') do
+ expect(page).to have_content('Delete')
+ expect(page).to have_content('History')
+ expect(page).to have_content('Permalink')
+ expect(page).to have_content('Replace')
+ expect(page).to have_link('Download')
+
+ expect(page).not_to have_content('Annotate')
+ expect(page).not_to have_content('Blame')
+
+ expect(page).not_to have_selector(:link_or_button, text: /^Edit$/)
+ expect(page).to have_selector(:link_or_button, 'Open in Web IDE')
+ end
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/user_deletes_files_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/user_deletes_files_spec.rb
new file mode 100644
index 00000000000..d503c9b1192
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/user_deletes_files_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Files > User deletes files', :js do
+ 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 'deletes the file', :js do
+ click_link('.gitignore')
+
+ expect(page).to have_content('.gitignore')
+
+ click_on('Delete')
+ fill_in(:commit_message, with: 'New commit message', visible: true)
+ click_button('Delete file')
+
+ expect(page).to have_current_path(project_tree_path(project, 'master/'), ignore_query: true)
+ expect(page).not_to have_content('.gitignore')
+ end
+ end
+
+ context 'when an user does not have write access', :js do
+ before do
+ project2.add_reporter(user)
+ visit(project2_tree_path_root_ref)
+ wait_for_requests
+ end
+
+ it 'deletes the file in a forked project', :js, :sidekiq_might_not_need_inline do
+ click_link('.gitignore')
+
+ expect(page).to have_content('.gitignore')
+
+ click_on('Delete')
+
+ expect(page).to have_link('Fork')
+ expect(page).to have_button('Cancel')
+
+ click_link('Fork')
+
+ expect(page).to have_content(fork_message)
+
+ click_on('Delete')
+ fill_in(:commit_message, with: 'New commit message', visible: true)
+ click_button('Delete file')
+
+ fork = user.fork_of(project2.reload)
+
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
+ expect(page).to have_content('New commit message')
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/user_edits_files_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/user_edits_files_spec.rb
new file mode 100644
index 00000000000..7a70d67d8ca
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/user_edits_files_spec.rb
@@ -0,0 +1,226 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Files > User edits files', :js do
+ include ProjectForksHelper
+ include BlobSpecHelpers
+
+ 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
+
+ after do
+ unset_default_button
+ end
+
+ shared_examples 'unavailable for an archived project' do
+ it 'does not show the edit link for an archived project', :js do
+ project.update!(archived: true)
+ visit project_tree_path(project, project.repository.root_ref)
+
+ click_link('.gitignore')
+
+ aggregate_failures 'available edit buttons' do
+ expect(page).not_to have_text('Edit')
+ expect(page).not_to have_text('Web IDE')
+
+ expect(page).not_to have_text('Replace')
+ expect(page).not_to have_text('Delete')
+ end
+ end
+ end
+
+ context 'when an user has write access', :js do
+ before do
+ project.add_maintainer(user)
+ visit(project_tree_path_root_ref)
+ wait_for_requests
+ end
+
+ it 'inserts a content of a file' do
+ set_default_button('edit')
+ click_link('.gitignore')
+ click_link_or_button('Edit')
+ find('.file-editor', match: :first)
+
+ find('#editor')
+ set_editor_value('*.rbca')
+
+ expect(editor_value).to eq('*.rbca')
+ end
+
+ it 'does not show the edit link if a file is binary' do
+ binary_file = File.join(project.repository.root_ref, 'files/images/logo-black.png')
+ visit(project_blob_path(project, binary_file))
+ wait_for_requests
+
+ page.within '.content' do
+ expect(page).not_to have_link('edit')
+ end
+ end
+
+ it 'commits an edited file' do
+ set_default_button('edit')
+ click_link('.gitignore')
+ click_link_or_button('Edit')
+ find('.file-editor', match: :first)
+
+ find('#editor')
+ set_editor_value('*.rbca')
+ fill_in(:commit_message, with: 'New commit message', visible: true)
+ click_button('Commit changes')
+
+ expect(page).to have_current_path(project_blob_path(project, 'master/.gitignore'), ignore_query: true)
+
+ wait_for_requests
+
+ expect(page).to have_content('*.rbca')
+ end
+
+ it 'commits an edited file to a new branch' do
+ set_default_button('edit')
+ click_link('.gitignore')
+ click_link_or_button('Edit')
+
+ find('.file-editor', match: :first)
+
+ find('#editor')
+ set_editor_value('*.rbca')
+ fill_in(:commit_message, with: 'New commit message', visible: true)
+ fill_in(:branch_name, with: 'new_branch_name', visible: true)
+ click_button('Commit changes')
+
+ expect(page).to have_current_path(project_new_merge_request_path(project), ignore_query: true)
+
+ click_link('Changes')
+
+ expect(page).to have_content('*.rbca')
+ end
+
+ it 'shows the diff of an edited file' do
+ set_default_button('edit')
+ click_link('.gitignore')
+ click_link_or_button('Edit')
+ find('.file-editor', match: :first)
+
+ find('#editor')
+ set_editor_value('*.rbca')
+ click_link('Preview changes')
+
+ expect(page).to have_css('.line_holder.new')
+ end
+
+ it_behaves_like 'unavailable for an archived project'
+ end
+
+ context 'when an user does not have write access', :js do
+ before do
+ project2.add_reporter(user)
+ visit(project2_tree_path_root_ref)
+ wait_for_requests
+ end
+
+ def expect_fork_prompt
+ expect(page).to have_selector(:link_or_button, 'Fork')
+ expect(page).to have_selector(:link_or_button, 'Cancel')
+ expect(page).to have_content(
+ "You can’t edit files directly in this project. "\
+ "Fork this project and submit a merge request with your changes."
+ )
+ end
+
+ def expect_fork_status
+ expect(page).to have_content(
+ "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
+
+ it 'inserts a content of a file in a forked project', :sidekiq_might_not_need_inline do
+ set_default_button('edit')
+ click_link('.gitignore')
+ click_link_or_button('Edit')
+
+ expect_fork_prompt
+
+ click_link_or_button('Fork project')
+
+ expect_fork_status
+
+ find('.file-editor', match: :first)
+
+ find('#editor')
+ set_editor_value('*.rbca')
+
+ expect(editor_value).to eq('*.rbca')
+ end
+
+ it 'commits an edited file in a forked project', :sidekiq_might_not_need_inline do
+ set_default_button('edit')
+ click_link('.gitignore')
+ click_link_or_button('Edit')
+
+ expect_fork_prompt
+ click_link_or_button('Fork project')
+
+ find('.file-editor', match: :first)
+
+ find('#editor')
+ set_editor_value('*.rbca')
+ fill_in(:commit_message, with: 'New commit message', visible: true)
+ click_button('Commit changes')
+
+ fork = user.fork_of(project2.reload)
+
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
+
+ wait_for_requests
+
+ expect(page).to have_content('New commit message')
+ end
+
+ context 'when the user already had a fork of the project', :js do
+ let!(:forked_project) { fork_project(project2, user, namespace: user.namespace, repository: true) }
+
+ before do
+ visit(project2_tree_path_root_ref)
+ wait_for_requests
+ end
+
+ it 'links to the forked project for editing', :sidekiq_might_not_need_inline do
+ set_default_button('edit')
+ click_link('.gitignore')
+ click_link_or_button('Edit')
+
+ expect(page).not_to have_link('Fork project')
+
+ find('#editor')
+ set_editor_value('*.rbca')
+ fill_in(:commit_message, with: 'Another commit', visible: true)
+ click_button('Commit changes')
+
+ fork = user.fork_of(project2)
+
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
+
+ wait_for_requests
+
+ expect(page).to have_content('Another commit')
+ expect(page).to have_content("From #{forked_project.full_path}")
+ expect(page).to have_content("into #{project2.full_path}")
+ end
+
+ it_behaves_like 'unavailable for an archived project' do
+ let(:project) { project2 }
+ end
+ end
+ end
+end
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
new file mode 100644
index 00000000000..5561cf15a66
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/user_replaces_files_spec.rb
@@ -0,0 +1,93 @@
+# 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/search/user_searches_for_code_spec.rb b/spec/features/search/user_searches_for_code_spec.rb
index c04a4493a9b..53c95b4a446 100644
--- a/spec/features/search/user_searches_for_code_spec.rb
+++ b/spec/features/search/user_searches_for_code_spec.rb
@@ -42,7 +42,7 @@ RSpec.describe 'User searches for code' do
it 'finds code and links to blob' do
fill_in('dashboard_search', with: 'rspec')
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
expect(page).to have_selector('.results', text: 'Update capybara, rspec-rails, poltergeist to recent versions')
@@ -52,7 +52,7 @@ RSpec.describe 'User searches for code' do
it 'finds code and links to blame' do
fill_in('dashboard_search', with: 'rspec')
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
expect(page).to have_selector('.results', text: 'Update capybara, rspec-rails, poltergeist to recent versions')
@@ -65,7 +65,7 @@ RSpec.describe 'User searches for code' do
search = 'for naming files'
fill_in('dashboard_search', with: search)
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
expect(page).to have_selector('.results', text: expected_result)
@@ -80,46 +80,103 @@ RSpec.describe 'User searches for code' do
end
end
- context 'search code within refs', :js do
- let(:ref_name) { 'v1.0.0' }
+ context 'when :new_header_search is true' do
+ context 'search code within refs', :js do
+ let(:ref_name) { 'v1.0.0' }
- before do
- visit(project_tree_path(project, ref_name))
+ before do
+ # This feature is diabled by default in spec_helper.rb.
+ # We missed a feature breaking bug, so to prevent this regression, testing both scenarios for this spec.
+ # This can be removed as part of closing https://gitlab.com/gitlab-org/gitlab/-/issues/339348.
+ stub_feature_flags(new_header_search: true)
+ visit(project_tree_path(project, ref_name))
- submit_search('gitlab-grack')
- select_search_scope('Code')
- end
+ submit_search('gitlab-grack')
+ select_search_scope('Code')
+ end
- it 'shows ref switcher in code result summary' do
- expect(find('.js-project-refs-dropdown')).to have_text(ref_name)
- end
- it 'persists branch name across search' do
- find('.btn-search').click
- expect(find('.js-project-refs-dropdown')).to have_text(ref_name)
- end
+ it 'shows ref switcher in code result summary' do
+ expect(find('.js-project-refs-dropdown')).to have_text(ref_name)
+ end
- # this example is use to test the desgine that the refs is not
- # only repersent the branch as well as the tags.
- it 'ref swither list all the branchs and tags' do
- find('.js-project-refs-dropdown').click
- expect(find('.dropdown-page-one .dropdown-content')).to have_link('sha-starting-with-large-number')
- expect(find('.dropdown-page-one .dropdown-content')).to have_link('v1.0.0')
- end
+ it 'persists branch name across search' do
+ find('.gl-search-box-by-click-search-button').click
+ expect(find('.js-project-refs-dropdown')).to have_text(ref_name)
+ end
+
+ # this example is use to test the desgine that the refs is not
+ # only repersent the branch as well as the tags.
+ it 'ref swither list all the branchs and tags' do
+ find('.js-project-refs-dropdown').click
+ expect(find('.dropdown-page-one .dropdown-content')).to have_link('sha-starting-with-large-number')
+ expect(find('.dropdown-page-one .dropdown-content')).to have_link('v1.0.0')
+ end
- it 'search result changes when refs switched' do
- expect(find('.results')).not_to have_content('path = gitlab-grack')
+ it 'search result changes when refs switched' do
+ expect(find('.results')).not_to have_content('path = gitlab-grack')
- find('.js-project-refs-dropdown').click
- find('.dropdown-page-one .dropdown-content').click_link('master')
+ find('.js-project-refs-dropdown').click
+ find('.dropdown-page-one .dropdown-content').click_link('master')
- expect(page).to have_selector('.results', text: 'path = gitlab-grack')
+ expect(page).to have_selector('.results', text: 'path = gitlab-grack')
+ end
+
+ it 'persist refs over browser tabs' do
+ ref = 'feature'
+ find('.js-project-refs-dropdown').click
+ link = find_link(ref)[:href]
+ expect(link.include?("repository_ref=" + ref)).to be(true)
+ end
end
+ end
- it 'persist refs over browser tabs' do
- ref = 'feature'
- find('.js-project-refs-dropdown').click
- link = find_link(ref)[:href]
- expect(link.include?("repository_ref=" + ref)).to be(true)
+ context 'when :new_header_search is false' do
+ context 'search code within refs', :js do
+ let(:ref_name) { 'v1.0.0' }
+
+ before do
+ # This feature is diabled by default in spec_helper.rb.
+ # We missed a feature breaking bug, so to prevent this regression, testing both scenarios for this spec.
+ # This can be removed as part of closing https://gitlab.com/gitlab-org/gitlab/-/issues/339348.
+ stub_feature_flags(new_header_search: false)
+ visit(project_tree_path(project, ref_name))
+
+ submit_search('gitlab-grack')
+ select_search_scope('Code')
+ end
+
+ it 'shows ref switcher in code result summary' do
+ expect(find('.js-project-refs-dropdown')).to have_text(ref_name)
+ end
+
+ it 'persists branch name across search' do
+ find('.gl-search-box-by-click-search-button').click
+ expect(find('.js-project-refs-dropdown')).to have_text(ref_name)
+ end
+
+ # this example is use to test the desgine that the refs is not
+ # only repersent the branch as well as the tags.
+ it 'ref swither list all the branchs and tags' do
+ find('.js-project-refs-dropdown').click
+ expect(find('.dropdown-page-one .dropdown-content')).to have_link('sha-starting-with-large-number')
+ expect(find('.dropdown-page-one .dropdown-content')).to have_link('v1.0.0')
+ end
+
+ it 'search result changes when refs switched' do
+ expect(find('.results')).not_to have_content('path = gitlab-grack')
+
+ find('.js-project-refs-dropdown').click
+ find('.dropdown-page-one .dropdown-content').click_link('master')
+
+ expect(page).to have_selector('.results', text: 'path = gitlab-grack')
+ end
+
+ it 'persist refs over browser tabs' do
+ ref = 'feature'
+ find('.js-project-refs-dropdown').click
+ link = find_link(ref)[:href]
+ expect(link.include?("repository_ref=" + ref)).to be(true)
+ end
end
end
diff --git a/spec/features/search/user_searches_for_issues_spec.rb b/spec/features/search/user_searches_for_issues_spec.rb
index b0902096770..c23a54594d4 100644
--- a/spec/features/search/user_searches_for_issues_spec.rb
+++ b/spec/features/search/user_searches_for_issues_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe 'User searches for issues', :js do
def search_for_issue(search)
fill_in('dashboard_search', with: search)
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
select_search_scope('Issues')
end
diff --git a/spec/features/search/user_searches_for_merge_requests_spec.rb b/spec/features/search/user_searches_for_merge_requests_spec.rb
index d7f490ba9bc..61c61d793db 100644
--- a/spec/features/search/user_searches_for_merge_requests_spec.rb
+++ b/spec/features/search/user_searches_for_merge_requests_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe 'User searches for merge requests', :js do
def search_for_mr(search)
fill_in('dashboard_search', with: search)
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
select_search_scope('Merge requests')
end
diff --git a/spec/features/search/user_searches_for_milestones_spec.rb b/spec/features/search/user_searches_for_milestones_spec.rb
index 7a1ec16385c..61f2e8e0c8f 100644
--- a/spec/features/search/user_searches_for_milestones_spec.rb
+++ b/spec/features/search/user_searches_for_milestones_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe 'User searches for milestones', :js do
it 'finds a milestone' do
fill_in('dashboard_search', with: milestone1.title)
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
select_search_scope('Milestones')
page.within('.results') do
@@ -40,7 +40,7 @@ RSpec.describe 'User searches for milestones', :js do
end
fill_in('dashboard_search', with: milestone1.title)
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
select_search_scope('Milestones')
page.within('.results') do
diff --git a/spec/features/search/user_searches_for_wiki_pages_spec.rb b/spec/features/search/user_searches_for_wiki_pages_spec.rb
index 06545d8640f..9808383adb7 100644
--- a/spec/features/search/user_searches_for_wiki_pages_spec.rb
+++ b/spec/features/search/user_searches_for_wiki_pages_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'User searches for wiki pages', :js do
end
fill_in('dashboard_search', with: search_term)
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
select_search_scope('Wiki')
page.within('.results') do
diff --git a/spec/features/static_site_editor_spec.rb b/spec/features/static_site_editor_spec.rb
index a47579582e2..98313905a33 100644
--- a/spec/features/static_site_editor_spec.rb
+++ b/spec/features/static_site_editor_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Static Site Editor' do
+ include ContentSecurityPolicyHelpers
+
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public, :repository) }
@@ -79,10 +81,7 @@ RSpec.describe 'Static Site Editor' do
context 'when no global CSP config exists' do
before do
- expect_next_instance_of(Projects::StaticSiteEditorController) do |controller|
- expect(controller).to receive(:current_content_security_policy)
- .and_return(ActionDispatch::ContentSecurityPolicy.new)
- end
+ setup_csp_for_controller(Projects::StaticSiteEditorController)
end
it 'does not add CSP directives' do
@@ -101,9 +100,7 @@ RSpec.describe 'Static Site Editor' do
p.frame_src :self, cdn_url
end
- expect_next_instance_of(Projects::StaticSiteEditorController) do |controller|
- expect(controller).to receive(:current_content_security_policy).and_return(csp)
- end
+ setup_existing_csp_for_controller(Projects::StaticSiteEditorController, csp)
end
it 'appends youtube to the CSP frame-src policy' do
diff --git a/spec/features/tags/developer_creates_tag_spec.rb b/spec/features/tags/developer_creates_tag_spec.rb
index f982d403ce1..b0219cb546d 100644
--- a/spec/features/tags/developer_creates_tag_spec.rb
+++ b/spec/features/tags/developer_creates_tag_spec.rb
@@ -38,8 +38,8 @@ RSpec.describe 'Developer creates tag' do
it 'with multiline message displays the message in a <pre> block' do
create_tag_in_form(tag: 'v3.0', ref: 'master', message: "Awesome tag message\n\n- hello\n- world")
- expect(current_path).to eq(
- project_tag_path(project, 'v3.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v3.0'), ignore_query: true)
expect(page).to have_content 'v3.0'
page.within 'pre.wrap' do
expect(page).to have_content "Awesome tag message - hello - world"
@@ -49,8 +49,8 @@ RSpec.describe 'Developer creates tag' do
it 'with multiline release notes parses the release note as Markdown' do
create_tag_in_form(tag: 'v4.0', ref: 'master', desc: "Awesome release notes\n\n- hello\n- world")
- expect(current_path).to eq(
- project_tag_path(project, 'v4.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v4.0'), ignore_query: true)
expect(page).to have_content 'v4.0'
page.within '.description' do
expect(page).to have_content 'Awesome release notes'
diff --git a/spec/features/tags/developer_deletes_tag_spec.rb b/spec/features/tags/developer_deletes_tag_spec.rb
index 7c4c6f54685..6b669695f7b 100644
--- a/spec/features/tags/developer_deletes_tag_spec.rb
+++ b/spec/features/tags/developer_deletes_tag_spec.rb
@@ -27,13 +27,13 @@ RSpec.describe 'Developer deletes tag', :js do
context 'from a specific tag page' do
it 'deletes the tag' do
click_on 'v1.0.0'
- expect(current_path).to eq(
- project_tag_path(project, 'v1.0.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v1.0.0'), ignore_query: true)
container = page.find('.nav-controls')
delete_tag container
- expect(current_path).to eq("#{project_tags_path(project)}/")
+ expect(page).to have_current_path("#{project_tags_path(project)}/", ignore_query: true)
expect(page).not_to have_content 'v1.0.0'
end
end
diff --git a/spec/features/tags/developer_updates_tag_spec.rb b/spec/features/tags/developer_updates_tag_spec.rb
index 93a275131bd..b2fc28b8493 100644
--- a/spec/features/tags/developer_updates_tag_spec.rb
+++ b/spec/features/tags/developer_updates_tag_spec.rb
@@ -20,8 +20,8 @@ RSpec.describe 'Developer updates tag' do
fill_in 'release_description', with: 'Awesome release notes'
click_button 'Save changes'
- expect(current_path).to eq(
- project_tag_path(project, 'v1.1.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v1.1.0'), ignore_query: true)
expect(page).to have_content 'v1.1.0'
expect(page).to have_content 'Awesome release notes'
end
@@ -45,8 +45,8 @@ RSpec.describe 'Developer updates tag' do
fill_in 'release_description', with: 'Awesome release notes'
click_button 'Save changes'
- expect(current_path).to eq(
- project_tag_path(project, 'v1.1.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v1.1.0'), ignore_query: true)
expect(page).to have_content 'v1.1.0'
expect(page).to have_content 'Awesome release notes'
end
diff --git a/spec/features/tags/developer_views_tags_spec.rb b/spec/features/tags/developer_views_tags_spec.rb
index 6bae53afe6f..57e1f7da04e 100644
--- a/spec/features/tags/developer_views_tags_spec.rb
+++ b/spec/features/tags/developer_views_tags_spec.rb
@@ -55,8 +55,8 @@ RSpec.describe 'Developer views tags' do
it 'views a specific tag page' do
click_on 'v1.0.0'
- expect(current_path).to eq(
- project_tag_path(project, 'v1.0.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v1.0.0'), ignore_query: true)
expect(page).to have_content 'v1.0.0'
expect(page).to have_content 'This tag has no release notes.'
end
@@ -65,25 +65,25 @@ RSpec.describe 'Developer views tags' do
it 'has a button to browse files' do
click_on 'v1.0.0'
- expect(current_path).to eq(
- project_tag_path(project, 'v1.0.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v1.0.0'), ignore_query: true)
click_on 'Browse files'
- expect(current_path).to eq(
- project_tree_path(project, 'v1.0.0'))
+ expect(page).to have_current_path(
+ project_tree_path(project, 'v1.0.0'), ignore_query: true)
end
it 'has a button to browse commits' do
click_on 'v1.0.0'
- expect(current_path).to eq(
- project_tag_path(project, 'v1.0.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v1.0.0'), ignore_query: true)
click_on 'Browse commits'
- expect(current_path).to eq(
- project_commits_path(project, 'v1.0.0'))
+ expect(page).to have_current_path(
+ project_commits_path(project, 'v1.0.0'), ignore_query: true)
end
end
end
diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb
index 1f1824c897e..7f5cf2359a3 100644
--- a/spec/features/triggers_spec.rb
+++ b/spec/features/triggers_spec.rb
@@ -17,6 +17,8 @@ RSpec.describe 'Triggers', :js do
@project.add_guest(guest_user)
visit project_settings_ci_cd_path(@project)
+
+ wait_for_requests
end
shared_examples 'triggers page' do
diff --git a/spec/features/unsubscribe_links_spec.rb b/spec/features/unsubscribe_links_spec.rb
index b7471720008..3fe276ce162 100644
--- a/spec/features/unsubscribe_links_spec.rb
+++ b/spec/features/unsubscribe_links_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe 'Unsubscribe links', :sidekiq_might_not_need_inline do
it 'shows the unsubscribe confirmation page and redirects to root path when confirming' do
visit body_link
- expect(current_path).to eq unsubscribe_sent_notification_path(SentNotification.last)
+ expect(page).to have_current_path unsubscribe_sent_notification_path(SentNotification.last), ignore_query: true
expect(page).to have_text(%(Unsubscribe from issue))
expect(page).to have_text(%(Are you sure you want to unsubscribe from the issue: #{issue.title} (#{issue.to_reference})?))
expect(issue.subscribed?(recipient, project)).to be_truthy
@@ -33,19 +33,19 @@ RSpec.describe 'Unsubscribe links', :sidekiq_might_not_need_inline do
click_link 'Unsubscribe'
expect(issue.subscribed?(recipient, project)).to be_falsey
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
it 'shows the unsubscribe confirmation page and redirects to root path when canceling' do
visit body_link
- expect(current_path).to eq unsubscribe_sent_notification_path(SentNotification.last)
+ expect(page).to have_current_path unsubscribe_sent_notification_path(SentNotification.last), ignore_query: true
expect(issue.subscribed?(recipient, project)).to be_truthy
click_link 'Cancel'
expect(issue.subscribed?(recipient, project)).to be_truthy
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
end
diff --git a/spec/features/users/active_sessions_spec.rb b/spec/features/users/active_sessions_spec.rb
index 6dc93fe017f..c722a4ec05c 100644
--- a/spec/features/users/active_sessions_spec.rb
+++ b/spec/features/users/active_sessions_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe 'Active user sessions', :clean_gitlab_redis_sessions do
Timecop.freeze(now) do
user = create(:user)
gitlab_sign_in(user)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
sessions = ActiveSession.list(user)
expect(sessions.count).to eq 1
@@ -59,12 +59,12 @@ RSpec.describe 'Active user sessions', :clean_gitlab_redis_sessions do
it 'logout deletes the active user login' do
user = create(:user)
gitlab_sign_in(user)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
expect(ActiveSession.list(user).count).to eq 1
gitlab_sign_out
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
expect(ActiveSession.list(user)).to be_empty
end
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index 2780549eea1..4d06415e203 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect(user.reset_password_token).not_to be_nil
gitlab_sign_in(user)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
user.reload
expect(user.reset_password_token).to be_nil
@@ -46,14 +46,14 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
user = create(:admin, password_automatically_set: true)
visit root_path
- expect(current_path).to eq edit_user_password_path
+ expect(page).to have_current_path edit_user_password_path, ignore_query: true
expect(page).to have_content('Please create a password for your new account.')
fill_in 'user_password', with: Gitlab::Password.test_default
fill_in 'user_password_confirmation', with: Gitlab::Password.test_default
click_button 'Change your password'
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
expect(page).to have_content(I18n.t('devise.passwords.updated_not_active'))
fill_in 'user_login', with: user.username
@@ -61,7 +61,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
click_button 'Sign in'
expect_single_session_with_authenticated_ttl
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
it 'does not show flash messages when login page' do
@@ -145,7 +145,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
fill_in 'user_email', with: user.email
click_button 'Resend'
- expect(current_path).to eq users_almost_there_path
+ expect(page).to have_current_path users_almost_there_path, ignore_query: true
end
end
end
@@ -226,7 +226,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
enter_code(user.current_otp)
expect_single_session_with_authenticated_ttl
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
it 'persists remember_me value via hidden field' do
@@ -255,7 +255,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
enter_code(user.current_otp)
expect_single_session_with_authenticated_ttl
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
it 'triggers ActiveSession.cleanup for the user' do
@@ -286,7 +286,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
enter_code(codes.sample)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
it 'invalidates the used code' do
@@ -373,7 +373,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect_single_session_with_authenticated_ttl
expect(page).not_to have_content('Two-Factor Authentication')
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
@@ -391,7 +391,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
enter_code(user.current_otp)
expect_single_session_with_authenticated_ttl
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
@@ -412,7 +412,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
expect_single_session_with_authenticated_ttl
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
expect(page).not_to have_content(I18n.t('devise.failure.already_authenticated'))
end
@@ -437,7 +437,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
context 'when the users password is expired' do
before do
- user.update!(password_expires_at: Time.parse('2018-05-08 11:29:46 UTC'))
+ user.update!(password_expires_at: Time.zone.parse('2018-05-08 11:29:46 UTC'))
end
it 'asks for a new password' do
@@ -450,7 +450,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
fill_in 'user_password', with: Gitlab::Password.test_default
click_button 'Sign in'
- expect(current_path).to eq(new_profile_password_path)
+ expect(page).to have_current_path(new_profile_password_path, ignore_query: true)
end
end
end
@@ -493,7 +493,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).to have_content('The global settings require you to enable Two-Factor Authentication for your account. You need to do this before ')
end
@@ -503,9 +503,9 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
click_link 'Configure it later'
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
@@ -518,7 +518,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).to have_content(
'The global settings require you to enable Two-Factor Authentication for your account.'
)
@@ -530,7 +530,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).not_to have_link('Configure it later')
end
end
@@ -547,7 +547,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).to have_content(
'The global settings require you to enable Two-Factor Authentication for your account.'
)
@@ -576,7 +576,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).to have_content(
'The group settings for Group 1 and Group 2 require you to enable '\
'Two-Factor Authentication for your account. '\
@@ -594,9 +594,9 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
click_link 'Configure it later'
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
@@ -609,7 +609,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).to have_content(
'The group settings for Group 1 and Group 2 require you to enable ' \
'Two-Factor Authentication for your account.'
@@ -622,7 +622,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).not_to have_link('Configure it later')
end
end
@@ -639,7 +639,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).to have_content(
'The group settings for Group 1 and Group 2 require you to enable ' \
'Two-Factor Authentication for your account. '\
@@ -775,7 +775,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
click_button 'Accept terms'
- expect(current_path).to eq(root_path)
+ expect(page).to have_current_path(root_path, ignore_query: true)
expect(page).not_to have_content(I18n.t('devise.failure.already_authenticated'))
end
@@ -792,11 +792,12 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
click_button 'Sign in'
- expect(current_path).to eq(root_path)
+ expect(page).to have_current_path(root_path, ignore_query: true)
end
context 'when 2FA is required for the user' do
before do
+ stub_feature_flags(mr_attention_requests: false)
group = create(:group, require_two_factor_authentication: true)
group.add_developer(user)
end
@@ -816,7 +817,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect_to_be_on_terms_page
click_button 'Accept terms'
- expect(current_path).to eq(profile_two_factor_auth_path)
+ expect(page).to have_current_path(profile_two_factor_auth_path, ignore_query: true)
fill_in 'pin_code', with: user.reload.current_otp
fill_in 'current_password', with: user.password
@@ -825,7 +826,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
click_button 'Copy codes'
click_link 'Proceed'
- expect(current_path).to eq(profile_account_path)
+ expect(page).to have_current_path(profile_account_path, ignore_query: true)
expect(page).to have_content('You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can use that key to generate additional recovery codes.')
end
end
@@ -853,14 +854,14 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect_to_be_on_terms_page
click_button 'Accept terms'
- expect(current_path).to eq(root_path)
+ expect(page).to have_current_path(root_path, ignore_query: true)
end
end
end
context 'when the users password is expired' do
before do
- user.update!(password_expires_at: Time.parse('2018-05-08 11:29:46 UTC'))
+ user.update!(password_expires_at: Time.zone.parse('2018-05-08 11:29:46 UTC'))
end
it 'asks the user to accept the terms before setting a new password' do
@@ -876,7 +877,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect_to_be_on_terms_page
click_button 'Accept terms'
- expect(current_path).to eq(new_profile_password_path)
+ expect(page).to have_current_path(new_profile_password_path, ignore_query: true)
fill_in 'user_password', with: Gitlab::Password.test_default
fill_in 'user_new_password', with: 'new password'
@@ -903,7 +904,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect_to_be_on_terms_page
click_button 'Accept terms'
- expect(current_path).to eq(profile_path)
+ expect(page).to have_current_path(profile_path, ignore_query: true)
fill_in 'Email', with: 'hello@world.com'
@@ -931,7 +932,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
expect(page).to have_content("Please check your email (#{user.email}) to verify that you own this address and unlock the power of CI/CD.")
end
@@ -944,7 +945,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
expect(page).to have_content(alert_title)
expect(page).to have_content(alert_message)
expect(page).to have_link('Resend confirmation email', href: new_user_confirmation_path)
diff --git a/spec/features/users/logout_spec.rb b/spec/features/users/logout_spec.rb
index 3129eb5e6f3..596f0dd5a94 100644
--- a/spec/features/users/logout_spec.rb
+++ b/spec/features/users/logout_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe 'Logout/Sign out', :js do
it 'sign out redirects to sign in page' do
gitlab_sign_out
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
it 'sign out does not show signed out flash notice' do
@@ -30,7 +30,7 @@ RSpec.describe 'Logout/Sign out', :js do
it 'sign out redirects to sign in page' do
gitlab_sign_out
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
end
end
diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb
index 8edbf639c81..cb395846b96 100644
--- a/spec/features/users/show_spec.rb
+++ b/spec/features/users/show_spec.rb
@@ -426,7 +426,7 @@ RSpec.describe 'User page' do
end
context 'structured markup' do
- let_it_be(:user) { create(:user, website_url: 'https://gitlab.com', organization: 'GitLab', job_title: 'Frontend Engineer', email: 'public@example.com', public_email: 'public@example.com', location: 'Country', created_at: Time.now, updated_at: Time.now) }
+ let_it_be(:user) { create(:user, website_url: 'https://gitlab.com', organization: 'GitLab', job_title: 'Frontend Engineer', email: 'public@example.com', public_email: 'public@example.com', location: 'Country', created_at: Time.zone.now, updated_at: Time.zone.now) }
it 'shows Person structured markup' do
subject
diff --git a/spec/features/users/signup_spec.rb b/spec/features/users/signup_spec.rb
index a651a6c09c6..3eae4955167 100644
--- a/spec/features/users/signup_spec.rb
+++ b/spec/features/users/signup_spec.rb
@@ -203,7 +203,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
expect { click_button 'Register' }.to change { User.count }.by(1)
- expect(current_path).to eq users_almost_there_path
+ expect(page).to have_current_path users_almost_there_path, ignore_query: true
expect(page).to have_content("Please check your email (#{new_user.email}) to confirm your account")
confirm_email
@@ -223,7 +223,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
expect { click_button 'Register' }.to change { User.count }.by(1)
- expect(current_path).to eq users_sign_up_welcome_path
+ expect(page).to have_current_path users_sign_up_welcome_path, ignore_query: true
end
end
end
@@ -239,7 +239,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
click_button "Register"
- expect(current_path).to eq users_sign_up_welcome_path
+ expect(page).to have_current_path users_sign_up_welcome_path, ignore_query: true
end
end
@@ -254,7 +254,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
expect { click_button 'Register' }.to change { User.count }.by(1)
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
expect(page).to have_content("You have signed up successfully. However, we could not sign you in because your account is awaiting approval from your GitLab administrator")
end
end
@@ -268,7 +268,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
click_button "Register"
- expect(current_path).to eq user_registration_path
+ expect(page).to have_current_path user_registration_path, ignore_query: true
expect(page).to have_content("error prohibited this user from being saved")
expect(page).to have_content("Email has already been taken")
end
@@ -280,7 +280,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
click_button "Register"
- expect(current_path).to eq user_registration_path
+ expect(page).to have_current_path user_registration_path, ignore_query: true
expect(page.body).not_to match(/#{new_user.password}/)
end
end
@@ -298,7 +298,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
click_button 'Register'
- expect(current_path).to eq users_sign_up_welcome_path
+ expect(page).to have_current_path users_sign_up_welcome_path, ignore_query: true
end
end
@@ -324,7 +324,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
expect { click_button 'Register' }.not_to change { User.count }
- expect(page).to have_content('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.')
+ expect(page).to have_content(_('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'))
end
end
diff --git a/spec/features/users/terms_spec.rb b/spec/features/users/terms_spec.rb
index 7cfe74f8aa9..7a662d24d60 100644
--- a/spec/features/users/terms_spec.rb
+++ b/spec/features/users/terms_spec.rb
@@ -82,7 +82,7 @@ RSpec.describe 'Users > Terms', :js do
click_link 'Continue'
- expect(current_path).to eq(root_path)
+ expect(page).to have_current_path(root_path, ignore_query: true)
end
end
@@ -99,7 +99,7 @@ RSpec.describe 'Users > Terms', :js do
enforce_terms
# Application settings are cached for a minute
- Timecop.travel 2.minutes do
+ travel_to 2.minutes.from_now do
within('.nav-sidebar') do
click_link 'Issues'
end
@@ -108,7 +108,7 @@ RSpec.describe 'Users > Terms', :js do
click_button('Accept terms')
- expect(current_path).to eq(project_issues_path(project))
+ expect(page).to have_current_path(project_issues_path(project), ignore_query: true)
end
end
@@ -123,11 +123,11 @@ RSpec.describe 'Users > Terms', :js do
click_button 'Create issue'
- expect(current_path).to eq(terms_path)
+ expect(page).to have_current_path(terms_path, ignore_query: true)
click_button('Accept terms')
- expect(current_path).to eq(new_project_issue_path(project))
+ expect(page).to have_current_path(new_project_issue_path(project), ignore_query: true)
expect(find_field('issue_title').value).to eq('Hello world, a new issue')
expect(find_field('issue_description').value).to eq("We don't want to lose what the user typed")
end