diff options
Diffstat (limited to 'spec/features/projects')
37 files changed, 615 insertions, 237 deletions
diff --git a/spec/features/projects/branches/user_deletes_branch_spec.rb b/spec/features/projects/branches/user_deletes_branch_spec.rb index 0d08e7ea10d..a89fed3a78a 100644 --- a/spec/features/projects/branches/user_deletes_branch_spec.rb +++ b/spec/features/projects/branches/user_deletes_branch_spec.rb @@ -3,6 +3,8 @@ require "spec_helper" RSpec.describe "User deletes branch", :js do + include Spec::Support::Helpers::ModalHelpers + let_it_be(:user) { create(:user) } let(:project) { create(:project, :repository) } @@ -24,9 +26,7 @@ RSpec.describe "User deletes branch", :js do find('.js-delete-branch-button').click end - page.within '.modal-footer' do - click_button 'Yes, delete branch' - end + accept_gl_confirm(button_text: 'Yes, delete branch') wait_for_requests diff --git a/spec/features/projects/ci/editor_spec.rb b/spec/features/projects/ci/editor_spec.rb index 2f960c09936..8197fe46c7b 100644 --- a/spec/features/projects/ci/editor_spec.rb +++ b/spec/features/projects/ci/editor_spec.rb @@ -12,8 +12,6 @@ RSpec.describe 'Pipeline Editor', :js do let(:other_branch) { 'test' } before do - stub_feature_flags(pipeline_editor_file_tree: false) - sign_in(user) project.add_developer(user) @@ -70,14 +68,8 @@ RSpec.describe 'Pipeline Editor', :js do expect(page).to have_content('Pipeline Editor') end - describe 'Branch Switcher (pipeline_editor_file_tree disabled)' do - it_behaves_like 'default branch switcher behavior' - end - - describe 'Branch Switcher (pipeline_editor_file_tree enabled)' do + describe 'Branch Switcher' do before do - stub_feature_flags(pipeline_editor_file_tree: true) - visit project_ci_pipeline_editor_path(project) wait_for_requests diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb index a8a23ba1c85..5c54b7fda7c 100644 --- a/spec/features/projects/clusters/gcp_spec.rb +++ b/spec/features/projects/clusters/gcp_spec.rb @@ -66,9 +66,9 @@ RSpec.describe 'Gcp Cluster', :js do context 'when user destroys the cluster' do before do click_link 'Advanced Settings' - click_button 'Remove integration and resources' + find('[data-testid="remove-integration-button"]').click fill_in 'confirm_cluster_name_input', with: cluster.name - click_button 'Remove integration' + find('[data-testid="remove-integration-modal-button"]').click click_link 'Certificate' end diff --git a/spec/features/projects/clusters/user_spec.rb b/spec/features/projects/clusters/user_spec.rb index b6bfaa3a9b9..527d038f975 100644 --- a/spec/features/projects/clusters/user_spec.rb +++ b/spec/features/projects/clusters/user_spec.rb @@ -100,9 +100,9 @@ RSpec.describe 'User Cluster', :js do context 'when user destroys the cluster' do before do click_link 'Advanced Settings' - click_button 'Remove integration and resources' + find('[data-testid="remove-integration-button"]').click fill_in 'confirm_cluster_name_input', with: cluster.name - click_button 'Remove integration' + find('[data-testid="remove-integration-modal-button"]').click click_link 'Certificate' end diff --git a/spec/features/projects/commit/comments/user_deletes_comments_spec.rb b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb index 67d3276fc14..9059f9e4857 100644 --- a/spec/features/projects/commit/comments/user_deletes_comments_spec.rb +++ b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb @@ -4,6 +4,7 @@ require "spec_helper" RSpec.describe "User deletes comments on a commit", :js do include Spec::Support::Helpers::Features::NotesHelpers + include Spec::Support::Helpers::ModalHelpers include RepoHelpers let(:comment_text) { "XML attached" } @@ -11,7 +12,6 @@ RSpec.describe "User deletes comments on a commit", :js do let(:user) { create(:user) } before do - stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) project.add_developer(user) @@ -32,9 +32,11 @@ RSpec.describe "User deletes comments on a commit", :js do find(".more-actions").click find(".more-actions .dropdown-menu li", match: :first) - accept_confirm { find(".js-note-delete").click } + find(".js-note-delete").click end + accept_gl_confirm(button_text: 'Delete comment') + expect(page).not_to have_css(".note") end end diff --git a/spec/features/projects/commit/user_comments_on_commit_spec.rb b/spec/features/projects/commit/user_comments_on_commit_spec.rb index b0be6edb245..a7f23f093a3 100644 --- a/spec/features/projects/commit/user_comments_on_commit_spec.rb +++ b/spec/features/projects/commit/user_comments_on_commit_spec.rb @@ -4,6 +4,7 @@ require "spec_helper" RSpec.describe "User comments on commit", :js do include Spec::Support::Helpers::Features::NotesHelpers + include Spec::Support::Helpers::ModalHelpers include RepoHelpers let_it_be(:project) { create(:project, :repository) } @@ -93,8 +94,6 @@ RSpec.describe "User comments on commit", :js do context "when deleting comment" do before do - stub_feature_flags(bootstrap_confirmation_modals: false) - visit(project_commit_path(project, sample_commit.id)) add_note(comment_text) @@ -112,9 +111,11 @@ RSpec.describe "User comments on commit", :js do find(".more-actions").click find(".more-actions .dropdown-menu li", match: :first) - accept_confirm { find(".js-note-delete").click } + find(".js-note-delete").click end + accept_gl_confirm(button_text: 'Delete comment') + expect(page).not_to have_css(".note") end end diff --git a/spec/features/projects/commits/multi_view_diff_spec.rb b/spec/features/projects/commits/multi_view_diff_spec.rb index 009dd05c6d1..282112a3767 100644 --- a/spec/features/projects/commits/multi_view_diff_spec.rb +++ b/spec/features/projects/commits/multi_view_diff_spec.rb @@ -18,71 +18,77 @@ RSpec.describe 'Multiple view Diffs', :js do let(:feature_flag_on) { false } before do - stub_feature_flags(rendered_diffs_viewer: feature_flag_on ? project : false) - visit path wait_for_all_requests end - context 'when :rendered_diffs_viewer is off' do - context 'and diff does not have ipynb' do - it_behaves_like "no multiple viewers", 'ddd0f15ae83993f5cb66a927a28673882e99100b' + context 'diff does not include ipynb' do + it_behaves_like "no multiple viewers", 'ddd0f15ae83993f5cb66a927a28673882e99100b' + + context 'and in inline diff' do + let(:ref) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' } + + it 'does not change display for non-ipynb' do + expect(page).to have_selector line_with_content('new', 1) + end end - context 'and diff has ipynb' do - it_behaves_like "no multiple viewers", '5d6ed1503801ca9dc28e95eeb85a7cf863527aee' + context 'and in parallel diff' do + let(:ref) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' } + + it 'does not change display for non-ipynb' do + page.find('#parallel-diff-btn').click + + expect(page).to have_selector line_with_content('new', 1) + end end end - context 'when :rendered_diffs_viewer is on' do - let(:feature_flag_on) { true } + context 'opening a diff with ipynb' do + it 'loads the rendered diff as hidden' do + diff = page.find('.diff-file, .file-holder', match: :first) - context 'and diff does not include ipynb' do - it_behaves_like "no multiple viewers", 'ddd0f15ae83993f5cb66a927a28673882e99100b' + expect(diff).not_to have_selector '[data-diff-toggle-entity="toHide"]' + expect(diff).to have_selector '[data-diff-toggle-entity="toShow"]' - context 'and in inline diff' do - let(:ref) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' } + expect(classes_for_element(diff, 'toHide', visible: false)).to include('hidden') + expect(classes_for_element(diff, 'toShow')).not_to include('hidden') - it 'does not change display for non-ipynb' do - expect(page).to have_selector line_with_content('new', 1) - end - end + expect(classes_for_element(diff, 'toShowBtn')).to include('selected') + expect(classes_for_element(diff, 'toHideBtn')).not_to include('selected') + end - context 'and in parallel diff' do - let(:ref) { '54fcc214b94e78d7a41a9a8fe6d87a5e59500e51' } + it 'displays the rendered diff and hides after selection changes' do + diff = page.find('.diff-file, .file-holder', match: :first) + diff.find('[data-diff-toggle-entity="toShowBtn"]').click - it 'does not change display for non-ipynb' do - page.find('#parallel-diff-btn').click + expect(diff).to have_selector '[data-diff-toggle-entity="toShow"]' + expect(diff).not_to have_selector '[data-diff-toggle-entity="toHide"]' - expect(page).to have_selector line_with_content('new', 1) - end - end + expect(classes_for_element(diff, 'toHideBtn')).not_to include('selected') + expect(classes_for_element(diff, 'toShowBtn')).to include('selected') end - context 'and opening a diff with ipynb' do - it 'loads the rendered diff as hidden' do - diff = page.find('.diff-file, .file-holder', match: :first) - - expect(diff).not_to have_selector '[data-diff-toggle-entity="toHide"]' - expect(diff).to have_selector '[data-diff-toggle-entity="toShow"]' + it 'transforms the diff' do + diff = page.find('.diff-file, .file-holder', match: :first) - expect(classes_for_element(diff, 'toHide', visible: false)).to include('hidden') - expect(classes_for_element(diff, 'toShow')).not_to include('hidden') + expect(diff['innerHTML']).to include('%% Cell type:markdown id:0aac5da7-745c-4eda-847a-3d0d07a1bb9b tags:') + end - expect(classes_for_element(diff, 'toShowBtn')).to include('selected') - expect(classes_for_element(diff, 'toHideBtn')).not_to include('selected') + context 'on parallel view' do + before do + page.find('#parallel-diff-btn').click end - it 'displays the rendered diff and hides after selection changes' do - diff = page.find('.diff-file, .file-holder', match: :first) - diff.find('[data-diff-toggle-entity="toShowBtn"]').click - - expect(diff).to have_selector '[data-diff-toggle-entity="toShow"]' - expect(diff).not_to have_selector '[data-diff-toggle-entity="toHide"]' + it 'lines without mapping cannot receive comments' do + expect(page).not_to have_selector('td.line_content.nomappinginraw ~ td.diff-line-num > .add-diff-note') + expect(page).to have_selector('td.line_content:not(.nomappinginraw) ~ td.diff-line-num > .add-diff-note') + end - expect(classes_for_element(diff, 'toHideBtn')).not_to include('selected') - expect(classes_for_element(diff, 'toShowBtn')).to include('selected') + it 'lines numbers without mapping are empty' do + expect(page).not_to have_selector('td.nomappinginraw + td.diff-line-num') + expect(page).to have_selector('td.nomappinginraw + td.diff-line-num', visible: false) end it 'transforms the diff' do @@ -90,40 +96,18 @@ RSpec.describe 'Multiple view Diffs', :js do expect(diff['innerHTML']).to include('%% Cell type:markdown id:0aac5da7-745c-4eda-847a-3d0d07a1bb9b tags:') end + end - context 'on parallel view' do - before do - page.find('#parallel-diff-btn').click - end - - it 'lines without mapping cannot receive comments' do - expect(page).not_to have_selector('td.line_content.nomappinginraw ~ td.diff-line-num > .add-diff-note') - expect(page).to have_selector('td.line_content:not(.nomappinginraw) ~ td.diff-line-num > .add-diff-note') - end - - it 'lines numbers without mapping are empty' do - expect(page).not_to have_selector('td.nomappinginraw + td.diff-line-num') - expect(page).to have_selector('td.nomappinginraw + td.diff-line-num', visible: false) - end - - it 'transforms the diff' do - diff = page.find('.diff-file, .file-holder', match: :first) - - expect(diff['innerHTML']).to include('%% Cell type:markdown id:0aac5da7-745c-4eda-847a-3d0d07a1bb9b tags:') - end + context 'on inline view' do + it 'lines without mapping cannot receive comments' do + expect(page).not_to have_selector('tr.line_holder[class$="nomappinginraw"] > td.diff-line-num > .add-diff-note') + expect(page).to have_selector('tr.line_holder:not([class$="nomappinginraw"]) > td.diff-line-num > .add-diff-note') end - context 'on inline view' do - it 'lines without mapping cannot receive comments' do - expect(page).not_to have_selector('tr.line_holder[class$="nomappinginraw"] > td.diff-line-num > .add-diff-note') - expect(page).to have_selector('tr.line_holder:not([class$="nomappinginraw"]) > td.diff-line-num > .add-diff-note') - end - - it 'lines numbers without mapping are empty' do - elements = page.all('tr.line_holder[class$="nomappinginraw"] > td.diff-line-num').map { |e| e.text(:all) } + it 'lines numbers without mapping are empty' do + elements = page.all('tr.line_holder[class$="nomappinginraw"] > td.diff-line-num').map { |e| e.text(:all) } - expect(elements).to all(be == "") - end + expect(elements).to all(be == "") end end end diff --git a/spec/features/projects/container_registry_spec.rb b/spec/features/projects/container_registry_spec.rb index 17eb421191f..54685441300 100644 --- a/spec/features/projects/container_registry_spec.rb +++ b/spec/features/projects/container_registry_spec.rb @@ -122,7 +122,7 @@ RSpec.describe 'Container Registry', :js do it 'renders the tags list correctly' do expect(page).to have_content('latest') expect(page).to have_content('stable') - expect(page).to have_content('Digest: N/A') + expect(page).to have_content('Digest: Not applicable.') end end diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb index bfd54b9c6da..951b24eafac 100644 --- a/spec/features/projects/environments/environment_spec.rb +++ b/spec/features/projects/environments/environment_spec.rb @@ -157,7 +157,7 @@ RSpec.describe 'Environment' do context 'with related deployable present' do let(:pipeline) { create(:ci_pipeline, project: project) } - let(:build) { create(:ci_build, pipeline: pipeline) } + let(:build) { create(:ci_build, pipeline: pipeline, environment: environment.name) } let(:deployment) do create(:deployment, :success, environment: environment, deployable: build) @@ -261,9 +261,12 @@ RSpec.describe 'Environment' do context 'when environment is available' do context 'with stop action' do + let(:build) { create(:ci_build, :success, pipeline: pipeline, environment: environment.name) } + let(:action) do create(:ci_build, :manual, pipeline: pipeline, - name: 'close_app') + name: 'close_app', + environment: environment.name) end let(:deployment) do @@ -283,7 +286,6 @@ RSpec.describe 'Environment' do click_button('Stop') click_button('Stop environment') # confirm modal wait_for_all_requests - expect(page).to have_button('Delete') end end @@ -361,8 +363,6 @@ RSpec.describe 'Environment' do end visit_environment(environment) - - expect(page).not_to have_button('Stop') end ## diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb index 6cf59394af7..9ec41cd8f8d 100644 --- a/spec/features/projects/environments/environments_spec.rb +++ b/spec/features/projects/environments/environments_spec.rb @@ -132,8 +132,6 @@ RSpec.describe 'Environments page', :js do create(:environment, project: project, state: :available) end - stub_feature_flags(bootstrap_confirmation_modals: false) - context 'when there are no deployments' do before do visit_environments(project) diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb index 23fcc1fe444..649c21d4459 100644 --- a/spec/features/projects/features_visibility_spec.rb +++ b/spec/features/projects/features_visibility_spec.rb @@ -189,7 +189,7 @@ RSpec.describe 'Edit Project Settings' do click_button "Save changes" end - expect(find(".sharing-permissions")).to have_selector(".gl-toggle.is-disabled", minimum: 4) + expect(find(".sharing-permissions")).to have_selector(".gl-toggle.is-disabled", minimum: 3) end it "shows empty features project homepage" do diff --git a/spec/features/projects/hook_logs/user_reads_log_spec.rb b/spec/features/projects/hook_logs/user_reads_log_spec.rb index 8513a9374d1..9b7ec14c36f 100644 --- a/spec/features/projects/hook_logs/user_reads_log_spec.rb +++ b/spec/features/projects/hook_logs/user_reads_log_spec.rb @@ -3,21 +3,80 @@ require 'spec_helper' RSpec.describe 'Hook logs' do - let(:web_hook_log) { create(:web_hook_log, response_body: '<script>') } - let(:project) { web_hook_log.web_hook.project } + let(:project) { create(:project) } + let(:project_hook) { create(:project_hook, project: project) } + let(:web_hook_log) { create(:web_hook_log, web_hook: project_hook, response_body: 'Hello World') } let(:user) { create(:user) } before do + web_hook_log project.add_maintainer(user) sign_in(user) end - it 'user reads log without getting XSS' do - visit( - project_hook_hook_log_path( - project, web_hook_log.web_hook, web_hook_log)) + it 'shows list of hook logs' do + visit edit_project_hook_path(project, project_hook) - expect(page).to have_content('<script>') + expect(page).to have_content('Recent events') + expect(page).to have_link('View details', href: project_hook_hook_log_path(project, project_hook, web_hook_log)) + end + + it 'shows hook log details' do + visit edit_project_hook_path(project, project_hook) + click_link 'View details' + + expect(page).to have_content("POST #{web_hook_log.url}") + expect(page).to have_content(web_hook_log.response_body) + expect(page).to have_content('Resend Request') + end + + it 'retries hook log' do + WebMock.stub_request(:post, project_hook.url) + + visit edit_project_hook_path(project, project_hook) + click_link 'View details' + click_link 'Resend Request' + + expect(page).to have_current_path(edit_project_hook_path(project, project_hook), ignore_query: true) + end + + context 'request gets internal error' do + let(:web_hook_log) { create(:web_hook_log, web_hook: project_hook, internal_error_message: 'Some error') } + + it 'shows hook log details with internal error message' do + visit edit_project_hook_path(project, project_hook) + click_link 'View details' + + expect(page).to have_content("POST #{web_hook_log.url}") + expect(page).to have_content(web_hook_log.internal_error_message) + expect(page).to have_content('Resend Request') + end + end + + context 'response body contains XSS string' do + let(:web_hook_log) { create(:web_hook_log, web_hook: project_hook, response_body: '<script>') } + + it 'displays log without getting XSS' do + visit(project_hook_hook_log_path(project, project_hook, web_hook_log)) + + expect(page).to have_content('<script>') + end + end + + context 'response data is too large' do + let(:web_hook_log) do + create(:web_hook_log, web_hook: project_hook, request_data: WebHookLog::OVERSIZE_REQUEST_DATA) + end + + it 'shows request data as too large and disables retry function' do + visit(project_hook_hook_log_path(project, project_hook, web_hook_log)) + + expect(page).to have_content('Request data is too large') + expect(page).not_to have_button( + _('Resent request'), + disabled: true, class: 'has-tooltip', title: _("Request data is too large") + ) + end end end diff --git a/spec/features/projects/integrations/user_activates_issue_tracker_spec.rb b/spec/features/projects/integrations/user_activates_issue_tracker_spec.rb index 2821f35f6a6..e7d4ed58549 100644 --- a/spec/features/projects/integrations/user_activates_issue_tracker_spec.rb +++ b/spec/features/projects/integrations/user_activates_issue_tracker_spec.rb @@ -34,7 +34,7 @@ RSpec.describe 'User activates issue tracker', :js do it 'activates the integration' do expect(page).to have_content("#{tracker} settings saved and active.") - expect(page).to have_current_path(edit_project_integration_path(project, tracker.parameterize(separator: '_')), ignore_query: true) + expect(page).to have_current_path(edit_project_settings_integration_path(project, tracker.parameterize(separator: '_')), ignore_query: true) end it 'shows the link in the menu' do @@ -58,7 +58,7 @@ RSpec.describe 'User activates issue tracker', :js do end expect(page).to have_content("#{tracker} settings saved and active.") - expect(page).to have_current_path(edit_project_integration_path(project, tracker.parameterize(separator: '_')), ignore_query: true) + expect(page).to have_current_path(edit_project_settings_integration_path(project, tracker.parameterize(separator: '_')), ignore_query: true) end end end @@ -73,7 +73,7 @@ RSpec.describe 'User activates issue tracker', :js do it 'saves but does not activate the integration' do expect(page).to have_content("#{tracker} settings saved, but not active.") - expect(page).to have_current_path(edit_project_integration_path(project, tracker.parameterize(separator: '_')), ignore_query: true) + expect(page).to have_current_path(edit_project_settings_integration_path(project, tracker.parameterize(separator: '_')), ignore_query: true) end it 'does not show the external tracker link in the menu' do diff --git a/spec/features/projects/integrations/user_activates_jira_spec.rb b/spec/features/projects/integrations/user_activates_jira_spec.rb index f855d6befe7..dad201ffbb6 100644 --- a/spec/features/projects/integrations/user_activates_jira_spec.rb +++ b/spec/features/projects/integrations/user_activates_jira_spec.rb @@ -20,7 +20,7 @@ RSpec.describe 'User activates Jira', :js do it 'activates the Jira integration' do expect(page).to have_content('Jira settings saved and active.') - expect(page).to have_current_path(edit_project_integration_path(project, :jira), ignore_query: true) + expect(page).to have_current_path(edit_project_settings_integration_path(project, :jira), ignore_query: true) end unless Gitlab.ee? @@ -55,13 +55,13 @@ RSpec.describe 'User activates Jira', :js do click_test_then_save_integration expect(page).to have_content('Jira settings saved and active.') - expect(page).to have_current_path(edit_project_integration_path(project, :jira), ignore_query: true) + expect(page).to have_current_path(edit_project_settings_integration_path(project, :jira), ignore_query: true) end end end describe 'user disables the Jira integration' do - include JiraServiceHelper + include JiraIntegrationHelpers before do stub_jira_integration_test @@ -72,7 +72,7 @@ RSpec.describe 'User activates Jira', :js do it 'saves but does not activate the Jira integration' do expect(page).to have_content('Jira settings saved, but not active.') - expect(page).to have_current_path(edit_project_integration_path(project, :jira), ignore_query: true) + expect(page).to have_current_path(edit_project_settings_integration_path(project, :jira), ignore_query: true) end it 'does not show the Jira link in the menu' do diff --git a/spec/features/projects/integrations/user_activates_mattermost_slash_command_spec.rb b/spec/features/projects/integrations/user_activates_mattermost_slash_command_spec.rb index ed0877ab0e9..54c9ec0f62e 100644 --- a/spec/features/projects/integrations/user_activates_mattermost_slash_command_spec.rb +++ b/spec/features/projects/integrations/user_activates_mattermost_slash_command_spec.rb @@ -15,7 +15,7 @@ RSpec.describe 'Set up Mattermost slash commands', :js do let(:mattermost_enabled) { true } describe 'activation' do - let(:edit_path) { edit_project_integration_path(project, :mattermost_slash_commands) } + let(:edit_path) { edit_project_settings_integration_path(project, :mattermost_slash_commands) } include_examples 'user activates the Mattermost Slash Command integration' end diff --git a/spec/features/projects/integrations/user_activates_slack_notifications_spec.rb b/spec/features/projects/integrations/user_activates_slack_notifications_spec.rb index 616469c5df8..e89f6e309ea 100644 --- a/spec/features/projects/integrations/user_activates_slack_notifications_spec.rb +++ b/spec/features/projects/integrations/user_activates_slack_notifications_spec.rb @@ -34,7 +34,7 @@ RSpec.describe 'User activates Slack notifications', :js do pipeline_channel: 6, wiki_page_channel: 7) - visit(edit_project_integration_path(project, integration)) + visit(edit_project_settings_integration_path(project, integration)) end it 'filters events by channel' do diff --git a/spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb b/spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb index 0b4c9620bdf..df8cd84ffdb 100644 --- a/spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb +++ b/spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb @@ -24,7 +24,11 @@ RSpec.describe 'Slack slash commands', :js do click_active_checkbox click_on 'Save' - expect(page).to have_current_path(edit_project_integration_path(project, :slack_slash_commands), ignore_query: true) + expect(page).to have_current_path( + edit_project_settings_integration_path(project, :slack_slash_commands), + ignore_query: true + ) + expect(page).to have_content('Slack slash commands settings saved, but not active.') end @@ -32,7 +36,11 @@ RSpec.describe 'Slack slash commands', :js do fill_in 'Token', with: 'token' click_on 'Save' - expect(page).to have_current_path(edit_project_integration_path(project, :slack_slash_commands), ignore_query: true) + expect(page).to have_current_path( + edit_project_settings_integration_path(project, :slack_slash_commands), + ignore_query: true + ) + expect(page).to have_content('Slack slash commands settings saved and active.') end diff --git a/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb b/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb index fcb04c338a9..8a2881c95dc 100644 --- a/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb +++ b/spec/features/projects/integrations/user_uses_inherited_settings_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'User uses inherited settings', :js do - include JiraServiceHelper + include JiraIntegrationHelpers include_context 'project integration activation' diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb index e2dc760beda..6a2d2c36521 100644 --- a/spec/features/projects/jobs/user_browses_job_spec.rb +++ b/spec/features/projects/jobs/user_browses_job_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'User browses a job', :js do + include Spec::Support::Helpers::ModalHelpers + let(:user) { create(:user) } let(:user_access_level) { :developer } let(:project) { create(:project, :repository, namespace: user.namespace) } @@ -12,7 +14,6 @@ RSpec.describe 'User browses a job', :js do before do project.add_maintainer(user) project.enable_ci - stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end @@ -26,7 +27,11 @@ RSpec.describe 'User browses a job', :js do # scroll to the top of the page first execute_script "window.scrollTo(0,0)" - accept_confirm { find('[data-testid="job-log-erase-link"]').click } + accept_gl_confirm(button_text: 'Erase job log') do + find('[data-testid="job-log-erase-link"]').click + end + + wait_for_requests expect(page).to have_no_css('.artifacts') expect(build).not_to have_trace diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index befaf85fc1e..f0d41c1dd11 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -987,7 +987,9 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do it 'renders message about job being stuck because of no runners with the specified tags' do expect(page).to have_selector('[data-testid="job-stuck-with-tags"') - expect(page).to have_content("This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:") + expect(page).to have_content("This job is stuck because of one of the following problems. There are no active runners online, no runners for the ") + expect(page).to have_content("protected branch") + expect(page).to have_content(", or no runners that match all of the job's tags:") end end @@ -997,7 +999,9 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do it 'renders message about job being stuck because of no runners with the specified tags' do expect(page).to have_selector('[data-testid="job-stuck-with-tags"') - expect(page).to have_content("This job is stuck because you don't have any active runners online or available with any of these tags assigned to them:") + expect(page).to have_content("This job is stuck because of one of the following problems. There are no active runners online, no runners for the ") + expect(page).to have_content("protected branch") + expect(page).to have_content(", or no runners that match all of the job's tags:") end end diff --git a/spec/features/projects/members/manage_members_spec.rb b/spec/features/projects/members/manage_members_spec.rb index 0f4120e88e0..8d229530ef5 100644 --- a/spec/features/projects/members/manage_members_spec.rb +++ b/spec/features/projects/members/manage_members_spec.rb @@ -48,20 +48,48 @@ RSpec.describe 'Projects > Members > Manage members', :js do end end - it 'uses ProjectMember access_level_roles for the invite members modal access option', :aggregate_failures do - visit_members_page + context 'when owner' do + it 'uses ProjectMember access_level_roles for the invite members modal access option', :aggregate_failures do + visit_members_page - click_on 'Invite members' + click_on 'Invite members' - click_on 'Guest' - wait_for_requests + click_on 'Guest' + wait_for_requests - page.within '.dropdown-menu' do - expect(page).to have_button('Guest') - expect(page).to have_button('Reporter') - expect(page).to have_button('Developer') - expect(page).to have_button('Maintainer') - expect(page).not_to have_button('Owner') + page.within '.dropdown-menu' do + expect(page).to have_button('Guest') + expect(page).to have_button('Reporter') + expect(page).to have_button('Developer') + expect(page).to have_button('Maintainer') + expect(page).to have_button('Owner') + end + end + end + + context 'when maintainer' do + let(:maintainer) { create(:user) } + + before do + project.add_maintainer(maintainer) + sign_in(maintainer) + end + + it 'uses ProjectMember access_level_roles for the invite members modal access option', :aggregate_failures do + visit_members_page + + click_on 'Invite members' + + click_on 'Guest' + wait_for_requests + + page.within '.dropdown-menu' do + expect(page).to have_button('Guest') + expect(page).to have_button('Reporter') + expect(page).to have_button('Developer') + expect(page).to have_button('Maintainer') + expect(page).not_to have_button('Owner') + end end end diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb index 67c40c1dbee..db227f3701d 100644 --- a/spec/features/projects/members/member_leaves_project_spec.rb +++ b/spec/features/projects/members/member_leaves_project_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe 'Projects > Members > Member leaves project' do include Spec::Support::Helpers::Features::MembersHelpers + include Spec::Support::Helpers::ModalHelpers let(:user) { create(:user) } let(:project) { create(:project, :repository, :with_namespace_settings) } @@ -11,7 +12,6 @@ RSpec.describe 'Projects > Members > Member leaves project' do before do project.add_developer(user) sign_in(user) - stub_feature_flags(bootstrap_confirmation_modals: false) end it 'user leaves project' do @@ -26,7 +26,7 @@ RSpec.describe 'Projects > Members > Member leaves project' do it 'user leaves project by url param', :js do visit project_path(project, leave: 1) - page.accept_confirm + accept_gl_confirm(button_text: 'Leave project') wait_for_all_requests expect(page).to have_current_path(dashboard_projects_path, ignore_query: true) diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb index 370d7b49832..be124502c32 100644 --- a/spec/features/projects/members/user_requests_access_spec.rb +++ b/spec/features/projects/members/user_requests_access_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'Projects > Members > User requests access', :js do + include Spec::Support::Helpers::ModalHelpers + let_it_be(:user) { create(:user) } let_it_be(:maintainer) { create(:user) } let_it_be(:project) { create(:project, :public, :repository) } @@ -13,7 +15,6 @@ RSpec.describe 'Projects > Members > User requests access', :js do sign_in(user) project.add_maintainer(maintainer) visit project_path(project) - stub_feature_flags(bootstrap_confirmation_modals: false) end it 'request access feature is disabled' do @@ -67,7 +68,7 @@ RSpec.describe 'Projects > Members > User requests access', :js do expect(project.requesters.exists?(user_id: user)).to be_truthy - accept_confirm { click_link 'Withdraw Access Request' } + accept_gl_confirm { click_link 'Withdraw Access Request' } expect(page).not_to have_content 'Withdraw Access Request' expect(page).to have_content 'Request Access' diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb index 0046dfe436f..c323e60bb71 100644 --- a/spec/features/projects/new_project_spec.rb +++ b/spec/features/projects/new_project_spec.rb @@ -57,10 +57,37 @@ RSpec.describe 'New project', :js do expect(page).to have_link('GitHub') expect(page).to have_link('Bitbucket') expect(page).to have_link('GitLab.com') - expect(page).to have_button('Repo by URL') + expect(page).to have_button('Repository by URL') expect(page).to have_link('GitLab export') end + describe 'github import option' do + context 'with user namespace' do + before do + visit new_project_path + click_link 'Import project' + end + + it 'renders link to github importer' do + expect(page).to have_link(href: new_import_github_path) + end + end + + context 'with group namespace' do + let(:group) { create(:group, :private) } + + before do + group.add_owner(user) + visit new_project_path(namespace_id: group.id) + click_link 'Import project' + end + + it 'renders link to github importer including namespace id' do + expect(page).to have_link(href: new_import_github_path(namespace_id: group.id)) + end + end + end + describe 'manifest import option' do before do visit new_project_path @@ -175,7 +202,7 @@ RSpec.describe 'New project', :js do it 'does not show the initialize with Readme checkbox on "Import project" tab' do visit new_project_path click_link 'Import project' - click_button 'Repo by URL' + click_button 'Repository by URL' page.within '#import-project-pane' do expect(page).not_to have_css('input#project_initialize_with_readme') @@ -277,7 +304,7 @@ RSpec.describe 'New project', :js do click_link 'Import project' end - context 'from git repository url, "Repo by URL"' do + context 'from git repository url, "Repository by URL"' do before do first('.js-import-git-toggle-button').click end diff --git a/spec/features/projects/pages/user_adds_domain_spec.rb b/spec/features/projects/pages/user_adds_domain_spec.rb index 71bf1c24655..afa3f29ce0d 100644 --- a/spec/features/projects/pages/user_adds_domain_spec.rb +++ b/spec/features/projects/pages/user_adds_domain_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' RSpec.describe 'User adds pages domain', :js do include LetsEncryptHelpers + include Spec::Support::Helpers::ModalHelpers let_it_be(:project) { create(:project, pages_https_only: false) } @@ -14,8 +15,6 @@ RSpec.describe 'User adds pages domain', :js do project.add_maintainer(user) sign_in(user) - - stub_feature_flags(bootstrap_confirmation_modals: false) end context 'when pages are exposed on external HTTP address', :http_pages_enabled do @@ -95,7 +94,7 @@ RSpec.describe 'User adds pages domain', :js do fill_in 'Domain', with: 'my.test.domain.com' - find('.js-auto-ssl-toggle-container .js-project-feature-toggle').click + find('.js-auto-ssl-toggle-container .js-project-feature-toggle button').click fill_in 'Certificate (PEM)', with: certificate_pem fill_in 'Key (PEM)', with: certificate_key @@ -168,7 +167,7 @@ RSpec.describe 'User adds pages domain', :js do within('#content-body') { click_link 'Edit' } - accept_confirm { click_link 'Remove' } + accept_gl_confirm(button_text: 'Remove certificate') { click_link 'Remove' } expect(page).to have_field('Certificate (PEM)', with: '') expect(page).to have_field('Key (PEM)', with: '') diff --git a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb index bdf280f4fe4..4c633bea64e 100644 --- a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb +++ b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do include LetsEncryptHelpers + include Spec::Support::Helpers::ModalHelpers let(:project) { create(:project, pages_https_only: false) } let(:user) { create(:user) } @@ -14,7 +15,6 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do before do allow(Gitlab.config.pages).to receive(:enabled).and_return(true) stub_lets_encrypt_settings - stub_feature_flags(bootstrap_confirmation_modals: false) project.add_role(user, role) sign_in(user) @@ -50,7 +50,7 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do expect(page).to have_selector '.card-header', text: 'Certificate' expect(page).to have_text domain.subject - find('.js-auto-ssl-toggle-container .js-project-feature-toggle').click + find('.js-auto-ssl-toggle-container .js-project-feature-toggle button').click expect(find("#pages_domain_auto_ssl_enabled", visible: false).value).to eq 'true' expect(page).not_to have_selector '.card-header', text: 'Certificate' @@ -74,7 +74,7 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do expect(page).not_to have_field 'Certificate (PEM)', type: 'textarea' expect(page).not_to have_field 'Key (PEM)', type: 'textarea' - find('.js-auto-ssl-toggle-container .js-project-feature-toggle').click + find('.js-auto-ssl-toggle-container .js-project-feature-toggle button').click expect(find("#pages_domain_auto_ssl_enabled", visible: false).value).to eq 'false' expect(page).to have_field 'Certificate (PEM)', type: 'textarea' @@ -139,7 +139,8 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do expect(page).to have_selector '.card-header', text: 'Certificate' expect(page).to have_text domain.subject - within('.card') { accept_confirm { click_on 'Remove' } } + within('.card') { click_on 'Remove' } + accept_gl_confirm(button_text: 'Remove certificate') expect(page).to have_field 'Certificate (PEM)', with: '' expect(page).to have_field 'Key (PEM)', with: '' end diff --git a/spec/features/projects/pages/user_edits_settings_spec.rb b/spec/features/projects/pages/user_edits_settings_spec.rb index 1226e1dc2ed..bd163f4a109 100644 --- a/spec/features/projects/pages/user_edits_settings_spec.rb +++ b/spec/features/projects/pages/user_edits_settings_spec.rb @@ -2,6 +2,8 @@ require 'spec_helper' RSpec.describe 'Pages edits pages settings', :js do + include Spec::Support::Helpers::ModalHelpers + let(:project) { create(:project, pages_https_only: false) } let(:user) { create(:user) } @@ -176,7 +178,6 @@ RSpec.describe 'Pages edits pages settings', :js do describe 'Remove page' do context 'when pages are deployed' do before do - stub_feature_flags(bootstrap_confirmation_modals: false) project.mark_pages_as_deployed end @@ -185,7 +186,7 @@ RSpec.describe 'Pages edits pages settings', :js do expect(page).to have_link('Remove pages') - accept_confirm { click_link 'Remove pages' } + accept_gl_confirm(button_text: 'Remove pages') { click_link 'Remove pages' } expect(page).to have_content('Pages were scheduled for removal') expect(project.reload.pages_deployed?).to be_falsey diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb index 7cb14feabd2..8cf6d5bd29b 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -3,15 +3,16 @@ require 'spec_helper' RSpec.describe 'Pipeline Schedules', :js do + include Spec::Support::Helpers::ModalHelpers + let!(:project) { create(:project, :repository) } let!(:pipeline_schedule) { create(:ci_pipeline_schedule, :nightly, project: project ) } let!(:pipeline) { create(:ci_pipeline, pipeline_schedule: pipeline_schedule) } let(:scope) { nil } let!(:user) { create(:user) } - context 'logged in as the pipeline scheduler owner' do + context 'logged in as the pipeline schedule owner' do before do - stub_feature_flags(bootstrap_confirmation_modals: false) project.add_developer(user) pipeline_schedule.update!(owner: user) gitlab_sign_in(user) @@ -81,7 +82,6 @@ RSpec.describe 'Pipeline Schedules', :js do context 'logged in as a project maintainer' do before do - stub_feature_flags(bootstrap_confirmation_modals: false) project.add_maintainer(user) gitlab_sign_in(user) end @@ -117,7 +117,9 @@ RSpec.describe 'Pipeline Schedules', :js do end it 'deletes the pipeline' do - accept_confirm { click_link 'Delete' } + click_link 'Delete' + + accept_gl_confirm(button_text: 'Delete pipeline schedule') expect(page).not_to have_css(".pipeline-schedule-table-row") end diff --git a/spec/features/projects/pipelines/legacy_pipeline_spec.rb b/spec/features/projects/pipelines/legacy_pipeline_spec.rb index a29cef393a8..db6feecba03 100644 --- a/spec/features/projects/pipelines/legacy_pipeline_spec.rb +++ b/spec/features/projects/pipelines/legacy_pipeline_spec.rb @@ -1070,4 +1070,202 @@ RSpec.describe 'Pipeline', :js do end end end + + describe 'GET /:project/-/pipelines/:id/builds' do + include_context 'pipeline builds' + + let_it_be(:project) { create(:project, :repository) } + + let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) } + + before do + visit builds_project_pipeline_path(project, pipeline) + end + + it 'shows a list of jobs' do + expect(page).to have_content('Test') + expect(page).to have_content(build_passed.id) + expect(page).to have_content('Deploy') + expect(page).to have_content(build_failed.id) + expect(page).to have_content(build_running.id) + expect(page).to have_content(build_external.id) + expect(page).to have_content('Retry') + expect(page).to have_content('Cancel running') + expect(page).to have_button('Play') + end + + context 'page tabs' do + it 'shows Pipeline, Jobs and DAG tabs with link' do + expect(page).to have_link('Pipeline') + expect(page).to have_link('Jobs') + expect(page).to have_link('Needs') + end + + it 'shows counter in Jobs tab' do + expect(page.find('.js-builds-counter').text).to eq(pipeline.total_size.to_s) + end + end + + context 'retrying jobs' do + it { expect(page).not_to have_content('retried') } + + context 'when retrying' do + before do + find('[data-testid="retry"]', match: :first).click + end + + it 'does not show a "Retry" button', :sidekiq_might_not_need_inline do + expect(page).not_to have_content('Retry') + end + end + end + + context 'canceling jobs' do + it { expect(page).not_to have_selector('.ci-canceled') } + + context 'when canceling' do + before do + click_on 'Cancel running' + end + + it 'does not show a "Cancel running" button', :sidekiq_might_not_need_inline do + expect(page).not_to have_content('Cancel running') + end + end + end + + context 'playing manual job' do + before do + within '[data-testid="jobs-tab-table"]' do + click_button('Play') + + wait_for_requests + end + end + + it { expect(build_manual.reload).to be_pending } + end + + context 'when user unschedules a delayed job' do + before do + within '[data-testid="jobs-tab-table"]' do + click_button('Unschedule') + end + end + + it 'unschedules the delayed job and shows play button as a manual job' do + expect(page).to have_button('Play') + expect(page).not_to have_button('Unschedule') + end + end + end + + describe 'GET /:project/-/pipelines/:id/failures' do + let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: '1234') } + let(:pipeline_failures_page) { failures_project_pipeline_path(project, pipeline) } + let!(:failed_build) { create(:ci_build, :failed, pipeline: pipeline) } + + subject { visit pipeline_failures_page } + + context 'with failed build' do + before do + failed_build.trace.set('4 examples, 1 failure') + end + + it 'lists failed builds' do + subject + + expect(page).to have_content(failed_build.name) + expect(page).to have_content(failed_build.stage) + end + + it 'shows build failure logs' do + subject + + expect(page).to have_content('4 examples, 1 failure') + end + + it 'shows the failure reason' do + subject + + expect(page).to have_content('There is an unknown failure, please try again') + end + + context 'when user does not have permission to retry build' do + it 'shows retry button for failed build' do + subject + + page.within(find('#js-tab-failures', match: :first)) do + expect(page).not_to have_button('Retry') + end + end + end + + context 'when user does have permission to retry build' do + before do + create(:protected_branch, :developers_can_merge, + name: pipeline.ref, project: project) + end + + it 'shows retry button for failed build' do + subject + + page.within(find('#js-tab-failures', match: :first)) do + expect(page).to have_button('Retry') + end + end + end + end + + context 'when missing build logs' do + it 'lists failed builds' do + subject + + expect(page).to have_content(failed_build.name) + expect(page).to have_content(failed_build.stage) + end + + it 'does not show log' do + subject + + expect(page).to have_content('No job log') + end + end + + context 'without permission to access builds' do + let(:role) { :guest } + + before do + project.update!(public_builds: false) + end + + context 'when accessing failed jobs page' do + it 'renders a 404 page' do + requests = inspect_requests { subject } + + expect(page).to have_title('Not Found') + expect(requests.first.status_code).to eq(404) + end + end + end + + context 'without failures' do + before do + failed_build.update!(status: :success) + end + + it 'does not show the failure tab' do + subject + + expect(page).not_to have_content('Failed Jobs') + end + + it 'displays the pipeline graph' do + subject + + expect(page).to have_current_path(pipeline_path(pipeline), ignore_query: true) + expect(page).to have_selector('.js-pipeline-graph') + end + end + end end diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index 9eda05f695d..a83d4191f38 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -414,16 +414,6 @@ RSpec.describe 'Pipeline', :js do expect(page).to have_selector('button[aria-label="Retry downstream pipeline"]') end - context 'and the FF downstream_retry_action is disabled' do - before do - stub_feature_flags(downstream_retry_action: false) - end - - it 'does not show the retry action' do - expect(page).not_to have_selector('button[aria-label="Retry downstream pipeline"]') - end - end - context 'when retrying' do before do find('button[aria-label="Retry downstream pipeline"]').click @@ -508,8 +498,7 @@ RSpec.describe 'Pipeline', :js do end it 'shows counter in Jobs tab' do - skip('Enable in jobs `pipeline_tabs_vue` MR') - expect(page.find('.js-builds-counter').text).to eq(pipeline.total_size.to_s) + expect(page.find('[data-testid="builds-counter"]').text).to eq(pipeline.total_size.to_s) end context 'without permission to access builds' do @@ -889,7 +878,6 @@ RSpec.describe 'Pipeline', :js do describe 'GET /:project/-/pipelines/:id/builds' do before do - stub_feature_flags(pipeline_tabs_vue: false) visit builds_project_pipeline_path(project, pipeline) end @@ -1042,7 +1030,6 @@ RSpec.describe 'Pipeline', :js do let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) } before do - stub_feature_flags(pipeline_tabs_vue: false) visit builds_project_pipeline_path(project, pipeline) end @@ -1066,8 +1053,7 @@ RSpec.describe 'Pipeline', :js do end it 'shows counter in Jobs tab' do - skip('unskip when jobs tab is implemented with ff `pipeline_tabs_vue`') - expect(page.find('.js-builds-counter').text).to eq(pipeline.total_size.to_s) + expect(page.find('[data-testid="builds-counter"]').text).to eq(pipeline.total_size.to_s) end end @@ -1130,10 +1116,6 @@ RSpec.describe 'Pipeline', :js do let(:pipeline_failures_page) { failures_project_pipeline_path(project, pipeline) } let!(:failed_build) { create(:ci_build, :failed, pipeline: pipeline) } - before do - stub_feature_flags(pipeline_tabs_vue: false) - end - subject { visit pipeline_failures_page } context 'with failed build' do @@ -1160,42 +1142,11 @@ RSpec.describe 'Pipeline', :js do expect(page).to have_content('There is an unknown failure, please try again') end - context 'when failed_jobs_tab_vue feature flag is disabled' do - before do - stub_feature_flags(failed_jobs_tab_vue: false) - end - - context 'when user does not have permission to retry build' do - it 'shows retry button for failed build' do - subject - - page.within(find('.build-failures', match: :first)) do - expect(page).not_to have_link('Retry') - end - end - end - - context 'when user does have permission to retry build' do - before do - create(:protected_branch, :developers_can_merge, - name: pipeline.ref, project: project) - end - - it 'shows retry button for failed build' do - subject - - page.within(find('.build-failures', match: :first)) do - expect(page).to have_link('Retry') - end - end - end - end - context 'when user does not have permission to retry build' do it 'shows retry button for failed build' do subject - page.within(find('#js-tab-failures', match: :first)) do + page.within(find('[data-testid="tab-failures"]', match: :first)) do expect(page).not_to have_button('Retry') end end @@ -1210,7 +1161,7 @@ RSpec.describe 'Pipeline', :js do it 'shows retry button for failed build' do subject - page.within(find('#js-tab-failures', match: :first)) do + page.within(find('[data-testid="tab-failures"]', match: :first)) do expect(page).to have_button('Retry') end end @@ -1255,7 +1206,6 @@ RSpec.describe 'Pipeline', :js do end it 'does not show the failure tab' do - skip('unskip when the failure tab has been implemented in ff `pipeline_tabs_vue`') subject expect(page).not_to have_content('Failed Jobs') diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index a18bf7c5caf..785edc69623 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -311,7 +311,6 @@ RSpec.describe 'Pipelines', :js do end before do - stub_feature_flags(bootstrap_confirmation_modals: false) visit_project_pipelines end diff --git a/spec/features/projects/releases/user_views_edit_release_spec.rb b/spec/features/projects/releases/user_views_edit_release_spec.rb index f08f5529472..6551b254643 100644 --- a/spec/features/projects/releases/user_views_edit_release_spec.rb +++ b/spec/features/projects/releases/user_views_edit_release_spec.rb @@ -30,10 +30,12 @@ RSpec.describe 'User edits Release', :js do it 'renders the breadcrumbs' do within('.breadcrumbs') do - expect(page).to have_content("#{project.creator.name} #{project.name} Edit Release") + expect(page).to have_content("#{project.creator.name} #{project.name} Releases #{release.name} Edit Release") expect(page).to have_link(project.creator.name, href: user_path(project.creator)) expect(page).to have_link(project.name, href: project_path(project)) + expect(page).to have_link(_('Releases'), href: project_releases_path(project)) + expect(page).to have_link(release.name, href: project_release_path(project, release)) expect(page).to have_link('Edit Release', href: edit_project_release_path(project, release)) end end diff --git a/spec/features/projects/settings/access_tokens_spec.rb b/spec/features/projects/settings/access_tokens_spec.rb index 122bf267021..88f9a50b093 100644 --- a/spec/features/projects/settings/access_tokens_spec.rb +++ b/spec/features/projects/settings/access_tokens_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'Project > Settings > Access Tokens', :js do + include Spec::Support::Helpers::ModalHelpers + let_it_be(:user) { create(:user) } let_it_be(:bot_user) { create(:user, :project_bot) } let_it_be(:group) { create(:group) } @@ -14,7 +16,6 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do end before do - stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end @@ -24,6 +25,11 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do create(:personal_access_token, user: bot_user) end + def role_dropdown_options + role_dropdown = page.find_by_id('resource_access_token_access_level') + role_dropdown.all('option').map(&:text) + end + context 'when user is not a project maintainer' do before do project.add_developer(user) @@ -33,37 +39,68 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do end describe 'token creation' do - it_behaves_like 'resource access tokens creation', 'project' + context 'when user is a project owner' do + before do + project.add_owner(user) + end - context 'when token creation is not allowed' do - it_behaves_like 'resource access tokens creation disallowed', 'Project access token creation is disabled in this group. You can still use and manage existing tokens.' + it_behaves_like 'resource access tokens creation', 'project' - context 'with a project in a personal namespace' do - let(:personal_project) { create(:project) } + it 'shows Owner option' do + visit resource_settings_access_tokens_path - before do - personal_project.add_maintainer(user) - end + expect(role_dropdown_options).to include('Owner') + end + end - it 'shows access token creation form and text' do - visit project_settings_access_tokens_path(personal_project) + context 'when user is a project maintainer' do + before_all do + project.add_maintainer(user) + end + + it_behaves_like 'resource access tokens creation', 'project' + + it 'does not show Owner option for a maintainer' do + visit resource_settings_access_tokens_path - expect(page).to have_selector('#new_resource_access_token') - expect(page).to have_text('Generate project access tokens scoped to this project for your applications that need access to the GitLab API.') - end + expect(role_dropdown_options).not_to include('Owner') end end end - describe 'active tokens' do - let!(:resource_access_token) { create_resource_access_token } + context 'when token creation is not allowed' do + it_behaves_like 'resource access tokens creation disallowed', 'Project access token creation is disabled in this group. You can still use and manage existing tokens.' - it_behaves_like 'active resource access tokens' + context 'with a project in a personal namespace' do + let(:personal_project) { create(:project) } + + before do + personal_project.add_maintainer(user) + end + + it 'shows access token creation form and text' do + visit project_settings_access_tokens_path(personal_project) + + expect(page).to have_selector('#js-new-access-token-form') + end + end end - describe 'inactive tokens' do - let!(:resource_access_token) { create_resource_access_token } + describe 'viewing tokens' do + before_all do + project.add_maintainer(user) + end + + describe 'active tokens' do + let!(:resource_access_token) { create_resource_access_token } + + it_behaves_like 'active resource access tokens' + end - it_behaves_like 'inactive resource access tokens', 'This project has no active access tokens.' + describe 'inactive tokens' do + let!(:resource_access_token) { create_resource_access_token } + + it_behaves_like 'inactive resource access tokens', 'This project has no active access tokens.' + end end end diff --git a/spec/features/projects/settings/branch_rules_settings_spec.rb b/spec/features/projects/settings/branch_rules_settings_spec.rb new file mode 100644 index 00000000000..5cc35f108b5 --- /dev/null +++ b/spec/features/projects/settings/branch_rules_settings_spec.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Projects > Settings > Repository > Branch rules settings' do + let(:project) { create(:project_empty_repo) } + let(:user) { create(:user) } + let(:role) { :developer } + + subject(:request) { visit project_settings_repository_branch_rules_path(project) } + + before do + project.add_role(user, role) + sign_in(user) + end + + context 'for developer' do + let(:role) { :developer } + + it 'is not allowed to view' do + request + + expect(page).to have_gitlab_http_status(:not_found) + end + end + + context 'for maintainer' do + let(:role) { :maintainer } + + context 'Branch rules', :js do + it 'renders branch rules page' do + request + + expect(page).to have_content('Branch rules') + end + end + + context 'branch_rules feature flag disabled' do + it 'does not render branch rules content' do + stub_feature_flags(branch_rules: false) + request + + expect(page).to have_gitlab_http_status(:not_found) + end + end + end +end diff --git a/spec/features/projects/settings/packages_settings_spec.rb b/spec/features/projects/settings/packages_settings_spec.rb index 057e6b635fe..1c2b0faa215 100644 --- a/spec/features/projects/settings/packages_settings_spec.rb +++ b/spec/features/projects/settings/packages_settings_spec.rb @@ -11,6 +11,7 @@ RSpec.describe 'Projects > Settings > Packages', :js do sign_in(user) stub_config(packages: { enabled: packages_enabled }) + stub_feature_flags(package_registry_access_level: package_registry_access_level) visit edit_project_path(project) end @@ -18,14 +19,31 @@ RSpec.describe 'Projects > Settings > Packages', :js do context 'Packages enabled in config' do let(:packages_enabled) { true } - it 'displays the packages toggle button' do - expect(page).to have_selector('[data-testid="toggle-label"]', text: 'Packages') - expect(page).to have_selector('input[name="project[packages_enabled]"] + button', visible: true) + context 'with feature flag disabled' do + let(:package_registry_access_level) { false } + + it 'displays the packages toggle button' do + expect(page).to have_selector('[data-testid="toggle-label"]', text: 'Packages') + expect(page).to have_selector('input[name="project[packages_enabled]"] + button', visible: true) + end + end + + context 'with feature flag enabled' do + let(:package_registry_access_level) { true } + + it 'displays the packages access level setting' do + expect(page).to have_selector('[data-testid="package-registry-access-level"] > label', text: 'Package registry') + expect(page).to have_selector( + 'input[name="project[project_feature_attributes][package_registry_access_level]"]', + visible: false + ) + end end end context 'Packages disabled in config' do let(:packages_enabled) { false } + let(:package_registry_access_level) { false } it 'does not show up in UI' do expect(page).not_to have_selector('[data-testid="toggle-label"]', text: 'Packages') diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb index 4e1b55d3d70..cfdd3d9224d 100644 --- a/spec/features/projects/settings/repository_settings_spec.rb +++ b/spec/features/projects/settings/repository_settings_spec.rb @@ -39,6 +39,22 @@ RSpec.describe 'Projects > Settings > Repository settings' do end end + context 'Branch rules', :js do + it 'renders branch rules settings' do + visit project_settings_repository_path(project) + expect(page).to have_content('Branch rules') + end + + context 'branch_rules feature flag disabled', :js do + it 'does not render branch rules settings' do + stub_feature_flags(branch_rules: false) + visit project_settings_repository_path(project) + + expect(page).not_to have_content('Branch rules') + end + end + end + context 'Deploy Keys', :js do let_it_be(:private_deploy_key) { create(:deploy_key, title: 'private_deploy_key', public: false) } let_it_be(:public_deploy_key) { create(:another_deploy_key, title: 'public_deploy_key', public: true) } diff --git a/spec/features/projects/settings/user_searches_in_settings_spec.rb b/spec/features/projects/settings/user_searches_in_settings_spec.rb index 44b5464a1b0..7ed96d01189 100644 --- a/spec/features/projects/settings/user_searches_in_settings_spec.rb +++ b/spec/features/projects/settings/user_searches_in_settings_spec.rb @@ -7,7 +7,6 @@ RSpec.describe 'User searches project settings', :js do let_it_be(:project) { create(:project, :repository, namespace: user.namespace, pages_https_only: false) } before do - stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end |