summaryrefslogtreecommitdiff
path: root/spec/features
diff options
context:
space:
mode:
Diffstat (limited to 'spec/features')
-rw-r--r--spec/features/admin/admin_appearance_spec.rb4
-rw-r--r--spec/features/admin/admin_hook_logs_spec.rb4
-rw-r--r--spec/features/admin/admin_jobs_spec.rb (renamed from spec/features/admin/admin_builds_spec.rb)20
-rw-r--r--spec/features/admin/admin_mode/login_spec.rb2
-rw-r--r--spec/features/admin/admin_projects_spec.rb2
-rw-r--r--spec/features/admin/admin_serverless_domains_spec.rb89
-rw-r--r--spec/features/admin/admin_settings_spec.rb66
-rw-r--r--spec/features/boards/new_issue_spec.rb22
-rw-r--r--spec/features/boards/reload_boards_on_browser_back_spec.rb4
-rw-r--r--spec/features/boards/sidebar_labels_spec.rb50
-rw-r--r--spec/features/clusters/cluster_detail_page_spec.rb2
-rw-r--r--spec/features/cycle_analytics_spec.rb59
-rw-r--r--spec/features/dashboard/activity_spec.rb6
-rw-r--r--spec/features/dashboard/issuables_counter_spec.rb2
-rw-r--r--spec/features/groups/board_spec.rb2
-rw-r--r--spec/features/groups/container_registry_spec.rb12
-rw-r--r--spec/features/groups/dependency_proxy_for_containers_spec.rb108
-rw-r--r--spec/features/groups/dependency_proxy_spec.rb50
-rw-r--r--spec/features/groups/import_export/connect_instance_spec.rb34
-rw-r--r--spec/features/groups/import_export/migration_history_spec.rb30
-rw-r--r--spec/features/groups/members/manage_groups_spec.rb11
-rw-r--r--spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb15
-rw-r--r--spec/features/groups/milestone_spec.rb8
-rw-r--r--spec/features/groups/packages_spec.rb4
-rw-r--r--spec/features/issues/related_issues_spec.rb98
-rw-r--r--spec/features/markdown/copy_as_gfm_spec.rb9
-rw-r--r--spec/features/markdown/markdown_spec.rb8
-rw-r--r--spec/features/merge_request/user_merges_immediately_spec.rb2
-rw-r--r--spec/features/merge_request/user_resolves_conflicts_spec.rb19
-rw-r--r--spec/features/merge_request/user_sees_deployment_widget_spec.rb32
-rw-r--r--spec/features/merge_request/user_sees_merge_widget_spec.rb12
-rw-r--r--spec/features/merge_request/user_sees_suggest_pipeline_spec.rb11
-rw-r--r--spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb2
-rw-r--r--spec/features/merge_request/user_suggests_changes_on_diff_spec.rb10
-rw-r--r--spec/features/profiles/password_spec.rb10
-rw-r--r--spec/features/profiles/two_factor_auths_spec.rb4
-rw-r--r--spec/features/profiles/user_edit_profile_spec.rb52
-rw-r--r--spec/features/projects/badges/coverage_spec.rb129
-rw-r--r--spec/features/projects/badges/pipeline_badge_spec.rb2
-rw-r--r--spec/features/projects/ci/lint_spec.rb2
-rw-r--r--spec/features/projects/container_registry_spec.rb12
-rw-r--r--spec/features/projects/environments/environments_spec.rb5
-rw-r--r--spec/features/projects/files/user_creates_directory_spec.rb2
-rw-r--r--spec/features/projects/files/user_uploads_files_spec.rb14
-rw-r--r--spec/features/projects/infrastructure_registry_spec.rb6
-rw-r--r--spec/features/projects/jobs/user_browses_jobs_spec.rb282
-rw-r--r--spec/features/projects/jobs_spec.rb8
-rw-r--r--spec/features/projects/members/groups_with_access_list_spec.rb11
-rw-r--r--spec/features/projects/members/invite_group_spec.rb7
-rw-r--r--spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb18
-rw-r--r--spec/features/projects/navbar_spec.rb1
-rw-r--r--spec/features/projects/new_project_spec.rb8
-rw-r--r--spec/features/projects/packages_spec.rb4
-rw-r--r--spec/features/projects/settings/monitor_settings_spec.rb35
-rw-r--r--spec/features/projects/settings/webhooks_settings_spec.rb4
-rw-r--r--spec/features/projects/show/user_uploads_files_spec.rb22
-rw-r--r--spec/features/projects/user_creates_project_spec.rb23
-rw-r--r--spec/features/security/project/internal_access_spec.rb1
-rw-r--r--spec/features/security/project/private_access_spec.rb1
-rw-r--r--spec/features/security/project/public_access_spec.rb1
-rw-r--r--spec/features/snippets/notes_on_personal_snippets_spec.rb4
-rw-r--r--spec/features/users/login_spec.rb18
-rw-r--r--spec/features/users/show_spec.rb19
63 files changed, 1082 insertions, 432 deletions
diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb
index cd148642b90..cb69eac8035 100644
--- a/spec/features/admin/admin_appearance_spec.rb
+++ b/spec/features/admin/admin_appearance_spec.rb
@@ -34,6 +34,10 @@ RSpec.describe 'Admin Appearance' do
visit admin_application_settings_appearances_path
click_link "Sign-in page"
+ expect(find('#login')).to be_disabled
+ expect(find('#password')).to be_disabled
+ expect(find('button')).to be_disabled
+
expect_custom_sign_in_appearance(appearance)
end
diff --git a/spec/features/admin/admin_hook_logs_spec.rb b/spec/features/admin/admin_hook_logs_spec.rb
index 3f63bf9a15c..837cab49bd4 100644
--- a/spec/features/admin/admin_hook_logs_spec.rb
+++ b/spec/features/admin/admin_hook_logs_spec.rb
@@ -17,8 +17,8 @@ RSpec.describe 'Admin::HookLogs' do
hook_log
visit edit_admin_hook_path(system_hook)
- expect(page).to have_content('Recent Deliveries')
- expect(page).to have_content(hook_log.url)
+ expect(page).to have_content('Recent events')
+ expect(page).to have_link('View details', href: admin_hook_hook_log_path(system_hook, hook_log))
end
it 'show hook log details' do
diff --git a/spec/features/admin/admin_builds_spec.rb b/spec/features/admin/admin_jobs_spec.rb
index 42827dd5b49..36822f89c12 100644
--- a/spec/features/admin/admin_builds_spec.rb
+++ b/spec/features/admin/admin_jobs_spec.rb
@@ -2,14 +2,14 @@
require 'spec_helper'
-RSpec.describe 'Admin Builds' do
+RSpec.describe 'Admin Jobs' do
before do
admin = create(:admin)
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
end
- describe 'GET /admin/builds' do
+ describe 'GET /admin/jobs' do
let(:pipeline) { create(:ci_pipeline) }
context 'All tab' do
@@ -22,7 +22,7 @@ RSpec.describe 'Admin Builds' do
visit admin_jobs_path
- expect(page).to have_selector('.nav-links li.active', text: 'All')
+ expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'All')
expect(page).to have_selector('.row-content-block', text: 'All jobs')
expect(page.all('.build-link').size).to eq(4)
expect(page).to have_button 'Stop all jobs'
@@ -37,7 +37,7 @@ RSpec.describe 'Admin Builds' do
it 'shows a message' do
visit admin_jobs_path
- expect(page).to have_selector('.nav-links li.active', text: 'All')
+ expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'All')
expect(page).to have_content 'No jobs to show'
expect(page).not_to have_button 'Stop all jobs'
end
@@ -54,7 +54,7 @@ RSpec.describe 'Admin Builds' do
visit admin_jobs_path(scope: :pending)
- expect(page).to have_selector('.nav-links li.active', text: 'Pending')
+ expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Pending')
expect(page.find('.build-link')).to have_content(build1.id)
expect(page.find('.build-link')).not_to have_content(build2.id)
expect(page.find('.build-link')).not_to have_content(build3.id)
@@ -69,7 +69,7 @@ RSpec.describe 'Admin Builds' do
visit admin_jobs_path(scope: :pending)
- expect(page).to have_selector('.nav-links li.active', text: 'Pending')
+ expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Pending')
expect(page).to have_content 'No jobs to show'
expect(page).not_to have_button 'Stop all jobs'
end
@@ -86,7 +86,7 @@ RSpec.describe 'Admin Builds' do
visit admin_jobs_path(scope: :running)
- expect(page).to have_selector('.nav-links li.active', text: 'Running')
+ expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Running')
expect(page.find('.build-link')).to have_content(build1.id)
expect(page.find('.build-link')).not_to have_content(build2.id)
expect(page.find('.build-link')).not_to have_content(build3.id)
@@ -101,7 +101,7 @@ RSpec.describe 'Admin Builds' do
visit admin_jobs_path(scope: :running)
- expect(page).to have_selector('.nav-links li.active', text: 'Running')
+ expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Running')
expect(page).to have_content 'No jobs to show'
expect(page).not_to have_button 'Stop all jobs'
end
@@ -117,7 +117,7 @@ RSpec.describe 'Admin Builds' do
visit admin_jobs_path(scope: :finished)
- expect(page).to have_selector('.nav-links li.active', text: 'Finished')
+ expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Finished')
expect(page.find('.build-link')).not_to have_content(build1.id)
expect(page.find('.build-link')).not_to have_content(build2.id)
expect(page.find('.build-link')).to have_content(build3.id)
@@ -131,7 +131,7 @@ RSpec.describe 'Admin Builds' do
visit admin_jobs_path(scope: :finished)
- expect(page).to have_selector('.nav-links li.active', text: 'Finished')
+ expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Finished')
expect(page).to have_content 'No jobs to show'
expect(page).to have_button 'Stop all jobs'
end
diff --git a/spec/features/admin/admin_mode/login_spec.rb b/spec/features/admin/admin_mode/login_spec.rb
index 5b2dfdb2941..c8ee6c14499 100644
--- a/spec/features/admin/admin_mode/login_spec.rb
+++ b/spec/features/admin/admin_mode/login_spec.rb
@@ -121,7 +121,7 @@ RSpec.describe 'Admin Mode Login' do
end
context 'when logging in via omniauth' do
- let(:user) { create(:omniauth_user, :admin, :two_factor, extern_uid: 'my-uid', provider: 'saml')}
+ let(:user) { create(:omniauth_user, :admin, :two_factor, extern_uid: 'my-uid', provider: 'saml', password_automatically_set: false)}
let(:mock_saml_response) do
File.read('spec/fixtures/authentication/saml_response.xml')
end
diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb
index 15def00f354..a50ef34d327 100644
--- a/spec/features/admin/admin_projects_spec.rb
+++ b/spec/features/admin/admin_projects_spec.rb
@@ -96,7 +96,7 @@ RSpec.describe "Admin::Projects" do
visit admin_project_path(project)
click_button 'Search for Namespace'
- click_link 'group: web'
+ click_button 'group: web'
click_button 'Transfer'
expect(page).to have_content("Web / #{project.name}")
diff --git a/spec/features/admin/admin_serverless_domains_spec.rb b/spec/features/admin/admin_serverless_domains_spec.rb
deleted file mode 100644
index 0312e82e1ba..00000000000
--- a/spec/features/admin/admin_serverless_domains_spec.rb
+++ /dev/null
@@ -1,89 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'Admin Serverless Domains', :js do
- let(:sample_domain) { build(:pages_domain) }
-
- before do
- allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
- admin = create(:admin)
- sign_in(admin)
- gitlab_enable_admin_mode_sign_in(admin)
- end
-
- it 'add domain with certificate' do
- visit admin_serverless_domains_path
-
- fill_in 'pages_domain[domain]', with: 'foo.com'
- fill_in 'pages_domain[user_provided_certificate]', with: sample_domain.certificate
- fill_in 'pages_domain[user_provided_key]', with: sample_domain.key
- click_button 'Add domain'
-
- expect(current_path).to eq admin_serverless_domains_path
-
- expect(page).to have_field('pages_domain[domain]', with: 'foo.com')
- expect(page).to have_field('serverless_domain_dns', with: /^\*\.foo\.com CNAME /)
- expect(page).to have_field('serverless_domain_verification', with: /^_gitlab-pages-verification-code.foo.com TXT /)
- expect(page).not_to have_field('pages_domain[user_provided_certificate]')
- expect(page).not_to have_field('pages_domain[user_provided_key]')
-
- expect(page).to have_content 'Unverified'
- expect(page).to have_content '/CN=test-certificate'
- end
-
- it 'update domain certificate' do
- visit admin_serverless_domains_path
-
- fill_in 'pages_domain[domain]', with: 'foo.com'
- fill_in 'pages_domain[user_provided_certificate]', with: sample_domain.certificate
- fill_in 'pages_domain[user_provided_key]', with: sample_domain.key
- click_button 'Add domain'
-
- expect(current_path).to eq admin_serverless_domains_path
-
- expect(page).not_to have_field('pages_domain[user_provided_certificate]')
- expect(page).not_to have_field('pages_domain[user_provided_key]')
-
- click_button 'Replace'
-
- expect(page).to have_field('pages_domain[user_provided_certificate]')
- expect(page).to have_field('pages_domain[user_provided_key]')
-
- fill_in 'pages_domain[user_provided_certificate]', with: sample_domain.certificate
- fill_in 'pages_domain[user_provided_key]', with: sample_domain.key
-
- click_button 'Save changes'
-
- expect(page).to have_content 'Domain was successfully updated'
- expect(page).to have_content '/CN=test-certificate'
- end
-
- context 'when domain exists' do
- let!(:domain) { create(:pages_domain, :instance_serverless) }
-
- it 'displays a modal when attempting to delete a domain' do
- visit admin_serverless_domains_path
-
- click_button 'Delete domain'
-
- page.within '#modal-delete-domain' do
- expect(page).to have_content "You are about to delete #{domain.domain} from your instance."
- expect(page).to have_link('Delete domain')
- end
- end
-
- it 'displays a modal with disabled button if unable to delete a domain' do
- create(:serverless_domain_cluster, pages_domain: domain)
-
- visit admin_serverless_domains_path
-
- click_button 'Delete domain'
-
- page.within '#modal-delete-domain' do
- expect(page).to have_content "You must disassociate #{domain.domain} from all clusters it is attached to before deletion."
- expect(page).to have_link('Delete domain')
- end
- end
- end
-end
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index b25fc9f257a..1c50a7f891f 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -314,12 +314,14 @@ RSpec.describe 'Admin updates settings' do
check 'Default to Auto DevOps pipeline for all projects'
fill_in 'application_setting_auto_devops_domain', with: 'domain.com'
uncheck 'Keep the latest artifacts for all jobs in the latest successful pipelines'
+ uncheck 'Enable pipeline suggestion banner'
click_button 'Save changes'
end
expect(current_settings.auto_devops_enabled?).to be true
expect(current_settings.auto_devops_domain).to eq('domain.com')
expect(current_settings.keep_latest_artifact).to be false
+ expect(current_settings.suggest_pipeline_enabled).to be false
expect(page).to have_content "Application settings saved successfully"
end
@@ -450,14 +452,14 @@ RSpec.describe 'Admin updates settings' do
visit reporting_admin_application_settings_path
page.within('.as-spam') do
- fill_in 'reCAPTCHA Site Key', with: 'key'
- fill_in 'reCAPTCHA Private Key', with: 'key'
+ fill_in 'reCAPTCHA site key', with: 'key'
+ fill_in 'reCAPTCHA private key', with: 'key'
check 'Enable reCAPTCHA'
check 'Enable reCAPTCHA for login'
- fill_in 'IPs per user', with: 15
+ fill_in 'IP addresses per user', with: 15
check 'Enable Spam Check via external API endpoint'
fill_in 'URL of the external Spam Check endpoint', with: 'grpc://www.example.com/spamcheck'
- fill_in 'Spam Check API Key', with: 'SPAM_CHECK_API_KEY'
+ fill_in 'Spam Check API key', with: 'SPAM_CHECK_API_KEY'
click_button 'Save changes'
end
@@ -602,18 +604,54 @@ RSpec.describe 'Admin updates settings' do
expect(current_settings.issues_create_limit).to eq(0)
end
- it 'changes Files API rate limits settings' do
- visit network_admin_application_settings_path
+ shared_examples 'regular throttle rate limit settings' do
+ it 'changes rate limit settings' do
+ visit network_admin_application_settings_path
- page.within('[data-testid="files-limits-settings"]') do
- check 'Enable unauthenticated API request rate limit'
- fill_in 'Max unauthenticated API requests per period per IP', with: 10
- click_button 'Save changes'
+ page.within(".#{selector}") do
+ check 'Enable unauthenticated API request rate limit'
+ fill_in 'Maximum unauthenticated API requests per rate limit period per IP', with: 12
+ fill_in 'Unauthenticated API rate limit period in seconds', with: 34
+
+ check 'Enable authenticated API request rate limit'
+ fill_in 'Maximum authenticated API requests per rate limit period per user', with: 56
+ fill_in 'Authenticated API rate limit period in seconds', with: 78
+
+ click_button 'Save changes'
+ end
+
+ expect(page).to have_content "Application settings saved successfully"
+
+ expect(current_settings).to have_attributes(
+ "throttle_unauthenticated_#{fragment}_enabled" => true,
+ "throttle_unauthenticated_#{fragment}_requests_per_period" => 12,
+ "throttle_unauthenticated_#{fragment}_period_in_seconds" => 34,
+ "throttle_authenticated_#{fragment}_enabled" => true,
+ "throttle_authenticated_#{fragment}_requests_per_period" => 56,
+ "throttle_authenticated_#{fragment}_period_in_seconds" => 78
+ )
end
+ end
- expect(page).to have_content "Application settings saved successfully"
- expect(current_settings.throttle_unauthenticated_files_api_enabled).to be true
- expect(current_settings.throttle_unauthenticated_files_api_requests_per_period).to eq(10)
+ context 'Package Registry API rate limits' do
+ let(:selector) { 'as-packages-limits' }
+ let(:fragment) { :packages_api }
+
+ include_examples 'regular throttle rate limit settings'
+ end
+
+ context 'Files API rate limits' do
+ let(:selector) { 'as-files-limits' }
+ let(:fragment) { :files_api }
+
+ include_examples 'regular throttle rate limit settings'
+ end
+
+ context 'Deprecated API rate limits' do
+ let(:selector) { 'as-deprecated-limits' }
+ let(:fragment) { :deprecated_api }
+
+ include_examples 'regular throttle rate limit settings'
end
end
@@ -623,8 +661,6 @@ RSpec.describe 'Admin updates settings' do
end
it 'change Help page' do
- stub_feature_flags(help_page_documentation_redirect: true)
-
new_support_url = 'http://example.com/help'
new_documentation_url = 'https://docs.gitlab.com'
diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb
index e055e8092d4..f88d31bda88 100644
--- a/spec/features/boards/new_issue_spec.rb
+++ b/spec/features/boards/new_issue_spec.rb
@@ -56,7 +56,7 @@ RSpec.describe 'Issue Boards new issue', :js do
end
end
- it 'creates new issue' do
+ it 'creates new issue and opens sidebar' do
page.within(first('.board')) do
click_button 'New issue'
end
@@ -68,7 +68,7 @@ RSpec.describe 'Issue Boards new issue', :js do
wait_for_requests
- page.within(first('.board .issue-count-badge-count')) do
+ page.within(first('.board [data-testid="issue-count-badge"]')) do
expect(page).to have_content('1')
end
@@ -78,20 +78,6 @@ RSpec.describe 'Issue Boards new issue', :js do
expect(page).to have_content(issue.to_reference)
expect(page).to have_link(issue.title, href: /#{issue_path(issue)}/)
end
- end
-
- # TODO https://gitlab.com/gitlab-org/gitlab/-/issues/323446
- xit 'shows sidebar when creating new issue' do
- page.within(first('.board')) do
- click_button 'New issue'
- end
-
- page.within(first('.board-new-issue-form')) do
- find('.form-control').set('bug')
- click_button 'Create issue'
- end
-
- wait_for_requests
expect(page).to have_selector('[data-testid="issue-boards-sidebar"]')
end
@@ -108,10 +94,6 @@ RSpec.describe 'Issue Boards new issue', :js do
wait_for_requests
- page.within(first('.board')) do
- find('.board-card').click
- end
-
page.within('[data-testid="sidebar-labels"]') do
click_button 'Edit'
diff --git a/spec/features/boards/reload_boards_on_browser_back_spec.rb b/spec/features/boards/reload_boards_on_browser_back_spec.rb
index 36682036d48..6a09e3c9506 100644
--- a/spec/features/boards/reload_boards_on_browser_back_spec.rb
+++ b/spec/features/boards/reload_boards_on_browser_back_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe 'Ensure Boards do not show stale data on browser back', :js do
visit project_board_path(project, board)
wait_for_requests
- page.within(first('.board .issue-count-badge-count')) do
+ page.within(first('.board [data-testid="issue-count-badge"]')) do
expect(page).to have_content('0')
end
end
@@ -35,7 +35,7 @@ RSpec.describe 'Ensure Boards do not show stale data on browser back', :js do
page.go_back
wait_for_requests
- page.within(first('.board .issue-count-badge-count')) do
+ page.within(first('.board [data-testid="issue-count-badge"]')) do
expect(page).to have_content('1')
end
diff --git a/spec/features/boards/sidebar_labels_spec.rb b/spec/features/boards/sidebar_labels_spec.rb
index fa16f47f69a..511233b50c0 100644
--- a/spec/features/boards/sidebar_labels_spec.rb
+++ b/spec/features/boards/sidebar_labels_spec.rb
@@ -29,12 +29,11 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
end
context 'labels' do
- # https://gitlab.com/gitlab-org/gitlab/-/issues/322725
- xit 'shows current labels when editing' do
+ it 'shows current labels when editing' do
click_card(card)
page.within('.labels') do
- click_link 'Edit'
+ click_button 'Edit'
wait_for_requests
@@ -54,9 +53,9 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
wait_for_requests
- click_link bug.title
+ click_on bug.title
- find('[data-testid="close-icon"]').click
+ click_button 'Close'
wait_for_requests
@@ -79,11 +78,11 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
wait_for_requests
- click_link bug.title
+ click_on bug.title
- click_link regression.title
+ click_on regression.title
- find('[data-testid="close-icon"]').click
+ click_button 'Close'
wait_for_requests
@@ -108,9 +107,9 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
wait_for_requests
- click_link stretch.title
+ click_button stretch.title
- find('[data-testid="close-icon"]').click
+ click_button 'Close'
wait_for_requests
@@ -125,43 +124,22 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
expect(card).not_to have_content(stretch.title)
end
- # https://gitlab.com/gitlab-org/gitlab/-/issues/324290
- xit 'creates project label' do
+ it 'creates project label' do
click_card(card)
page.within('.labels') do
- click_link 'Edit'
+ click_button 'Edit'
wait_for_requests
- click_link 'Create project label'
- fill_in 'new_label_name', with: 'test label'
+ click_on 'Create project label'
+ fill_in 'Name new label', with: 'test label'
first('.suggest-colors-dropdown a').click
click_button 'Create'
wait_for_requests
- expect(page).to have_link 'test label'
+ expect(page).to have_button 'test label'
end
expect(page).to have_selector('.board', count: 3)
end
-
- # https://gitlab.com/gitlab-org/gitlab/-/issues/324290
- xit 'creates project label and list' do
- click_card(card)
-
- page.within('.labels') do
- click_link 'Edit'
- wait_for_requests
-
- click_link 'Create project label'
- fill_in 'new_label_name', with: 'test label'
- first('.suggest-colors-dropdown a').click
- first('.js-add-list').click
- click_button 'Create'
- wait_for_requests
-
- expect(page).to have_link 'test label'
- end
- expect(page).to have_selector('.board', count: 4)
- end
end
end
diff --git a/spec/features/clusters/cluster_detail_page_spec.rb b/spec/features/clusters/cluster_detail_page_spec.rb
index cba8aaef1ef..06e3e00db7d 100644
--- a/spec/features/clusters/cluster_detail_page_spec.rb
+++ b/spec/features/clusters/cluster_detail_page_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe 'Clusterable > Show page' do
it 'does not show the environments tab' do
visit cluster_path
- expect(page).not_to have_selector('.js-cluster-nav-environments', text: 'Environments')
+ expect(page).not_to have_selector('[data-testid="cluster-environments-tab"]')
end
end
diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb
index bec474f6cfe..34a55118cb3 100644
--- a/spec/features/cycle_analytics_spec.rb
+++ b/spec/features/cycle_analytics_spec.rb
@@ -7,10 +7,13 @@ RSpec.describe 'Value Stream Analytics', :js do
let_it_be(:guest) { create(:user) }
let_it_be(:stage_table_selector) { '[data-testid="vsa-stage-table"]' }
let_it_be(:stage_table_event_selector) { '[data-testid="vsa-stage-event"]' }
+ let_it_be(:stage_table_event_title_selector) { '[data-testid="vsa-stage-event-title"]' }
+ let_it_be(:stage_table_pagination_selector) { '[data-testid="vsa-stage-pagination"]' }
+ let_it_be(:stage_table_duration_column_header_selector) { '[data-testid="vsa-stage-header-duration"]' }
let_it_be(:metrics_selector) { "[data-testid='vsa-time-metrics']" }
let_it_be(:metric_value_selector) { "[data-testid='displayValue']" }
- let(:stage_table) { page.find(stage_table_selector) }
+ let(:stage_table) { find(stage_table_selector) }
let(:project) { create(:project, :repository) }
let(:issue) { create(:issue, project: project, created_at: 2.days.ago) }
let(:milestone) { create(:milestone, project: project) }
@@ -53,6 +56,7 @@ RSpec.describe 'Value Stream Analytics', :js do
# So setting the date range to be the last 2 days should skip past the existing data
from = 2.days.ago.strftime("%Y-%m-%d")
to = 1.day.ago.strftime("%Y-%m-%d")
+ max_items_per_page = 20
around do |example|
travel_to(5.days.ago) { example.run }
@@ -60,9 +64,8 @@ RSpec.describe 'Value Stream Analytics', :js do
before do
project.add_maintainer(user)
- create_list(:issue, 2, project: project, created_at: 2.weeks.ago, milestone: milestone)
-
create_cycle(user, project, issue, mr, milestone, pipeline)
+ create_list(:issue, max_items_per_page, project: project, created_at: 2.weeks.ago, milestone: milestone)
deploy_master(user, project)
issue.metrics.update!(first_mentioned_in_commit_at: issue.metrics.first_associated_with_milestone_at + 1.hour)
@@ -81,6 +84,8 @@ RSpec.describe 'Value Stream Analytics', :js do
wait_for_requests
end
+ let(:stage_table_events) { stage_table.all(stage_table_event_selector) }
+
it 'displays metrics' do
metrics_tiles = page.find(metrics_selector)
@@ -112,20 +117,62 @@ RSpec.describe 'Value Stream Analytics', :js do
end
it 'can filter the issues by date' do
- expect(stage_table.all(stage_table_event_selector).length).to eq(3)
+ expect(page).to have_selector(stage_table_event_selector)
set_daterange(from, to)
- expect(stage_table.all(stage_table_event_selector).length).to eq(0)
+ expect(page).not_to have_selector(stage_table_event_selector)
+ expect(page).not_to have_selector(stage_table_pagination_selector)
end
it 'can filter the metrics by date' do
- expect(metrics_values).to eq(["3.0", "2.0", "1.0", "0.0"])
+ expect(metrics_values).to match_array(["21.0", "2.0", "1.0", "0.0"])
set_daterange(from, to)
expect(metrics_values).to eq(['-'] * 4)
end
+
+ it 'can sort records' do
+ # NOTE: checking that the string changes should suffice
+ # depending on the order the tests are run we might run into problems with hard coded strings
+ original_first_title = first_stage_title
+ stage_time_column.click
+
+ expect_to_be_sorted "descending"
+ expect(first_stage_title).not_to have_text(original_first_title, exact: true)
+
+ stage_time_column.click
+
+ expect_to_be_sorted "ascending"
+ expect(first_stage_title).to have_text(original_first_title, exact: true)
+ end
+
+ it 'paginates the results' do
+ original_first_title = first_stage_title
+
+ expect(page).to have_selector(stage_table_pagination_selector)
+
+ go_to_next_page
+
+ expect(page).not_to have_text(original_first_title, exact: true)
+ end
+
+ def stage_time_column
+ stage_table.find(stage_table_duration_column_header_selector).ancestor("th")
+ end
+
+ def first_stage_title
+ stage_table.all(stage_table_event_title_selector).first.text
+ end
+
+ def expect_to_be_sorted(direction)
+ expect(stage_time_column['aria-sort']).to eq(direction)
+ end
+
+ def go_to_next_page
+ page.find(stage_table_pagination_selector).find_link("Next").click
+ end
end
end
diff --git a/spec/features/dashboard/activity_spec.rb b/spec/features/dashboard/activity_spec.rb
index e75e661b513..7390edc3c47 100644
--- a/spec/features/dashboard/activity_spec.rb
+++ b/spec/features/dashboard/activity_spec.rb
@@ -13,19 +13,19 @@ RSpec.describe 'Dashboard > Activity' do
it 'shows Your Projects' do
visit activity_dashboard_path
- expect(find('.top-area .nav-tabs li.active')).to have_content('Your projects')
+ expect(find('[data-testid="dashboard-activity-tabs"] a.active')).to have_content('Your projects')
end
it 'shows Starred Projects' do
visit activity_dashboard_path(filter: 'starred')
- expect(find('.top-area .nav-tabs li.active')).to have_content('Starred projects')
+ expect(find('[data-testid="dashboard-activity-tabs"] a.active')).to have_content('Starred projects')
end
it 'shows Followed Projects' do
visit activity_dashboard_path(filter: 'followed')
- expect(find('.top-area .nav-tabs li.active')).to have_content('Followed users')
+ expect(find('[data-testid="dashboard-activity-tabs"] a.active')).to have_content('Followed users')
end
end
diff --git a/spec/features/dashboard/issuables_counter_spec.rb b/spec/features/dashboard/issuables_counter_spec.rb
index d4c6b6faa79..8e938fef155 100644
--- a/spec/features/dashboard/issuables_counter_spec.rb
+++ b/spec/features/dashboard/issuables_counter_spec.rb
@@ -55,7 +55,7 @@ RSpec.describe 'Navigation bar counter', :use_clean_rails_memory_store_caching d
end
def expect_counters(issuable_type, count)
- dashboard_count = find('.nav-links li.active')
+ dashboard_count = find('.gl-tabs-nav li a.active')
nav_count = find(".dashboard-shortcuts-#{issuable_type}")
header_count = find(".header-content .#{issuable_type.tr('_', '-')}-count")
diff --git a/spec/features/groups/board_spec.rb b/spec/features/groups/board_spec.rb
index afe36dabcb5..aece6d790b5 100644
--- a/spec/features/groups/board_spec.rb
+++ b/spec/features/groups/board_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe 'Group Boards' do
it 'adds an issue to the backlog' do
page.within(find('.board', match: :first)) do
issue_title = 'New Issue'
- find(:css, '.issue-count-badge-add-button').click
+ click_button 'New issue'
wait_for_requests
diff --git a/spec/features/groups/container_registry_spec.rb b/spec/features/groups/container_registry_spec.rb
index 65374263f45..098559dc3f8 100644
--- a/spec/features/groups/container_registry_spec.rb
+++ b/spec/features/groups/container_registry_spec.rb
@@ -16,6 +16,7 @@ RSpec.describe 'Container Registry', :js do
sign_in(user)
stub_container_registry_config(enabled: true)
stub_container_registry_tags(repository: :any, tags: [])
+ stub_container_registry_info
end
it 'has a page title set' do
@@ -57,6 +58,16 @@ RSpec.describe 'Container Registry', :js do
expect(page).to have_content 'latest'
end
+ [ContainerRegistry::Path::InvalidRegistryPathError, Faraday::Error].each do |error_class|
+ context "when there is a #{error_class}" do
+ before do
+ expect(::ContainerRegistry::Client).to receive(:registry_info).and_raise(error_class, nil, nil)
+ end
+
+ it_behaves_like 'handling feature network errors with the container registry'
+ end
+ end
+
describe 'image repo details' do
before do
visit_container_registry_details 'my/image'
@@ -81,6 +92,7 @@ RSpec.describe 'Container Registry', :js do
expect(service).to receive(:execute).with(container_repository) { { status: :success } }
expect(Projects::ContainerRepository::DeleteTagsService).to receive(:new).with(container_repository.project, user, tags: ['latest']) { service }
+ first('[data-testid="additional-actions"]').click
first('[data-testid="single-delete-button"]').click
expect(find('.modal .modal-title')).to have_content _('Remove tag')
find('.modal .modal-footer .btn-danger').click
diff --git a/spec/features/groups/dependency_proxy_for_containers_spec.rb b/spec/features/groups/dependency_proxy_for_containers_spec.rb
new file mode 100644
index 00000000000..a4cd6d0f503
--- /dev/null
+++ b/spec/features/groups/dependency_proxy_for_containers_spec.rb
@@ -0,0 +1,108 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Group Dependency Proxy for containers', :js do
+ include DependencyProxyHelpers
+
+ include_context 'file upload requests helpers'
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:sha) { 'a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4' }
+ let_it_be(:content) { fixture_file_upload("spec/fixtures/dependency_proxy/#{sha}.gz").read }
+
+ let(:image) { 'alpine' }
+ let(:url) { capybara_url("/v2/#{group.full_path}/dependency_proxy/containers/#{image}/blobs/sha256:#{sha}") }
+ let(:token) { 'token' }
+ let(:headers) { { 'Authorization' => "Bearer #{build_jwt(user).encoded}" } }
+
+ subject do
+ HTTParty.get(url, headers: headers)
+ end
+
+ def run_server(handler)
+ default_server = Capybara.server
+
+ Capybara.server = Capybara.servers[:puma]
+ server = Capybara::Server.new(handler)
+ server.boot
+ server
+ ensure
+ Capybara.server = default_server
+ end
+
+ let_it_be(:external_server) do
+ handler = lambda do |env|
+ if env['REQUEST_PATH'] == '/token'
+ [200, {}, [{ token: 'token' }.to_json]]
+ else
+ [200, {}, [content]]
+ end
+ end
+
+ run_server(handler)
+ end
+
+ before do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: true)
+ stub_config(dependency_proxy: { enabled: true })
+ group.add_developer(user)
+
+ stub_const("DependencyProxy::Registry::AUTH_URL", external_server.base_url)
+ stub_const("DependencyProxy::Registry::LIBRARY_URL", external_server.base_url)
+ end
+
+ shared_examples 'responds with the file' do
+ it 'sends file' do
+ expect(subject.code).to eq(200)
+ expect(subject.body).to eq(content)
+ expect(subject.headers.to_h).to include(
+ "content-type" => ["application/gzip"],
+ "content-disposition" => ["attachment; filename=\"#{sha}.gz\"; filename*=UTF-8''#{sha}.gz"],
+ "content-length" => ["32"]
+ )
+ end
+ end
+
+ shared_examples 'caches the file' do
+ it 'caches the file' do
+ expect { subject }.to change {
+ group.dependency_proxy_blobs.count
+ }.from(0).to(1)
+
+ expect(subject.code).to eq(200)
+ expect(group.dependency_proxy_blobs.first.file.read).to eq(content)
+ end
+ end
+
+ context 'fetching a blob' do
+ context 'when the blob is cached for the group' do
+ let!(:dependency_proxy_blob) { create(:dependency_proxy_blob, group: group) }
+
+ it_behaves_like 'responds with the file'
+
+ context 'dependency_proxy_workhorse feature flag disabled' do
+ before do
+ stub_feature_flags({ dependency_proxy_workhorse: false })
+ end
+
+ it_behaves_like 'responds with the file'
+ end
+ end
+ end
+
+ context 'when the blob must be downloaded' do
+ it_behaves_like 'responds with the file'
+ it_behaves_like 'caches the file'
+
+ context 'dependency_proxy_workhorse feature flag disabled' do
+ before do
+ stub_feature_flags({ dependency_proxy_workhorse: false })
+ end
+
+ it_behaves_like 'responds with the file'
+ it_behaves_like 'caches the file'
+ end
+ end
+end
diff --git a/spec/features/groups/dependency_proxy_spec.rb b/spec/features/groups/dependency_proxy_spec.rb
index 51371ddc532..d6b0bdc8ea4 100644
--- a/spec/features/groups/dependency_proxy_spec.rb
+++ b/spec/features/groups/dependency_proxy_spec.rb
@@ -3,13 +3,14 @@
require 'spec_helper'
RSpec.describe 'Group Dependency Proxy' do
- let(:developer) { create(:user) }
+ let(:owner) { create(:user) }
let(:reporter) { create(:user) }
let(:group) { create(:group) }
let(:path) { group_dependency_proxy_path(group) }
+ let(:settings_path) { group_settings_packages_and_registries_path(group) }
before do
- group.add_developer(developer)
+ group.add_owner(owner)
group.add_reporter(reporter)
enable_feature
@@ -22,42 +23,46 @@ RSpec.describe 'Group Dependency Proxy' do
visit path
- expect(page).not_to have_css('.js-dependency-proxy-toggle-area')
- expect(page).not_to have_css('.js-dependency-proxy-url')
+ expect(page).not_to have_css('[data-testid="proxy-url"]')
end
end
context 'feature is available', :js do
- context 'when logged in as group developer' do
+ context 'when logged in as group owner' do
before do
- sign_in(developer)
- visit path
+ sign_in(owner)
end
it 'sidebar menu is open' do
+ visit path
+
sidebar = find('.nav-sidebar')
expect(sidebar).to have_link _('Dependency Proxy')
end
it 'toggles defaults to enabled' do
- page.within('.js-dependency-proxy-toggle-area') do
- expect(find('.js-project-feature-toggle-input', visible: false).value).to eq('true')
- end
+ visit path
+
+ expect(page).to have_css('[data-testid="proxy-url"]')
end
it 'shows the proxy URL' do
- page.within('.edit_dependency_proxy_group_setting') do
- expect(find('.js-dependency-proxy-url').value).to have_content('/dependency_proxy/containers')
- end
+ visit path
+
+ expect(find('input[data-testid="proxy-url"]').value).to have_content('/dependency_proxy/containers')
end
it 'hides the proxy URL when feature is disabled' do
- page.within('.edit_dependency_proxy_group_setting') do
- find('.js-project-feature-toggle').click
- end
+ visit settings_path
+ wait_for_requests
+
+ click_button 'Enable Proxy'
+
+ expect(page).to have_button 'Enable Proxy', class: '!is-checked'
+
+ visit path
- expect(page).not_to have_css('.js-dependency-proxy-url')
- expect(find('.js-project-feature-toggle-input', visible: false).value).to eq('false')
+ expect(page).not_to have_css('input[data-testid="proxy-url"]')
end
end
@@ -68,18 +73,17 @@ RSpec.describe 'Group Dependency Proxy' do
end
it 'does not show the feature toggle but shows the proxy URL' do
- expect(page).not_to have_css('.js-dependency-proxy-toggle-area')
- expect(find('.js-dependency-proxy-url').value).to have_content('/dependency_proxy/containers')
+ expect(find('input[data-testid="proxy-url"]').value).to have_content('/dependency_proxy/containers')
end
end
end
context 'feature is not avaible' do
before do
- sign_in(developer)
+ sign_in(owner)
end
- context 'feature flag is disabled' do
+ context 'feature flag is disabled', :js do
before do
stub_feature_flags(dependency_proxy_for_private_groups: false)
end
@@ -90,7 +94,7 @@ RSpec.describe 'Group Dependency Proxy' do
it 'informs user that feature is only available for public groups' do
visit path
- expect(page).to have_content('Dependency proxy feature is limited to public groups for now.')
+ expect(page).to have_content('Dependency Proxy feature is limited to public groups for now.')
end
end
end
diff --git a/spec/features/groups/import_export/connect_instance_spec.rb b/spec/features/groups/import_export/connect_instance_spec.rb
index cf893e444c4..552b599a3f3 100644
--- a/spec/features/groups/import_export/connect_instance_spec.rb
+++ b/spec/features/groups/import_export/connect_instance_spec.rb
@@ -19,34 +19,12 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do
end
context 'when the user provides valid credentials' do
+ source_url = 'https://gitlab.com'
+
+ include_context 'bulk imports requests context', source_url
+
it 'successfully connects to remote instance' do
- source_url = 'https://gitlab.com'
pat = 'demo-pat'
- stub_path = 'stub-group'
- total = 37
-
- stub_request(:get, "%{url}/api/v4/groups?page=1&per_page=20&top_level_only=true&min_access_level=50&search=" % { url: source_url }).to_return(
- body: [{
- id: 2595438,
- web_url: 'https://gitlab.com/groups/auto-breakfast',
- name: 'Stub',
- path: stub_path,
- full_name: 'Stub',
- full_path: stub_path
- }].to_json,
- headers: {
- 'Content-Type' => 'application/json',
- 'X-Next-Page' => 2,
- 'X-Page' => 1,
- 'X-Per-Page' => 20,
- 'X-Total' => total,
- 'X-Total-Pages' => 2
- }
- )
-
- allow_next_instance_of(BulkImports::Clients::HTTP) do |client|
- allow(client).to receive(:validate_instance_version!).and_return(true)
- end
expect(page).to have_content 'Import groups from another instance of GitLab'
expect(page).to have_content 'Not all related objects are migrated'
@@ -56,8 +34,8 @@ RSpec.describe 'Import/Export - Connect to another instance', :js do
click_on 'Connect instance'
- expect(page).to have_content 'Showing 1-1 of %{total} groups from %{url}' % { url: source_url, total: total }
- expect(page).to have_content stub_path
+ expect(page).to have_content 'Showing 1-1 of 42 groups from %{url}' % { url: source_url }
+ expect(page).to have_content 'stub-group'
visit '/'
diff --git a/spec/features/groups/import_export/migration_history_spec.rb b/spec/features/groups/import_export/migration_history_spec.rb
new file mode 100644
index 00000000000..243bdcc13a9
--- /dev/null
+++ b/spec/features/groups/import_export/migration_history_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Import/Export - GitLab migration history', :js do
+ let_it_be(:user) { create(:user) }
+
+ let_it_be(:user_import_1) { create(:bulk_import, user: user) }
+ let_it_be(:finished_entity_1) { create(:bulk_import_entity, :finished, bulk_import: user_import_1) }
+
+ let_it_be(:user_import_2) { create(:bulk_import, user: user) }
+ let_it_be(:failed_entity_2) { create(:bulk_import_entity, :failed, bulk_import: user_import_2) }
+
+ before do
+ gitlab_sign_in(user)
+
+ visit new_group_path
+
+ click_link 'Import group'
+ end
+
+ it 'successfully displays import history' do
+ click_link 'History'
+
+ wait_for_requests
+
+ expect(page).to have_content 'Group import history'
+ expect(page.find('tbody')).to have_css('tr', count: 2)
+ end
+end
diff --git a/spec/features/groups/members/manage_groups_spec.rb b/spec/features/groups/members/manage_groups_spec.rb
index 2dfcd941b4f..d822a5ea871 100644
--- a/spec/features/groups/members/manage_groups_spec.rb
+++ b/spec/features/groups/members/manage_groups_spec.rb
@@ -63,6 +63,7 @@ RSpec.describe 'Groups > Members > Manage groups', :js do
context 'when group link exists' do
let_it_be(:shared_with_group) { create(:group) }
let_it_be(:shared_group) { create(:group) }
+ let_it_be(:expiration_date) { 5.days.from_now.to_date }
let(:additional_link_attrs) { {} }
@@ -115,29 +116,29 @@ RSpec.describe 'Groups > Members > Manage groups', :js do
click_groups_tab
page.within first_row do
- fill_in 'Expiration date', with: 5.days.from_now.to_date
+ fill_in 'Expiration date', with: expiration_date
find_field('Expiration date').native.send_keys :enter
wait_for_requests
- expect(page).to have_content(/in \d days/)
+ expect(page).to have_field('Expiration date', with: expiration_date)
end
end
context 'when expiry date is set' do
- let(:additional_link_attrs) { { expires_at: 5.days.from_now.to_date } }
+ let(:additional_link_attrs) { { expires_at: expiration_date } }
it 'clears expiry date' do
click_groups_tab
page.within first_row do
- expect(page).to have_content(/in \d days/)
+ expect(page).to have_field('Expiration date', with: expiration_date)
find('[data-testid="clear-button"]').click
wait_for_requests
- expect(page).to have_content('No expiration set')
+ expect(page).to have_field('Expiration date', with: '')
end
end
end
diff --git a/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb
index ddf3c6d8f9b..86185b8dd32 100644
--- a/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb
+++ b/spec/features/groups/members/master_adds_member_with_expiration_date_spec.rb
@@ -8,6 +8,7 @@ RSpec.describe 'Groups > Members > Owner adds member with expiration date', :js
let_it_be(:user1) { create(:user, name: 'John Doe') }
let_it_be(:group) { create(:group) }
+ let_it_be(:expiration_date) { 5.days.from_now.to_date }
let(:new_member) { create(:user, name: 'Mary Jane') }
@@ -19,10 +20,10 @@ RSpec.describe 'Groups > Members > Owner adds member with expiration date', :js
it 'expiration date is displayed in the members list' do
visit group_group_members_path(group)
- invite_member(new_member.name, role: 'Guest', expires_at: 5.days.from_now.to_date)
+ invite_member(new_member.name, role: 'Guest', expires_at: expiration_date)
page.within second_row do
- expect(page).to have_content(/in \d days/)
+ expect(page).to have_field('Expiration date', with: expiration_date)
end
end
@@ -31,27 +32,27 @@ RSpec.describe 'Groups > Members > Owner adds member with expiration date', :js
visit group_group_members_path(group)
page.within second_row do
- fill_in 'Expiration date', with: 5.days.from_now.to_date
+ fill_in 'Expiration date', with: expiration_date
find_field('Expiration date').native.send_keys :enter
wait_for_requests
- expect(page).to have_content(/in \d days/)
+ expect(page).to have_field('Expiration date', with: expiration_date)
end
end
it 'clears expiration date' do
- create(:group_member, :developer, user: new_member, group: group, expires_at: 5.days.from_now.to_date)
+ create(:group_member, :developer, user: new_member, group: group, expires_at: expiration_date)
visit group_group_members_path(group)
page.within second_row do
- expect(page).to have_content(/in \d days/)
+ expect(page).to have_field('Expiration date', with: expiration_date)
find('[data-testid="clear-button"]').click
wait_for_requests
- expect(page).to have_content('No expiration set')
+ expect(page).to have_field('Expiration date', with: '')
end
end
end
diff --git a/spec/features/groups/milestone_spec.rb b/spec/features/groups/milestone_spec.rb
index c51ee250331..4edf27e8fa4 100644
--- a/spec/features/groups/milestone_spec.rb
+++ b/spec/features/groups/milestone_spec.rb
@@ -98,9 +98,11 @@ RSpec.describe 'Group milestones' do
end
it 'counts milestones correctly' do
- expect(find('.top-area .active .badge').text).to eq("3")
- expect(find('.top-area .closed .badge').text).to eq("3")
- expect(find('.top-area .all .badge').text).to eq("6")
+ page.within '[data-testid="milestones-filter"]' do
+ expect(page).to have_content('Open 3')
+ expect(page).to have_content('Closed 3')
+ expect(page).to have_content('All 6')
+ end
end
it 'lists group and project milestones' do
diff --git a/spec/features/groups/packages_spec.rb b/spec/features/groups/packages_spec.rb
index 3c2ade6b274..0dfc7180187 100644
--- a/spec/features/groups/packages_spec.rb
+++ b/spec/features/groups/packages_spec.rb
@@ -28,6 +28,10 @@ RSpec.describe 'Group Packages' do
context 'when feature is available', :js do
before do
+ # we are simply setting the featrure flag to false because the new UI has nothing to test yet
+ # when the refactor is complete or almost complete we will turn on the feature tests
+ # see https://gitlab.com/gitlab-org/gitlab/-/issues/330846 for status of this work
+ stub_feature_flags(package_list_apollo: false)
visit_group_packages
end
diff --git a/spec/features/issues/related_issues_spec.rb b/spec/features/issues/related_issues_spec.rb
index 837859bbe26..a95229d4f1b 100644
--- a/spec/features/issues/related_issues_spec.rb
+++ b/spec/features/issues/related_issues_spec.rb
@@ -41,13 +41,13 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
- expect(page).not_to have_selector('.js-issue-count-badge-add-button')
+ expect(page).not_to have_button 'Add a related issue'
end
end
context 'when logged in but not a member' do
before do
- gitlab_sign_in(user)
+ sign_in(user)
end
it 'shows widget when internal project' do
@@ -57,7 +57,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
- expect(page).not_to have_selector('.js-issue-count-badge-add-button')
+ expect(page).not_to have_button 'Add a related issue'
end
it 'does not show widget when private project' do
@@ -76,7 +76,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
- expect(page).not_to have_selector('.js-issue-count-badge-add-button')
+ expect(page).not_to have_button 'Add a related issue'
end
it 'shows widget on their own public issue' do
@@ -86,13 +86,13 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
- expect(page).not_to have_selector('.js-issue-count-badge-add-button')
+ expect(page).not_to have_button 'Add a related issue'
end
end
context 'when logged in and a guest' do
before do
- gitlab_sign_in(user)
+ sign_in(user)
end
it 'shows widget when internal project' do
@@ -103,7 +103,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
- expect(page).not_to have_selector('.js-issue-count-badge-add-button')
+ expect(page).not_to have_button 'Add a related issue'
end
it 'shows widget when private project' do
@@ -114,7 +114,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
- expect(page).not_to have_selector('.js-issue-count-badge-add-button')
+ expect(page).not_to have_button 'Add a related issue'
end
it 'shows widget when public project' do
@@ -125,13 +125,13 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
- expect(page).not_to have_selector('.js-issue-count-badge-add-button')
+ expect(page).not_to have_button 'Add a related issue'
end
end
context 'when logged in and a reporter' do
before do
- gitlab_sign_in(user)
+ sign_in(user)
end
it 'shows widget when internal project' do
@@ -142,7 +142,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
- expect(page).to have_selector('.js-issue-count-badge-add-button')
+ expect(page).to have_button 'Add a related issue'
end
it 'shows widget when private project' do
@@ -153,7 +153,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
- expect(page).to have_selector('.js-issue-count-badge-add-button')
+ expect(page).to have_button 'Add a related issue'
end
it 'shows widget when public project' do
@@ -164,7 +164,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
- expect(page).to have_selector('.js-issue-count-badge-add-button')
+ expect(page).to have_button 'Add a related issue'
end
it 'shows widget on their own public issue' do
@@ -175,7 +175,7 @@ RSpec.describe 'Related issues', :js do
visit project_issue_path(project, issue)
expect(page).to have_css('.related-issues-block')
- expect(page).to have_selector('.js-issue-count-badge-add-button')
+ expect(page).to have_button 'Add a related issue'
end
end
end
@@ -186,7 +186,7 @@ RSpec.describe 'Related issues', :js do
before do
project.add_guest(user)
- gitlab_sign_in(user)
+ sign_in(user)
end
context 'visiting some issue someone else created' do
@@ -216,7 +216,7 @@ RSpec.describe 'Related issues', :js do
before do
project.add_maintainer(user)
project_b.add_maintainer(user)
- gitlab_sign_in(user)
+ sign_in(user)
end
context 'without existing related issues' do
@@ -230,9 +230,9 @@ RSpec.describe 'Related issues', :js do
end
it 'add related issue' do
- find('.js-issue-count-badge-add-button').click
- find('.js-add-issuable-form-input').set "#{issue_b.to_reference(project)} "
- find('.js-add-issuable-form-add-button').click
+ click_button 'Add a related issue'
+ fill_in 'Paste issue link', with: "#{issue_b.to_reference(project)} "
+ click_button 'Add'
wait_for_requests
@@ -247,9 +247,9 @@ RSpec.describe 'Related issues', :js do
end
it 'add cross-project related issue' do
- find('.js-issue-count-badge-add-button').click
- find('.js-add-issuable-form-input').set "#{issue_project_b_a.to_reference(project)} "
- find('.js-add-issuable-form-add-button').click
+ click_button 'Add a related issue'
+ fill_in 'Paste issue link', with: "#{issue_project_b_a.to_reference(project)} "
+ click_button 'Add'
wait_for_requests
@@ -261,9 +261,9 @@ RSpec.describe 'Related issues', :js do
end
it 'pressing enter should submit the form' do
- find('.js-issue-count-badge-add-button').click
- find('.js-add-issuable-form-input').set "#{issue_project_b_a.to_reference(project)} "
- find('.js-add-issuable-form-input').native.send_key(:enter)
+ click_button 'Add a related issue'
+ fill_in 'Paste issue link', with: "#{issue_project_b_a.to_reference(project)} "
+ find_field('Paste issue link').native.send_key(:enter)
wait_for_requests
@@ -275,10 +275,10 @@ RSpec.describe 'Related issues', :js do
end
it 'disallows duplicate entries' do
- find('.js-issue-count-badge-add-button').click
- find('.js-add-issuable-form-input').set 'duplicate duplicate duplicate'
+ click_button 'Add a related issue'
+ fill_in 'Paste issue link', with: 'duplicate duplicate duplicate'
- items = all('.js-add-issuable-form-token-list-item')
+ items = all('.issue-token')
expect(items.count).to eq(1)
expect(items[0].text).to eq('duplicate')
@@ -288,29 +288,35 @@ RSpec.describe 'Related issues', :js do
it 'allows us to remove pending issues' do
# Tests against https://gitlab.com/gitlab-org/gitlab/issues/11625
- find('.js-issue-count-badge-add-button').click
- find('.js-add-issuable-form-input').set 'issue1 issue2 issue3 '
+ click_button 'Add a related issue'
+ fill_in 'Paste issue link', with: 'issue1 issue2 issue3 '
- items = all('.js-add-issuable-form-token-list-item')
+ items = all('.issue-token')
expect(items.count).to eq(3)
expect(items[0].text).to eq('issue1')
expect(items[1].text).to eq('issue2')
expect(items[2].text).to eq('issue3')
# Remove pending issues left to right to make sure none get stuck
- items[0].find('.js-issue-token-remove-button').click
- items = all('.js-add-issuable-form-token-list-item')
+ within items[0] do
+ click_button 'Remove'
+ end
+ items = all('.issue-token')
expect(items.count).to eq(2)
expect(items[0].text).to eq('issue2')
expect(items[1].text).to eq('issue3')
- items[0].find('.js-issue-token-remove-button').click
- items = all('.js-add-issuable-form-token-list-item')
+ within items[0] do
+ click_button 'Remove'
+ end
+ items = all('.issue-token')
expect(items.count).to eq(1)
expect(items[0].text).to eq('issue3')
- items[0].find('.js-issue-token-remove-button').click
- items = all('.js-add-issuable-form-token-list-item')
+ within items[0] do
+ click_button 'Remove'
+ end
+ items = all('.issue-token')
expect(items.count).to eq(0)
end
end
@@ -351,9 +357,9 @@ RSpec.describe 'Related issues', :js do
end
it 'add related issue' do
- find('.js-issue-count-badge-add-button').click
- find('.js-add-issuable-form-input').set "##{issue_d.iid} "
- find('.js-add-issuable-form-add-button').click
+ click_button 'Add a related issue'
+ fill_in 'Paste issue link', with: "##{issue_d.iid} "
+ click_button 'Add'
wait_for_requests
@@ -367,9 +373,9 @@ RSpec.describe 'Related issues', :js do
end
it 'add invalid related issue' do
- find('.js-issue-count-badge-add-button').click
- find('.js-add-issuable-form-input').set "#9999999 "
- find('.js-add-issuable-form-add-button').click
+ click_button 'Add a related issue'
+ fill_in 'Paste issue link', with: '#9999999 '
+ click_button 'Add'
wait_for_requests
@@ -382,9 +388,9 @@ RSpec.describe 'Related issues', :js do
end
it 'add unauthorized related issue' do
- find('.js-issue-count-badge-add-button').click
- find('.js-add-issuable-form-input').set "#{issue_project_unauthorized_a.to_reference(project)} "
- find('.js-add-issuable-form-add-button').click
+ click_button 'Add a related issue'
+ fill_in 'Paste issue link', with: "#{issue_project_unauthorized_a.to_reference(project)} "
+ click_button 'Add'
wait_for_requests
diff --git a/spec/features/markdown/copy_as_gfm_spec.rb b/spec/features/markdown/copy_as_gfm_spec.rb
index c700f878df6..d3aaf339421 100644
--- a/spec/features/markdown/copy_as_gfm_spec.rb
+++ b/spec/features/markdown/copy_as_gfm_spec.rb
@@ -201,6 +201,15 @@ RSpec.describe 'Copy as GFM', :js do
GFM
)
+ aggregate_failures('CustomEmojiFilter') do
+ gfm = ':custom_emoji:'
+
+ html = '<img class="emoji" src="custom_emoji.svg" title=":custom_emoji:" height="20" width="20">'
+
+ output_gfm = html_to_gfm(html)
+ expect(output_gfm.strip).to eq(gfm.strip)
+ end
+
aggregate_failures('MathFilter: math as transformed from HTML to KaTeX') do
gfm = '$`c = \pm\sqrt{a^2 + b^2}`$'
diff --git a/spec/features/markdown/markdown_spec.rb b/spec/features/markdown/markdown_spec.rb
index 3208ad82c03..9eff02a8c1b 100644
--- a/spec/features/markdown/markdown_spec.rb
+++ b/spec/features/markdown/markdown_spec.rb
@@ -133,8 +133,9 @@ RSpec.describe 'GitLab Markdown', :aggregate_failures do
expect(doc.at_css('td:contains("Baz")')['align']).to eq 'left'
end
+ # note that 2 are from the hardcoded <sup>, and 2 from footnotes
aggregate_failures 'permits superscript elements' do
- expect(doc).to have_selector('sup', count: 2)
+ expect(doc).to have_selector('sup', count: 4)
end
aggregate_failures 'permits subscript elements' do
@@ -148,6 +149,11 @@ RSpec.describe 'GitLab Markdown', :aggregate_failures do
aggregate_failures "removes `href` from `a` elements if it's fishy" do
expect(doc).not_to have_selector('a[href*="javascript"]')
end
+
+ aggregate_failures 'permits footnotes' do
+ expect(doc).to have_selector('section.footnotes ol li p:contains("Footnote 1")')
+ expect(doc).to have_selector('section.footnotes ol li p:contains("Footnote with w")')
+ end
end
describe 'Escaping' do
diff --git a/spec/features/merge_request/user_merges_immediately_spec.rb b/spec/features/merge_request/user_merges_immediately_spec.rb
index bca6e6ceba5..3a05f35a671 100644
--- a/spec/features/merge_request/user_merges_immediately_spec.rb
+++ b/spec/features/merge_request/user_merges_immediately_spec.rb
@@ -36,7 +36,7 @@ RSpec.describe 'Merge requests > User merges immediately', :js do
Sidekiq::Testing.fake! do
click_button 'Merge immediately'
- expect(find('.accept-merge-request.btn-confirm')).to have_content('Merge in progress')
+ expect(find('.media-body h4')).to have_content('Merging!')
wait_for_requests
end
diff --git a/spec/features/merge_request/user_resolves_conflicts_spec.rb b/spec/features/merge_request/user_resolves_conflicts_spec.rb
index 03ab42aaccd..982e75760d7 100644
--- a/spec/features/merge_request/user_resolves_conflicts_spec.rb
+++ b/spec/features/merge_request/user_resolves_conflicts_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'Merge request > User resolves conflicts', :js do
let(:user) { project.creator }
def create_merge_request(source_branch)
- create(:merge_request, source_branch: source_branch, target_branch: 'conflict-start', source_project: project, merge_status: :unchecked) do |mr|
+ create(:merge_request, source_branch: source_branch, target_branch: 'conflict-start', source_project: project, merge_status: :unchecked, reviewers: [user]) do |mr|
mr.mark_as_unmergeable
end
end
@@ -178,6 +178,23 @@ RSpec.describe 'Merge request > User resolves conflicts', :js do
end
end
+ context 'sidebar' do
+ let(:merge_request) { create_merge_request('conflict-resolvable') }
+
+ before do
+ project.add_developer(user)
+ sign_in(user)
+
+ visit conflicts_project_merge_request_path(project, merge_request)
+ end
+
+ it 'displays reviewers' do
+ page.within '.issuable-sidebar' do
+ expect(page).to have_selector('[data-testid="reviewer"]', count: 1)
+ end
+ end
+ end
+
unresolvable_conflicts = {
'conflict-too-large' => 'when the conflicts contain a large file',
'conflict-binary-file' => 'when the conflicts contain a binary file',
diff --git a/spec/features/merge_request/user_sees_deployment_widget_spec.rb b/spec/features/merge_request/user_sees_deployment_widget_spec.rb
index 1e547d504ef..873cc0a89c6 100644
--- a/spec/features/merge_request/user_sees_deployment_widget_spec.rb
+++ b/spec/features/merge_request/user_sees_deployment_widget_spec.rb
@@ -13,6 +13,8 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
let(:sha) { project.commit(ref).id }
let(:pipeline) { create(:ci_pipeline, sha: sha, project: project, ref: ref) }
let!(:manual) { }
+ let(:build) { create(:ci_build, :with_deployment, environment: environment.name, pipeline: pipeline) }
+ let!(:deployment) { build.deployment }
before do
merge_request.update!(merge_commit_sha: sha)
@@ -21,8 +23,9 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
end
context 'when deployment succeeded' do
- let(:build) { create(:ci_build, :success, pipeline: pipeline) }
- let!(:deployment) { create(:deployment, :succeed, environment: environment, sha: sha, ref: ref, deployable: build) }
+ before do
+ build.success!
+ end
it 'displays that the environment is deployed' do
visit project_merge_request_path(project, merge_request)
@@ -34,9 +37,8 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
context 'when a user created a new merge request with the same SHA' do
let(:pipeline2) { create(:ci_pipeline, sha: sha, project: project, ref: 'video') }
- let(:build2) { create(:ci_build, :success, pipeline: pipeline2) }
let(:environment2) { create(:environment, project: project) }
- let!(:deployment2) { create(:deployment, environment: environment2, sha: sha, ref: 'video', deployable: build2) }
+ let!(:build2) { create(:ci_build, :with_deployment, :success, environment: environment2.name, pipeline: pipeline2) }
it 'displays one environment which is related to the pipeline' do
visit project_merge_request_path(project, merge_request)
@@ -50,8 +52,9 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
end
context 'when deployment failed' do
- let(:build) { create(:ci_build, :failed, pipeline: pipeline) }
- let!(:deployment) { create(:deployment, :failed, environment: environment, sha: sha, ref: ref, deployable: build) }
+ before do
+ build.drop!
+ end
it 'displays that the deployment failed' do
visit project_merge_request_path(project, merge_request)
@@ -63,8 +66,9 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
end
context 'when deployment running' do
- let(:build) { create(:ci_build, :running, pipeline: pipeline) }
- let!(:deployment) { create(:deployment, :running, environment: environment, sha: sha, ref: ref, deployable: build) }
+ before do
+ build.run!
+ end
it 'displays that the running deployment' do
visit project_merge_request_path(project, merge_request)
@@ -76,8 +80,8 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
end
context 'when deployment will happen' do
- let(:build) { create(:ci_build, :created, pipeline: pipeline) }
- let!(:deployment) { create(:deployment, environment: environment, sha: sha, ref: ref, deployable: build) }
+ let(:build) { create(:ci_build, :with_deployment, environment: environment.name, pipeline: pipeline) }
+ let!(:deployment) { build.deployment }
it 'displays that the environment name' do
visit project_merge_request_path(project, merge_request)
@@ -89,8 +93,9 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
end
context 'when deployment was cancelled' do
- let(:build) { create(:ci_build, :canceled, pipeline: pipeline) }
- let!(:deployment) { create(:deployment, :canceled, environment: environment, sha: sha, ref: ref, deployable: build) }
+ before do
+ build.cancel!
+ end
it 'displays that the environment name' do
visit project_merge_request_path(project, merge_request)
@@ -102,11 +107,10 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
end
context 'with stop action' do
- let(:build) { create(:ci_build, :success, pipeline: pipeline) }
- let!(:deployment) { create(:deployment, :succeed, environment: environment, sha: sha, ref: ref, deployable: build) }
let(:manual) { create(:ci_build, :manual, pipeline: pipeline, name: 'close_app') }
before do
+ build.success!
deployment.update!(on_stop: manual.name)
visit project_merge_request_path(project, merge_request)
wait_for_requests
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 2f7758143a1..f74b097ab3e 100644
--- a/spec/features/merge_request/user_sees_merge_widget_spec.rb
+++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb
@@ -45,18 +45,12 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
let!(:environment) { create(:environment, project: project) }
let(:sha) { project.commit(merge_request.source_branch).sha }
let(:pipeline) { create(:ci_pipeline, status: 'success', sha: sha, project: project, ref: merge_request.source_branch) }
- let(:build) { create(:ci_build, :success, pipeline: pipeline) }
-
- let!(:deployment) do
- create(:deployment, :succeed,
- environment: environment,
- ref: merge_request.source_branch,
- deployable: build,
- sha: sha)
- end
+ let!(:build) { create(:ci_build, :with_deployment, :success, environment: environment.name, pipeline: pipeline) }
+ let!(:deployment) { build.deployment }
before do
merge_request.update!(head_pipeline: pipeline)
+ deployment.update!(status: :success)
visit project_merge_request_path(project, merge_request)
end
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 4bb6c3265a4..3893a9cdf28 100644
--- a/spec/features/merge_request/user_sees_suggest_pipeline_spec.rb
+++ b/spec/features/merge_request/user_sees_suggest_pipeline_spec.rb
@@ -6,9 +6,10 @@ RSpec.describe 'Merge request > User sees suggest pipeline', :js do
let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.source_project }
let(:user) { project.creator }
+ let(:suggest_pipeline_enabled) { true }
before do
- stub_application_setting(auto_devops_enabled: false)
+ stub_application_setting(suggest_pipeline_enabled: suggest_pipeline_enabled, auto_devops_enabled: false)
project.add_maintainer(user)
sign_in(user)
visit project_merge_request_path(project, merge_request)
@@ -66,4 +67,12 @@ RSpec.describe 'Merge request > User sees suggest pipeline', :js do
# nudge 4
expect(page).to have_content("That's it, well done!")
end
+
+ context 'when feature setting is disabled' do
+ let(:suggest_pipeline_enabled) { false }
+
+ it 'does not show the suggest pipeline widget' do
+ expect(page).not_to have_content('Are you adding technical debt or code vulnerabilities?')
+ end
+ end
end
diff --git a/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb b/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb
index 275a87ca391..d2bde320c54 100644
--- a/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb
+++ b/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb
@@ -64,7 +64,7 @@ RSpec.describe 'Merge request > User selects branches for new MR', :js do
click_button "Check out branch"
- expect(page).to have_content 'git checkout -b "orphaned-branch" "origin/orphaned-branch"'
+ expect(page).to have_content 'git checkout -b \'orphaned-branch\' \'origin/orphaned-branch\''
end
it 'allows filtering multiple dropdowns' do
diff --git a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
index dbc88d0cce2..690a292937a 100644
--- a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
+++ b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
@@ -159,7 +159,12 @@ RSpec.describe 'User comments on a diff', :js do
wait_for_requests
expect(page).to have_content('Remove from batch')
- expect(page).to have_content("Apply suggestions #{index + 1}")
+
+ if index < 1
+ expect(page).to have_content("Apply suggestion")
+ else
+ expect(page).to have_content("Apply #{index + 1} suggestions")
+ end
end
end
@@ -167,13 +172,12 @@ RSpec.describe 'User comments on a diff', :js do
click_button('Remove from batch')
wait_for_requests
- expect(page).to have_content('Apply suggestion')
expect(page).to have_content('Add suggestion to batch')
end
page.within("[id='#{files[1][:hash]}']") do
expect(page).to have_content('Remove from batch')
- expect(page).to have_content('Apply suggestions 1')
+ expect(page).to have_content('Apply suggestion')
end
end
diff --git a/spec/features/profiles/password_spec.rb b/spec/features/profiles/password_spec.rb
index 893dd2c76e0..7059697354d 100644
--- a/spec/features/profiles/password_spec.rb
+++ b/spec/features/profiles/password_spec.rb
@@ -89,7 +89,7 @@ RSpec.describe 'Profile > Password' do
shared_examples 'user enters an incorrect current password' do
subject do
page.within '.update-password' do
- fill_in 'user_current_password', with: user_current_password
+ fill_in 'user_password', with: user_current_password
fill_passwords(new_password, new_password)
end
end
@@ -131,7 +131,7 @@ RSpec.describe 'Profile > Password' do
end
context 'when current password is incorrect' do
- let(:user_current_password) {'invalid' }
+ let(:user_current_password) { 'invalid' }
it_behaves_like 'user enters an incorrect current password'
end
@@ -139,7 +139,7 @@ RSpec.describe 'Profile > Password' do
context 'when the password reset is successful' do
subject do
page.within '.update-password' do
- fill_in "user_current_password", with: user.password
+ fill_in "user_password", with: user.password
fill_passwords(new_password, new_password)
end
end
@@ -169,8 +169,8 @@ RSpec.describe 'Profile > Password' do
expect(current_path).to eq new_profile_password_path
- fill_in :user_current_password, with: user.password
- fill_in :user_password, with: '12345678'
+ fill_in :user_password, with: user.password
+ fill_in :user_new_password, with: '12345678'
fill_in :user_password_confirmation, with: '12345678'
click_button 'Set new password'
diff --git a/spec/features/profiles/two_factor_auths_spec.rb b/spec/features/profiles/two_factor_auths_spec.rb
index 7f3ce617846..3f5789e119a 100644
--- a/spec/features/profiles/two_factor_auths_spec.rb
+++ b/spec/features/profiles/two_factor_auths_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe 'Two factor auths' do
end
context 'when user authenticates with an external service' do
- let_it_be(:user) { create(:omniauth_user, password_automatically_set: true) }
+ let_it_be(:user) { create(:omniauth_user) }
it 'does not require the current password to set up two factor authentication', :js do
visit profile_two_factor_auth_path
@@ -88,7 +88,7 @@ RSpec.describe 'Two factor auths' do
end
context 'when user authenticates with an external service' do
- let_it_be(:user) { create(:omniauth_user, :two_factor, password_automatically_set: true) }
+ let_it_be(:user) { create(:omniauth_user, :two_factor) }
it 'does not require the current_password to disable two-factor authentication', :js do
visit profile_two_factor_auth_path
diff --git a/spec/features/profiles/user_edit_profile_spec.rb b/spec/features/profiles/user_edit_profile_spec.rb
index af085b63155..026da5814e3 100644
--- a/spec/features/profiles/user_edit_profile_spec.rb
+++ b/spec/features/profiles/user_edit_profile_spec.rb
@@ -19,6 +19,17 @@ RSpec.describe 'User edit profile' do
wait_for_requests if respond_to?(:wait_for_requests)
end
+ def update_user_email
+ fill_in 'user_email', with: 'new-email@example.com'
+ click_button 'Update profile settings'
+ end
+
+ def confirm_password(password)
+ fill_in 'password-confirmation', with: password
+ click_button 'Confirm password'
+ wait_for_requests if respond_to?(:wait_for_requests)
+ end
+
def visit_user
visit user_path(user)
wait_for_requests
@@ -88,16 +99,42 @@ RSpec.describe 'User edit profile' do
expect(page).to have_content('Website url is not a valid URL')
end
- describe 'when I change my email' do
+ describe 'when I change my email', :js do
before do
user.send_reset_password_instructions
end
+ it 'will prompt to confirm my password' do
+ expect(user.reset_password_token?).to be true
+
+ update_user_email
+
+ expect(page).to have_selector('[data-testid="password-prompt-modal"]')
+ end
+
+ context 'when prompted to confirm password' do
+ before do
+ update_user_email
+ end
+
+ it 'with the correct password successfully updates' do
+ confirm_password(user.password)
+
+ expect(page).to have_text("Profile was successfully updated")
+ end
+
+ it 'with the incorrect password fails to update' do
+ confirm_password("Fake password")
+
+ expect(page).to have_text("Invalid password")
+ end
+ end
+
it 'clears the reset password token' do
expect(user.reset_password_token?).to be true
- fill_in 'user_email', with: 'new-email@example.com'
- submit_settings
+ update_user_email
+ confirm_password(user.password)
user.reload
expect(user.confirmation_token).not_to be_nil
@@ -524,14 +561,11 @@ RSpec.describe 'User edit profile' do
page.find("a", text: "Nuku'alofa").click
- tz = page.find('.user-time-preferences #user_timezone', visible: false)
-
- expect(tz.value).to eq('Pacific/Tongatapu')
+ expect(page).to have_field(:user_timezone, with: 'Pacific/Tongatapu', type: :hidden)
end
- it 'timezone defaults to servers default' do
- timezone_name = Time.zone.tzinfo.name
- expect(page.find('.user-time-preferences #user_timezone', visible: false).value).to eq(timezone_name)
+ it 'timezone defaults to empty' do
+ expect(page).to have_field(:user_timezone, with: '', type: :hidden)
end
end
end
diff --git a/spec/features/projects/badges/coverage_spec.rb b/spec/features/projects/badges/coverage_spec.rb
index 1760ec880bc..5c1bc1ad239 100644
--- a/spec/features/projects/badges/coverage_spec.rb
+++ b/spec/features/projects/badges/coverage_spec.rb
@@ -12,6 +12,120 @@ RSpec.describe 'test coverage badge' do
sign_in(user)
end
+ it 'user requests coverage badge image for pipeline with custom limits - 80% good' do
+ create_pipeline do |pipeline|
+ create_build(pipeline, coverage: 80, name: 'test:1')
+ end
+
+ show_test_coverage_badge(min_good: 75, min_acceptable: 50, min_medium: 25)
+
+ expect_coverage_badge_color(:good)
+ expect_coverage_badge('80.00%')
+ end
+
+ it 'user requests coverage badge image for pipeline with custom limits - 74% - bad config' do
+ create_pipeline do |pipeline|
+ create_build(pipeline, coverage: 74, name: 'test:1')
+ end
+ # User sets a minimum good value that is lower than min acceptable and min medium,
+ # in which case we force the min acceptable value to be min good -1 and min medium value to be min acceptable -1
+ show_test_coverage_badge(min_good: 75, min_acceptable: 76, min_medium: 77)
+
+ expect_coverage_badge_color(:acceptable)
+ expect_coverage_badge('74.00%')
+ end
+
+ it 'user requests coverage badge image for pipeline with custom limits - 73% - bad config' do
+ create_pipeline do |pipeline|
+ create_build(pipeline, coverage: 73, name: 'test:1')
+ end
+ # User sets a minimum good value that is lower than min acceptable and min medium,
+ # in which case we force the min acceptable value to be min good -1 and min medium value to be min acceptable -1
+ show_test_coverage_badge(min_good: 75, min_acceptable: 76, min_medium: 77)
+
+ expect_coverage_badge_color(:medium)
+ expect_coverage_badge('73.00%')
+ end
+
+ it 'user requests coverage badge image for pipeline with custom limits - 72% - partial config - low' do
+ create_pipeline do |pipeline|
+ create_build(pipeline, coverage: 72, name: 'test:1')
+ end
+ # User only sets good to 75 and leaves the others on the default settings,
+ # in which case we force the min acceptable value to be min good -1 and min medium value to be min acceptable -1
+ show_test_coverage_badge(min_good: 75)
+
+ expect_coverage_badge_color(:low)
+ expect_coverage_badge('72.00%')
+ end
+
+ it 'user requests coverage badge image for pipeline with custom limits - 72% - partial config - medium' do
+ create_pipeline do |pipeline|
+ create_build(pipeline, coverage: 72, name: 'test:1')
+ end
+ # User only sets good to 74 and leaves the others on the default settings,
+ # in which case we force the min acceptable value to be min good -1 and min medium value to be min acceptable -1
+ show_test_coverage_badge(min_good: 74)
+
+ expect_coverage_badge_color(:medium)
+ expect_coverage_badge('72.00%')
+ end
+
+ it 'user requests coverage badge image for pipeline with custom limits - 72% - partial config - medium v2' do
+ create_pipeline do |pipeline|
+ create_build(pipeline, coverage: 72, name: 'test:1')
+ end
+ # User only sets medium to 72 and leaves the others on the defaults good as 95 and acceptable as 90
+ show_test_coverage_badge(min_medium: 72)
+
+ expect_coverage_badge_color(:medium)
+ expect_coverage_badge('72.00%')
+ end
+
+ it 'user requests coverage badge image for pipeline with custom limits - 70% acceptable' do
+ create_pipeline do |pipeline|
+ create_build(pipeline, coverage: 70, name: 'test:1')
+ end
+
+ show_test_coverage_badge(min_good: 75, min_acceptable: 50, min_medium: 25)
+
+ expect_coverage_badge_color(:acceptable)
+ expect_coverage_badge('70.00%')
+ end
+
+ it 'user requests coverage badge image for pipeline with custom limits - 30% medium' do
+ create_pipeline do |pipeline|
+ create_build(pipeline, coverage: 30, name: 'test:1')
+ end
+
+ show_test_coverage_badge(min_good: 75, min_acceptable: 50, min_medium: 25)
+
+ expect_coverage_badge_color(:medium)
+ expect_coverage_badge('30.00%')
+ end
+
+ it 'user requests coverage badge image for pipeline with custom limits - 20% low' do
+ create_pipeline do |pipeline|
+ create_build(pipeline, coverage: 20, name: 'test:1')
+ end
+
+ show_test_coverage_badge(min_good: 75, min_acceptable: 50, min_medium: 25)
+
+ expect_coverage_badge_color(:low)
+ expect_coverage_badge('20.00%')
+ end
+
+ it 'user requests coverage badge image for pipeline with custom limits - nonsense values which use the defaults' do
+ create_pipeline do |pipeline|
+ create_build(pipeline, coverage: 92, name: 'test:1')
+ end
+
+ show_test_coverage_badge(min_good: "nonsense", min_acceptable: "rubbish", min_medium: "NaN")
+
+ expect_coverage_badge_color(:acceptable)
+ expect_coverage_badge('92.00%')
+ end
+
it 'user requests coverage badge image for pipeline' do
create_pipeline do |pipeline|
create_build(pipeline, coverage: 100, name: 'test:1')
@@ -20,6 +134,7 @@ RSpec.describe 'test coverage badge' do
show_test_coverage_badge
+ expect_coverage_badge_color(:good)
expect_coverage_badge('95.00%')
end
@@ -32,6 +147,7 @@ RSpec.describe 'test coverage badge' do
show_test_coverage_badge(job: 'coverage')
+ expect_coverage_badge_color(:medium)
expect_coverage_badge('85.00%')
end
@@ -73,8 +189,9 @@ RSpec.describe 'test coverage badge' do
create(:ci_build, :success, opts)
end
- def show_test_coverage_badge(job: nil)
- visit coverage_project_badges_path(project, ref: :master, job: job, format: :svg)
+ def show_test_coverage_badge(job: nil, min_good: nil, min_acceptable: nil, min_medium: nil)
+ visit coverage_project_badges_path(project, ref: :master, job: job, min_good: min_good,
+ min_acceptable: min_acceptable, min_medium: min_medium, format: :svg)
end
def expect_coverage_badge(coverage)
@@ -82,4 +199,12 @@ RSpec.describe 'test coverage badge' do
expect(page.response_headers['Content-Type']).to include('image/svg+xml')
expect(svg.at(%Q{text:contains("#{coverage}")})).to be_truthy
end
+
+ def expect_coverage_badge_color(color)
+ svg = Nokogiri::HTML(page.body)
+ expect(page.response_headers['Content-Type']).to include('image/svg+xml')
+ badge_color = svg.xpath("//path[starts-with(@d, 'M62')]")[0].attributes['fill'].to_s
+ expected_badge_color = Gitlab::Ci::Badge::Coverage::Template::STATUS_COLOR[color]
+ expect(badge_color).to eq(expected_badge_color)
+ end
end
diff --git a/spec/features/projects/badges/pipeline_badge_spec.rb b/spec/features/projects/badges/pipeline_badge_spec.rb
index 9d8f9872a1a..e3a01ab6fa2 100644
--- a/spec/features/projects/badges/pipeline_badge_spec.rb
+++ b/spec/features/projects/badges/pipeline_badge_spec.rb
@@ -68,7 +68,7 @@ RSpec.describe 'Pipeline Badge' do
visit pipeline_project_badges_path(project, ref: ref, format: :svg)
expect(page.status_code).to eq(200)
- expect(page.response_headers['Cache-Control']).to eq('no-store')
+ expect(page.response_headers['Cache-Control']).to eq('private, no-store')
end
end
diff --git a/spec/features/projects/ci/lint_spec.rb b/spec/features/projects/ci/lint_spec.rb
index 0d9ea6331a7..7f10c6afcd5 100644
--- a/spec/features/projects/ci/lint_spec.rb
+++ b/spec/features/projects/ci/lint_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe 'CI Lint', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/297782' do
+RSpec.describe 'CI Lint', :js do
include Spec::Support::Helpers::Features::SourceEditorSpecHelpers
let(:project) { create(:project, :repository) }
diff --git a/spec/features/projects/container_registry_spec.rb b/spec/features/projects/container_registry_spec.rb
index 40d0260eafd..eec50c3a66a 100644
--- a/spec/features/projects/container_registry_spec.rb
+++ b/spec/features/projects/container_registry_spec.rb
@@ -20,6 +20,7 @@ RSpec.describe 'Container Registry', :js do
sign_in(user)
project.add_developer(user)
stub_container_registry_config(enabled: true)
+ stub_container_registry_info
stub_container_registry_tags(repository: :any, tags: [])
end
@@ -96,6 +97,7 @@ RSpec.describe 'Container Registry', :js do
expect(service).to receive(:execute).with(container_repository) { { status: :success } }
expect(Projects::ContainerRepository::DeleteTagsService).to receive(:new).with(container_repository.project, user, tags: ['1']) { service }
+ first('[data-testid="additional-actions"]').click
first('[data-testid="single-delete-button"]').click
expect(find('.modal .modal-title')).to have_content _('Remove tag')
find('.modal .modal-footer .btn-danger').click
@@ -121,6 +123,16 @@ RSpec.describe 'Container Registry', :js do
expect(page).to have_content('Digest: N/A')
end
end
+
+ [ContainerRegistry::Path::InvalidRegistryPathError, Faraday::Error].each do |error_class|
+ context "when there is a #{error_class}" do
+ before do
+ expect(::ContainerRegistry::Client).to receive(:registry_info).and_raise(error_class, nil, nil)
+ end
+
+ it_behaves_like 'handling feature network errors with the container registry'
+ end
+ end
end
describe 'image repo details when image has no name' do
diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb
index 9413fae02e0..34e2ca7c8a7 100644
--- a/spec/features/projects/environments/environments_spec.rb
+++ b/spec/features/projects/environments/environments_spec.rb
@@ -226,6 +226,7 @@ RSpec.describe 'Environments page', :js do
end
it 'does not show terminal button' do
+ expect(page).not_to have_button(_('More actions'))
expect(page).not_to have_terminal_button
end
@@ -273,6 +274,7 @@ RSpec.describe 'Environments page', :js do
let(:role) { :maintainer }
it 'shows the terminal button' do
+ click_button(_('More actions'))
expect(page).to have_terminal_button
end
end
@@ -281,6 +283,7 @@ RSpec.describe 'Environments page', :js do
let(:role) { :developer }
it 'does not show terminal button' do
+ expect(page).not_to have_button(_('More actions'))
expect(page).not_to have_terminal_button
end
end
@@ -515,7 +518,7 @@ RSpec.describe 'Environments page', :js do
end
def have_terminal_button
- have_link(nil, href: terminal_project_environment_path(project, environment))
+ have_link(_('Terminal'), href: terminal_project_environment_path(project, environment))
end
def visit_environments(project, **opts)
diff --git a/spec/features/projects/files/user_creates_directory_spec.rb b/spec/features/projects/files/user_creates_directory_spec.rb
index 46b93d738e1..5ad7641a5be 100644
--- a/spec/features/projects/files/user_creates_directory_spec.rb
+++ b/spec/features/projects/files/user_creates_directory_spec.rb
@@ -98,12 +98,14 @@ RSpec.describe 'Projects > Files > User creates a directory', :js do
expect(page).to have_content(fork_message)
find('.add-to-tree').click
+ wait_for_requests
click_link('New directory')
fill_in(:dir_name, with: 'new_directory')
fill_in(:commit_message, with: 'New commit message', visible: true)
click_button('Create directory')
fork = user.fork_of(project2.reload)
+ wait_for_requests
expect(current_path).to eq(project_new_merge_request_path(fork))
end
diff --git a/spec/features/projects/files/user_uploads_files_spec.rb b/spec/features/projects/files/user_uploads_files_spec.rb
index 54e816d3d13..cc621dfd9f8 100644
--- a/spec/features/projects/files/user_uploads_files_spec.rb
+++ b/spec/features/projects/files/user_uploads_files_spec.rb
@@ -19,13 +19,15 @@ RSpec.describe 'Projects > Files > User uploads files' do
wait_for_requests
end
- include_examples 'it uploads and commits a new text file'
+ [true, false].each do |value|
+ include_examples 'it uploads and commits a new text file', drop: value
- include_examples 'it uploads and commits a new image file'
+ include_examples 'it uploads and commits a new image file', drop: value
- include_examples 'it uploads and commits a new pdf file'
+ include_examples 'it uploads and commits a new pdf file', drop: value
- include_examples 'it uploads a file to a sub-directory'
+ include_examples 'it uploads a file to a sub-directory', drop: value
+ end
end
context 'when a user does not have write access' do
@@ -35,6 +37,8 @@ RSpec.describe 'Projects > Files > User uploads files' do
visit(project_tree_path(project2))
end
- include_examples 'it uploads and commits a new file to a forked project'
+ [true, false].each do |value|
+ include_examples 'it uploads and commits a new file to a forked project', drop: value
+ end
end
end
diff --git a/spec/features/projects/infrastructure_registry_spec.rb b/spec/features/projects/infrastructure_registry_spec.rb
index 16dd96e6c02..ee35e02b5e8 100644
--- a/spec/features/projects/infrastructure_registry_spec.rb
+++ b/spec/features/projects/infrastructure_registry_spec.rb
@@ -45,10 +45,8 @@ RSpec.describe 'Infrastructure Registry' do
expect(page).to have_css('.packages-app h1[data-testid="title"]', text: terraform_module.name)
- page.within(%Q([name="#{terraform_module.name}"])) do
- expect(page).to have_content('Provision instructions')
- expect(page).to have_content('Registry setup')
- end
+ expect(page).to have_content('Provision instructions')
+ expect(page).to have_content('Registry setup')
end
end
diff --git a/spec/features/projects/jobs/user_browses_jobs_spec.rb b/spec/features/projects/jobs/user_browses_jobs_spec.rb
index dbcd7b5caf5..8538b894869 100644
--- a/spec/features/projects/jobs/user_browses_jobs_spec.rb
+++ b/spec/features/projects/jobs/user_browses_jobs_spec.rb
@@ -2,36 +2,276 @@
require 'spec_helper'
+def visit_jobs_page
+ visit(project_jobs_path(project))
+
+ wait_for_requests
+end
+
RSpec.describe 'User browses jobs' do
- let!(:build) { create(:ci_build, :coverage, pipeline: pipeline) }
- let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') }
- let(:project) { create(:project, :repository, namespace: user.namespace) }
- let(:user) { create(:user) }
+ describe 'with jobs_table_vue feature flag turned off' do
+ let!(:build) { create(:ci_build, :coverage, pipeline: pipeline) }
+ let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') }
+ let(:project) { create(:project, :repository, namespace: user.namespace) }
+ let(:user) { create(:user) }
- before do
- stub_feature_flags(jobs_table_vue: false)
- project.add_maintainer(user)
- project.enable_ci
- project.update_attribute(:build_coverage_regex, /Coverage (\d+)%/)
+ before do
+ stub_feature_flags(jobs_table_vue: false)
+ project.add_maintainer(user)
+ project.enable_ci
+ project.update_attribute(:build_coverage_regex, /Coverage (\d+)%/)
- sign_in(user)
+ sign_in(user)
- visit(project_jobs_path(project))
- end
+ visit(project_jobs_path(project))
+ end
- it 'shows the coverage' do
- page.within('td.coverage') do
- expect(page).to have_content('99.9%')
+ it 'shows the coverage' do
+ page.within('td.coverage') do
+ expect(page).to have_content('99.9%')
+ end
+ end
+
+ context 'with a failed job' do
+ let!(:build) { create(:ci_build, :coverage, :failed, pipeline: pipeline) }
+
+ 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
- context 'with a failed job' do
- let!(:build) { create(:ci_build, :coverage, :failed, pipeline: pipeline) }
+ describe 'with jobs_table_vue feature flag turned on', :js do
+ let(:project) { create(:project, :repository) }
+ let(:user) { create(:user) }
+
+ before do
+ stub_feature_flags(jobs_table_vue: true)
+
+ project.add_maintainer(user)
+ project.enable_ci
+
+ sign_in(user)
+ end
+
+ describe 'header tabs' do
+ before do
+ visit_jobs_page
+ end
+
+ it 'shows a tab for All jobs and count' do
+ expect(page.find('[data-testid="jobs-all-tab"]').text).to include('All')
+ expect(page.find('[data-testid="jobs-all-tab"] .badge').text).to include('0')
+ end
+
+ it 'shows a tab for Pending jobs and count' do
+ expect(page.find('[data-testid="jobs-pending-tab"]').text).to include('Pending')
+ expect(page.find('[data-testid="jobs-pending-tab"] .badge').text).to include('0')
+ end
+
+ it 'shows a tab for Running jobs and count' do
+ expect(page.find('[data-testid="jobs-running-tab"]').text).to include('Running')
+ expect(page.find('[data-testid="jobs-running-tab"] .badge').text).to include('0')
+ end
+
+ it 'shows a tab for Finished jobs and count' do
+ expect(page.find('[data-testid="jobs-finished-tab"]').text).to include('Finished')
+ expect(page.find('[data-testid="jobs-finished-tab"] .badge').text).to include('0')
+ end
+
+ it 'updates the content when tab is clicked' do
+ page.find('[data-testid="jobs-finished-tab"]').click
+ wait_for_requests
+
+ expect(page).to have_content('No jobs to show')
+ end
+ end
+
+ describe 'Empty state' do
+ before do
+ visit_jobs_page
+ end
+
+ it 'renders an empty state' do
+ expect(page).to have_content 'Use jobs to automate your tasks'
+ expect(page).to have_content 'Create CI/CD configuration file'
+ end
+ end
+
+ describe 'Job actions' do
+ let!(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.id, ref: 'master') }
+
+ context 'when a job can be canceled' do
+ let!(:job) do
+ create(:ci_build, pipeline: pipeline,
+ stage: 'test')
+ end
+
+ before do
+ job.run
+
+ visit_jobs_page
+ end
+
+ it 'cancels a job successfully' do
+ page.find('[data-testid="cancel-button"]').click
+
+ wait_for_requests
+
+ expect(page).to have_selector('.ci-canceled')
+ end
+ end
+
+ context 'when a job can be retried' do
+ let!(:job) do
+ create(:ci_build, pipeline: pipeline,
+ stage: 'test')
+ end
+
+ before do
+ job.drop
+
+ visit_jobs_page
+ end
+
+ it 'retries a job successfully' do
+ page.find('[data-testid="retry"]').click
+
+ wait_for_requests
+
+ expect(page).to have_selector('.ci-pending')
+ end
+ end
+
+ context 'with a scheduled job' do
+ let!(:scheduled_job) { create(:ci_build, :scheduled, pipeline: pipeline, name: 'build') }
+
+ before do
+ visit_jobs_page
+ end
+
+ it 'plays a job successfully' do
+ page.find('[data-testid="play-scheduled"]').click
+
+ page.within '#play-job-modal' do
+ page.find_button('OK').click
+ end
+
+ wait_for_requests
+
+ expect(page).to have_selector('.ci-pending')
+ end
+
+ it 'unschedules a job successfully' do
+ page.find('[data-testid="unschedule"]').click
+
+ wait_for_requests
+
+ expect(page).to have_selector('.ci-manual')
+ end
+ end
+
+ context 'with downloadable artifacts' do
+ let!(:with_artifacts) do
+ build = create(:ci_build, :success,
+ pipeline: pipeline,
+ name: 'rspec tests',
+ stage: 'test')
+
+ create(:ci_job_artifact, :codequality, job: build)
+ end
+
+ before do
+ visit_jobs_page
+ end
+
+ it 'shows the download artifacts button' do
+ expect(page).to have_selector('[data-testid="download-artifacts"]')
+ end
+ end
+
+ context 'with artifacts expired' do
+ let!(:with_artifacts_expired) do
+ create(:ci_build, :expired, :success,
+ pipeline: pipeline,
+ name: 'rspec',
+ stage: 'test')
+ end
+
+ before do
+ visit_jobs_page
+ end
+
+ it 'does not show the download artifacts button' do
+ expect(page).not_to have_selector('[data-testid="download-artifacts"]')
+ end
+ end
+ end
+
+ describe 'Jobs table' do
+ let!(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.id, ref: 'master') }
+
+ context 'column links' do
+ let!(:job) do
+ create(:ci_build, pipeline: pipeline,
+ stage: 'test')
+ end
+
+ before do
+ job.run
+
+ visit_jobs_page
+ end
+
+ it 'contains a link to the pipeline' do
+ expect(page.find('[data-testid="pipeline-id"]')).to have_content "##{pipeline.id}"
+ end
+
+ it 'contains a link to the job sha' do
+ expect(page.find('[data-testid="job-sha"]')).to have_content "#{job.sha[0..7]}"
+ end
+
+ it 'contains a link to the job id' do
+ expect(page.find('[data-testid="job-id-link"]')).to have_content "#{job.id}"
+ end
+
+ it 'contains a link to the job ref' do
+ expect(page.find('[data-testid="job-ref"]')).to have_content "#{job.ref}"
+ end
+ end
+ end
+
+ describe 'when user is not logged in' do
+ before do
+ sign_out(user)
+ end
+
+ context 'when project is public' do
+ let(:public_project) { create(:project, :public, :repository) }
+
+ context 'without jobs' do
+ it 'shows an empty state' do
+ visit project_jobs_path(public_project)
+ wait_for_requests
+
+ expect(page).to have_content 'Use jobs to automate your tasks'
+ end
+ end
+ end
+
+ context 'when project is private' do
+ let(:private_project) { create(:project, :private, :repository) }
+
+ it 'redirects the user to sign_in and displays the flash alert' do
+ visit project_jobs_path(private_project)
+ wait_for_requests
- 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)')
+ expect(page).to have_content 'You need to sign in'
+ expect(page.current_path).to eq("/users/sign_in")
+ end
end
end
end
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index a1416f3f563..7ccd5c51493 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -46,7 +46,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
it "shows Pending tab jobs" do
- expect(page).to have_selector('.nav-links li.active', text: 'Pending')
+ expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Pending')
expect(page).to have_content job.short_sha
expect(page).to have_content job.ref
expect(page).to have_content job.name
@@ -60,7 +60,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
it "shows Running tab jobs" do
- expect(page).to have_selector('.nav-links li.active', text: 'Running')
+ expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Running')
expect(page).to have_content job.short_sha
expect(page).to have_content job.ref
expect(page).to have_content job.name
@@ -74,7 +74,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
it "shows Finished tab jobs" do
- expect(page).to have_selector('.nav-links li.active', text: 'Finished')
+ expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'Finished')
expect(page).to have_content('Use jobs to automate your tasks')
end
end
@@ -86,7 +86,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
it "shows All tab jobs" do
- expect(page).to have_selector('.nav-links li.active', text: 'All')
+ expect(page).to have_selector('[data-testid="jobs-tabs"] a.active', text: 'All')
expect(page).to have_content job.short_sha
expect(page).to have_content job.ref
expect(page).to have_content job.name
diff --git a/spec/features/projects/members/groups_with_access_list_spec.rb b/spec/features/projects/members/groups_with_access_list_spec.rb
index 84a972b3027..eb32570448b 100644
--- a/spec/features/projects/members/groups_with_access_list_spec.rb
+++ b/spec/features/projects/members/groups_with_access_list_spec.rb
@@ -8,6 +8,7 @@ RSpec.describe 'Projects > Members > Groups with access list', :js do
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group, :public) }
let_it_be(:project) { create(:project, :public) }
+ let_it_be(:expiration_date) { 5.days.from_now.to_date }
let(:additional_link_attrs) { {} }
let!(:group_link) { create(:project_group_link, project: project, group: group, **additional_link_attrs) }
@@ -37,27 +38,27 @@ RSpec.describe 'Projects > Members > Groups with access list', :js do
it 'updates expiry date' do
page.within find_group_row(group) do
- fill_in 'Expiration date', with: 5.days.from_now.to_date
+ fill_in 'Expiration date', with: expiration_date
find_field('Expiration date').native.send_keys :enter
wait_for_requests
- expect(page).to have_content(/in \d days/)
+ expect(page).to have_field('Expiration date', with: expiration_date)
end
end
context 'when link has expiry date set' do
- let(:additional_link_attrs) { { expires_at: 5.days.from_now.to_date } }
+ let(:additional_link_attrs) { { expires_at: expiration_date } }
it 'clears expiry date' do
page.within find_group_row(group) do
- expect(page).to have_content(/in \d days/)
+ expect(page).to have_field('Expiration date', with: expiration_date)
find('[data-testid="clear-button"]').click
wait_for_requests
- expect(page).to have_content('No expiration set')
+ expect(page).to have_field('Expiration date', with: '')
end
end
end
diff --git a/spec/features/projects/members/invite_group_spec.rb b/spec/features/projects/members/invite_group_spec.rb
index 8c3646125a5..b674cad0312 100644
--- a/spec/features/projects/members/invite_group_spec.rb
+++ b/spec/features/projects/members/invite_group_spec.rb
@@ -165,6 +165,8 @@ RSpec.describe 'Project > Members > Invite group', :js do
let(:project) { create(:project) }
let!(:group) { create(:group) }
+ let_it_be(:expiration_date) { 5.days.from_now.to_date }
+
around do |example|
freeze_time { example.run }
end
@@ -176,15 +178,14 @@ RSpec.describe 'Project > Members > Invite group', :js do
visit project_project_members_path(project)
- invite_group(group.name, role: 'Guest', expires_at: 5.days.from_now)
+ invite_group(group.name, role: 'Guest', expires_at: expiration_date)
end
it 'the group link shows the expiration time with a warning class' do
setup
click_link 'Groups'
- expect(find_group_row(group)).to have_content(/in \d days/)
- expect(find_group_row(group)).to have_selector('.gl-text-orange-500')
+ expect(page).to have_field('Expiration date', with: expiration_date)
end
end
diff --git a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
index c1b14cf60e7..830ada29a2e 100644
--- a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
+++ b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb
@@ -9,6 +9,8 @@ RSpec.describe 'Projects > Members > Maintainer adds member with expiration date
let_it_be(:maintainer) { create(:user) }
let_it_be(:project) { create(:project) }
+ let_it_be(:three_days_from_now) { 3.days.from_now.to_date }
+ let_it_be(:five_days_from_now) { 5.days.from_now.to_date }
let(:new_member) { create(:user) }
@@ -22,39 +24,39 @@ RSpec.describe 'Projects > Members > Maintainer adds member with expiration date
it 'expiration date is displayed in the members list' do
visit project_project_members_path(project)
- invite_member(new_member.name, role: 'Guest', expires_at: 5.days.from_now.to_date)
+ invite_member(new_member.name, role: 'Guest', expires_at: five_days_from_now)
page.within find_member_row(new_member) do
- expect(page).to have_content(/in \d days/)
+ expect(page).to have_field('Expiration date', with: five_days_from_now)
end
end
it 'changes expiration date' do
- project.team.add_users([new_member.id], :developer, expires_at: 3.days.from_now.to_date)
+ project.team.add_users([new_member.id], :developer, expires_at: three_days_from_now)
visit project_project_members_path(project)
page.within find_member_row(new_member) do
- fill_in 'Expiration date', with: 5.days.from_now.to_date
+ fill_in 'Expiration date', with: five_days_from_now
find_field('Expiration date').native.send_keys :enter
wait_for_requests
- expect(page).to have_content(/in \d days/)
+ expect(page).to have_field('Expiration date', with: five_days_from_now)
end
end
it 'clears expiration date' do
- project.team.add_users([new_member.id], :developer, expires_at: 5.days.from_now.to_date)
+ project.team.add_users([new_member.id], :developer, expires_at: five_days_from_now)
visit project_project_members_path(project)
page.within find_member_row(new_member) do
- expect(page).to have_content(/in \d days/)
+ expect(page).to have_field('Expiration date', with: five_days_from_now)
find('[data-testid="clear-button"]').click
wait_for_requests
- expect(page).to have_content('No expiration set')
+ expect(page).to have_field('Expiration date', with: '')
end
end
diff --git a/spec/features/projects/navbar_spec.rb b/spec/features/projects/navbar_spec.rb
index 876bc82d16c..f61eaccf5b9 100644
--- a/spec/features/projects/navbar_spec.rb
+++ b/spec/features/projects/navbar_spec.rb
@@ -18,6 +18,7 @@ RSpec.describe 'Project navbar' do
stub_config(registry: { enabled: false })
insert_package_nav(_('Infrastructure'))
insert_infrastructure_registry_nav
+ insert_infrastructure_google_cloud_nav
end
it_behaves_like 'verified navigation bar' do
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index 39f9d3b331b..dacbaa826a0 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -296,12 +296,16 @@ RSpec.describe 'New project', :js do
expect(git_import_instructions).to have_content 'Git repository URL'
end
- it 'reports error if repo URL does not end with .git' do
+ it 'reports error if repo URL is not a valid Git repository' do
+ stub_request(:get, "http://foo/bar/info/refs?service=git-upload-pack").to_return(status: 200, body: "not-a-git-repo")
+
fill_in 'project_import_url', with: 'http://foo/bar'
# simulate blur event
find('body').click
- expect(page).to have_text('A repository URL usually ends in a .git suffix')
+ wait_for_requests
+
+ expect(page).to have_text('There is not a valid Git repository at this URL')
end
it 'keeps "Import project" tab open after form validation error' do
diff --git a/spec/features/projects/packages_spec.rb b/spec/features/projects/packages_spec.rb
index 7fcc8200b1c..9b1e87192f5 100644
--- a/spec/features/projects/packages_spec.rb
+++ b/spec/features/projects/packages_spec.rb
@@ -27,6 +27,10 @@ RSpec.describe 'Packages' do
context 'when feature is available', :js do
before do
+ # we are simply setting the featrure flag to false because the new UI has nothing to test yet
+ # when the refactor is complete or almost complete we will turn on the feature tests
+ # see https://gitlab.com/gitlab-org/gitlab/-/issues/330846 for status of this work
+ stub_feature_flags(package_list_apollo: false)
visit_project_packages
end
diff --git a/spec/features/projects/settings/monitor_settings_spec.rb b/spec/features/projects/settings/monitor_settings_spec.rb
index e3d75c30e5e..3f6c4646f00 100644
--- a/spec/features/projects/settings/monitor_settings_spec.rb
+++ b/spec/features/projects/settings/monitor_settings_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe 'Projects > Settings > For a forked project', :js do
let_it_be(:project) { create(:project, :repository, create_templates: :issue) }
- let(:user) { project.owner}
+ let(:user) { project.owner }
before do
sign_in(user)
@@ -16,7 +16,8 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do
visit project_path(project)
wait_for_requests
- expect(page).to have_selector('.sidebar-sub-level-items a[aria-label="Monitor"]', text: 'Monitor', visible: false)
+ expect(page).to have_selector('.sidebar-sub-level-items a[aria-label="Monitor"]',
+ text: 'Monitor', visible: :hidden)
end
end
@@ -42,7 +43,7 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do
expect(find_field(send_email)).to be_checked
end
- it 'updates form values', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/333665' do
+ it 'updates form values' do
check(create_issue)
uncheck(send_email)
click_on('No template selected')
@@ -52,10 +53,8 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do
click_settings_tab
expect(find_field(create_issue)).to be_checked
- expect(page).to have_selector(:id, 'alert-integration-settings-issue-template', text: 'bug')
-
- click_settings_tab
expect(find_field(send_email)).not_to be_checked
+ expect(page).to have_selector(:id, 'alert-integration-settings-issue-template', text: 'bug')
end
def click_settings_tab
@@ -68,13 +67,15 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do
page.within '[data-testid="alert-integration-settings"]' do
click_button 'Save changes'
end
+
+ wait_for_all_requests
end
end
- context 'error tracking settings form' do
+ describe 'error tracking settings form' do
let(:sentry_list_projects_url) { 'http://sentry.example.com/api/0/projects/' }
- context 'success path' do
+ context 'when project dropdown is loaded' do
let(:projects_sample_response) do
Gitlab::Utils.deep_indifferent_access(
Gitlab::Json.parse(fixture_file('sentry/list_projects_sample_response.json'))
@@ -97,7 +98,9 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do
within '.js-error-tracking-settings' do
click_button('Expand')
+ choose('cloud-hosted Sentry')
end
+
expect(page).to have_content('Sentry API URL')
expect(page.body).to include('Error Tracking')
expect(page).to have_button('Connect')
@@ -121,7 +124,7 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do
end
end
- context 'project dropdown fails to load' do
+ context 'when project dropdown fails to load' do
before do
WebMock.stub_request(:get, sentry_list_projects_url)
.to_return(
@@ -140,8 +143,10 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do
within '.js-error-tracking-settings' do
click_button('Expand')
+ choose('cloud-hosted Sentry')
+ check('Active')
end
- check('Active')
+
fill_in('error-tracking-api-host', with: 'http://sentry.example.com')
fill_in('error-tracking-token', with: 'token')
@@ -151,7 +156,7 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do
end
end
- context 'integrated error tracking backend' do
+ context 'with integrated error tracking backend' do
it 'successfully fills and submits the form' do
visit project_settings_operations_path(project)
@@ -175,11 +180,17 @@ RSpec.describe 'Projects > Settings > For a forked project', :js do
wait_for_requests
assert_text('Your changes have been saved')
+
+ within '.js-error-tracking-settings' do
+ click_button('Expand')
+ end
+
+ expect(page).to have_content('Paste this DSN into your Sentry SDK')
end
end
end
- context 'grafana integration settings form' do
+ describe 'grafana integration settings form' do
it 'successfully fills and completes the form' do
visit project_settings_operations_path(project)
diff --git a/spec/features/projects/settings/webhooks_settings_spec.rb b/spec/features/projects/settings/webhooks_settings_spec.rb
index 528fd58cbe6..8d73ffecd46 100644
--- a/spec/features/projects/settings/webhooks_settings_spec.rb
+++ b/spec/features/projects/settings/webhooks_settings_spec.rb
@@ -115,8 +115,8 @@ RSpec.describe 'Projects > Settings > Webhook Settings' do
hook_log
visit edit_project_hook_path(project, hook)
- expect(page).to have_content('Recent Deliveries')
- expect(page).to have_content(hook_log.url)
+ expect(page).to have_content('Recent events')
+ expect(page).to have_link('View details', href: hook_log.present.details_path)
end
it 'show hook log details' do
diff --git a/spec/features/projects/show/user_uploads_files_spec.rb b/spec/features/projects/show/user_uploads_files_spec.rb
index eb230082bfa..51e41397439 100644
--- a/spec/features/projects/show/user_uploads_files_spec.rb
+++ b/spec/features/projects/show/user_uploads_files_spec.rb
@@ -21,13 +21,15 @@ RSpec.describe 'Projects > Show > User uploads files' do
wait_for_requests
end
- include_examples 'it uploads and commits a new text file'
+ [true, false].each do |value|
+ include_examples 'it uploads and commits a new text file', drop: value
- include_examples 'it uploads and commits a new image file'
+ include_examples 'it uploads and commits a new image file', drop: value
- include_examples 'it uploads and commits a new pdf file'
+ include_examples 'it uploads and commits a new pdf file', drop: value
- include_examples 'it uploads a file to a sub-directory'
+ include_examples 'it uploads a file to a sub-directory', drop: value
+ end
end
context 'when a user does not have write access' do
@@ -37,7 +39,9 @@ RSpec.describe 'Projects > Show > User uploads files' do
visit(project_path(project2))
end
- include_examples 'it uploads and commits a new file to a forked project'
+ [true, false].each do |value|
+ include_examples 'it uploads and commits a new file to a forked project', drop: value
+ end
end
context 'when in the empty_repo_upload experiment' do
@@ -50,13 +54,17 @@ RSpec.describe 'Projects > Show > User uploads files' do
context 'with an empty repo' do
let(:project) { create(:project, :empty_repo, creator: user) }
- include_examples 'uploads and commits a new text file via "upload file" button'
+ [true, false].each do |value|
+ include_examples 'uploads and commits a new text file via "upload file" button', drop: value
+ end
end
context 'with a nonempty repo' do
let(:project) { create(:project, :repository, creator: user) }
- include_examples 'uploads and commits a new text file via "upload file" button'
+ [true, false].each do |value|
+ include_examples 'uploads and commits a new text file via "upload file" button', drop: value
+ end
end
end
end
diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb
index 9f08759603e..5d482f9fbd0 100644
--- a/spec/features/projects/user_creates_project_spec.rb
+++ b/spec/features/projects/user_creates_project_spec.rb
@@ -33,6 +33,29 @@ RSpec.describe 'User creates a project', :js do
expect(page).to have_content(project.url_to_repo)
end
+ it 'creates a new project that is not blank' do
+ stub_experiments(new_project_sast_enabled: 'candidate')
+
+ visit(new_project_path)
+
+ find('[data-qa-panel-name="blank_project"]').click # rubocop:disable QA/SelectorUsage
+ fill_in(:project_name, with: 'With initial commits')
+
+ expect(page).to have_checked_field 'Initialize repository with a README'
+ expect(page).to have_checked_field 'Enable Static Application Security Testing (SAST)'
+
+ page.within('#content-body') do
+ click_button('Create project')
+ end
+
+ project = Project.last
+
+ expect(current_path).to eq(project_path(project))
+ 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')
+ end
+
context 'in a subgroup they do not own' do
let(:parent) { create(:group) }
let!(:subgroup) { create(:group, parent: parent) }
diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb
index 9dcef13757a..4012a302196 100644
--- a/spec/features/security/project/internal_access_spec.rb
+++ b/spec/features/security/project/internal_access_spec.rb
@@ -553,6 +553,7 @@ RSpec.describe "Internal Project Access" do
before do
stub_container_registry_tags(repository: :any, tags: ['latest'])
stub_container_registry_config(enabled: true)
+ stub_container_registry_info
project.container_repositories << container_repository
end
diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb
index 5a200bea80a..aa34ccce2c1 100644
--- a/spec/features/security/project/private_access_spec.rb
+++ b/spec/features/security/project/private_access_spec.rb
@@ -570,6 +570,7 @@ RSpec.describe "Private Project Access" do
before do
stub_container_registry_tags(repository: :any, tags: ['latest'])
stub_container_registry_config(enabled: true)
+ stub_container_registry_info
project.container_repositories << container_repository
end
diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb
index 8ceb6920e77..abe128c6f78 100644
--- a/spec/features/security/project/public_access_spec.rb
+++ b/spec/features/security/project/public_access_spec.rb
@@ -552,6 +552,7 @@ RSpec.describe "Public Project Access" do
before do
stub_container_registry_tags(repository: :any, tags: ['latest'])
stub_container_registry_config(enabled: true)
+ stub_container_registry_info
project.container_repositories << container_repository
end
diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb
index e03f71c5352..fc88cd9205c 100644
--- a/spec/features/snippets/notes_on_personal_snippets_spec.rb
+++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb
@@ -70,8 +70,8 @@ RSpec.describe 'Comments on personal snippets', :js do
context 'when submitting a note' do
it 'shows a valid form' do
is_expected.to have_css('.js-main-target-form', visible: true, count: 1)
- expect(find('.js-main-target-form .js-comment-button').value)
- .to eq('Comment')
+ expect(find('.js-main-target-form .js-comment-button button', match: :first))
+ .to have_content('Comment')
page.within('.js-main-target-form') do
expect(page).not_to have_link('Cancel')
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index 79c4057a8b9..10c1c2cb26e 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -171,6 +171,18 @@ RSpec.describe 'Login', :clean_gitlab_redis_shared_state do
end
end
+ describe 'with OneTrust authentication' do
+ before do
+ stub_config(extra: { one_trust_id: SecureRandom.uuid })
+ end
+
+ it 'has proper Content-Security-Policy headers' do
+ visit root_path
+
+ expect(response_headers['Content-Security-Policy']).to include('https://cdn.cookielaw.org https://*.onetrust.com')
+ end
+ end
+
describe 'with two-factor authentication', :js do
def enter_code(code)
fill_in 'user_otp_attempt', with: code
@@ -866,8 +878,8 @@ RSpec.describe 'Login', :clean_gitlab_redis_shared_state do
expect(current_path).to eq(new_profile_password_path)
- fill_in 'user_current_password', with: '12345678'
- fill_in 'user_password', with: 'new password'
+ fill_in 'user_password', with: '12345678'
+ fill_in 'user_new_password', with: 'new password'
fill_in 'user_password_confirmation', with: 'new password'
click_button 'Set new password'
@@ -875,7 +887,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_shared_state do
end
end
- context 'when the user does not have an email configured' do
+ context 'when the user does not have an email configured', :js do
let(:user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'saml', email: 'temp-email-for-oauth-user@gitlab.localhost') }
before do
diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb
index e629d329033..61672662fbe 100644
--- a/spec/features/users/show_spec.rb
+++ b/spec/features/users/show_spec.rb
@@ -81,6 +81,7 @@ RSpec.describe 'User page' do
context 'timezone' do
let_it_be(:timezone) { 'America/Los_Angeles' }
+ let_it_be(:local_time_selector) { '[data-testid="user-local-time"]' }
before do
travel_to Time.find_zone(timezone).local(2021, 7, 20, 15, 30, 45)
@@ -92,7 +93,19 @@ RSpec.describe 'User page' do
it 'shows local time' do
subject
- expect(page).to have_content('3:30 PM')
+ within local_time_selector do
+ expect(page).to have_content('3:30 PM')
+ end
+ end
+ end
+
+ context 'when timezone is not set' do
+ let_it_be(:user) { create(:user, timezone: nil) }
+
+ it 'does not show local time' do
+ subject
+
+ expect(page).not_to have_selector(local_time_selector)
end
end
@@ -102,7 +115,9 @@ RSpec.describe 'User page' do
it 'shows local time using the configured default timezone (UTC in this case)' do
subject
- expect(page).to have_content('10:30 PM')
+ within local_time_selector do
+ expect(page).to have_content('10:30 PM')
+ end
end
end
end