diff options
Diffstat (limited to 'spec/features')
82 files changed, 1428 insertions, 418 deletions
diff --git a/spec/features/admin/admin_deploy_keys_spec.rb b/spec/features/admin/admin_deploy_keys_spec.rb index 7ce6cce0a5c..c0b6995a84a 100644 --- a/spec/features/admin/admin_deploy_keys_spec.rb +++ b/spec/features/admin/admin_deploy_keys_spec.rb @@ -18,7 +18,7 @@ RSpec.describe 'admin deploy keys', type: :feature do describe 'create new deploy key' do before do visit admin_deploy_keys_path - click_link 'New Deploy Key' + click_link 'New deploy key' end it 'creates new deploy key' do diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb index a871e370ba2..d5f595894d6 100644 --- a/spec/features/admin/admin_groups_spec.rb +++ b/spec/features/admin/admin_groups_spec.rb @@ -24,14 +24,23 @@ feature 'Admin Groups', feature: true do it 'creates new group' do visit admin_groups_path - click_link "New Group" - fill_in 'group_path', with: 'gitlab' - fill_in 'group_description', with: 'Group description' + click_link "New group" + path_component = 'gitlab' + group_name = 'GitLab group name' + group_description = 'Description of group for GitLab' + fill_in 'group_path', with: path_component + fill_in 'group_name', with: group_name + fill_in 'group_description', with: group_description click_button "Create group" - expect(current_path).to eq admin_group_path(Group.find_by(path: 'gitlab')) - expect(page).to have_content('Group: gitlab') - expect(page).to have_content('Group description') + expect(current_path).to eq admin_group_path(Group.find_by(path: path_component)) + content = page.find('div#content-body') + h3_texts = content.all('h3').collect(&:text).join("\n") + expect(h3_texts).to match group_name + li_texts = content.all('li').collect(&:text).join("\n") + expect(li_texts).to match group_name + expect(li_texts).to match path_component + expect(li_texts).to match group_description end scenario 'shows the visibility level radio populated with the default value' do @@ -39,6 +48,15 @@ feature 'Admin Groups', feature: true do expect_selected_visibility(internal) end + + scenario 'when entered in group path, it auto filled the group name', js: true do + visit admin_groups_path + click_link "New group" + group_path = 'gitlab' + fill_in 'group_path', with: group_path + name_field = find('input#group_name') + expect(name_field.value).to eq group_path + end end describe 'show a group' do @@ -59,6 +77,17 @@ feature 'Admin Groups', feature: true do expect_selected_visibility(group.visibility_level) end + + scenario 'edit group path does not change group name', js: true do + group = create(:group, :private) + + visit admin_group_edit_path(group) + name_field = find('input#group_name') + original_name = name_field.value + fill_in 'group_path', with: 'this-new-path' + + expect(name_field.value).to eq original_name + end end describe 'add user into a group', js: true do diff --git a/spec/features/admin/admin_health_check_spec.rb b/spec/features/admin/admin_health_check_spec.rb index f7e49a56deb..523afa2318f 100644 --- a/spec/features/admin/admin_health_check_spec.rb +++ b/spec/features/admin/admin_health_check_spec.rb @@ -2,7 +2,6 @@ require 'spec_helper' feature "Admin Health Check", feature: true do include StubENV - include WaitForAjax before do stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') @@ -24,11 +23,12 @@ feature "Admin Health Check", feature: true do expect(page).to have_selector('#health-check-token', text: token) end - describe 'reload access token', js: true do + describe 'reload access token' do it 'changes the access token' do orig_token = current_application_settings.health_check_access_token click_button 'Reset health check access token' - wait_for_ajax + + expect(page).to have_content('New health check access token has been generated!') expect(find('#health-check-token').text).not_to eq orig_token end end diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb index 570c374a89b..fb519a9bf12 100644 --- a/spec/features/admin/admin_hooks_spec.rb +++ b/spec/features/admin/admin_hooks_spec.rb @@ -33,7 +33,7 @@ describe "Admin::Hooks", feature: true do fill_in 'hook_url', with: url check 'Enable SSL verification' - expect { click_button 'Add System Hook' }.to change(SystemHook, :count).by(1) + expect { click_button 'Add system hook' }.to change(SystemHook, :count).by(1) expect(page).to have_content 'SSL Verification: enabled' expect(current_path).to eq(admin_hooks_path) expect(page).to have_content(url) @@ -44,7 +44,7 @@ describe "Admin::Hooks", feature: true do before do WebMock.stub_request(:post, @system_hook.url) visit admin_hooks_path - click_link "Test Hook" + click_link "Test hook" end it { expect(current_path).to eq(admin_hooks_path) } diff --git a/spec/features/admin/admin_manage_applications_spec.rb b/spec/features/admin/admin_manage_applications_spec.rb index c2c618b5659..0079125889b 100644 --- a/spec/features/admin/admin_manage_applications_spec.rb +++ b/spec/features/admin/admin_manage_applications_spec.rb @@ -8,7 +8,7 @@ RSpec.describe 'admin manage applications', feature: true do it do visit admin_applications_path - click_on 'New Application' + click_on 'New application' expect(page).to have_content('New application') fill_in :doorkeeper_application_name, with: 'test' diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb index ff23d486355..0fb4baeb71c 100644 --- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb +++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb @@ -30,7 +30,7 @@ describe 'Admin > Users > Impersonation Tokens', feature: true, js: true do check "api" check "read_user" - expect { click_on "Create Impersonation Token" }.to change { PersonalAccessTokensFinder.new(impersonation: true).execute.count } + expect { click_on "Create impersonation token" }.to change { PersonalAccessTokensFinder.new(impersonation: true).execute.count } expect(active_impersonation_tokens).to have_text(name) expect(active_impersonation_tokens).to have_text('In') expect(active_impersonation_tokens).to have_text('api') diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb index c0807b8c507..f6c3bc6a58d 100644 --- a/spec/features/admin/admin_users_spec.rb +++ b/spec/features/admin/admin_users_spec.rb @@ -223,7 +223,7 @@ describe "Admin::Users", feature: true do it "changes user entry" do user.reload expect(user.name).to eq('Big Bang') - expect(user.is_admin?).to be_truthy + expect(user.admin?).to be_truthy expect(user.password_expires_at).to be <= Time.now end end diff --git a/spec/features/auto_deploy_spec.rb b/spec/features/auto_deploy_spec.rb index 009e9c6b04c..6f36c74c911 100644 --- a/spec/features/auto_deploy_spec.rb +++ b/spec/features/auto_deploy_spec.rb @@ -56,7 +56,7 @@ describe 'Auto deploy' do click_on 'OpenShift' end wait_for_ajax - click_button 'Commit Changes' + click_button 'Commit changes' expect(page).to have_content('New Merge Request From auto-deploy into master') end diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb index 1c0f97d8a1c..248c31115ad 100644 --- a/spec/features/boards/add_issues_modal_spec.rb +++ b/spec/features/boards/add_issues_modal_spec.rb @@ -145,7 +145,7 @@ describe 'Issue Boards add issue modal', :feature, :js do context 'selecing issues' do it 'selects single issue' do page.within('.add-issues-modal') do - first('.card').click + first('.card .card-number').click page.within('.nav-links') do expect(page).to have_content('Selected issues 1') @@ -155,7 +155,7 @@ describe 'Issue Boards add issue modal', :feature, :js do it 'changes button text' do page.within('.add-issues-modal') do - first('.card').click + first('.card .card-number').click expect(first('.add-issues-footer .btn')).to have_content('Add 1 issue') end @@ -163,7 +163,7 @@ describe 'Issue Boards add issue modal', :feature, :js do it 'changes button text with plural' do page.within('.add-issues-modal') do - all('.card').each do |el| + all('.card .card-number').each do |el| el.click end @@ -173,7 +173,7 @@ describe 'Issue Boards add issue modal', :feature, :js do it 'shows only selected issues on selected tab' do page.within('.add-issues-modal') do - first('.card').click + first('.card .card-number').click click_link 'Selected issues' @@ -203,7 +203,7 @@ describe 'Issue Boards add issue modal', :feature, :js do it 'selects all that arent already selected' do page.within('.add-issues-modal') do - first('.card').click + first('.card .card-number').click expect(page).to have_selector('.is-active', count: 1) @@ -215,11 +215,11 @@ describe 'Issue Boards add issue modal', :feature, :js do it 'unselects from selected tab' do page.within('.add-issues-modal') do - first('.card').click + first('.card .card-number').click click_link 'Selected issues' - first('.card').click + first('.card .card-number').click expect(page).not_to have_selector('.is-active') end @@ -229,7 +229,7 @@ describe 'Issue Boards add issue modal', :feature, :js do context 'adding issues' do it 'adds to board' do page.within('.add-issues-modal') do - first('.card').click + first('.card .card-number').click click_button 'Add 1 issue' end @@ -241,7 +241,7 @@ describe 'Issue Boards add issue modal', :feature, :js do it 'adds to second list' do page.within('.add-issues-modal') do - first('.card').click + first('.card .card-number').click click_button planning.title diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index e168585534d..30ad169e30e 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -590,7 +590,7 @@ describe 'Issue Boards', feature: true, js: true do end def click_filter_link(link_text) - page.within('.filtered-search-input-container') do + page.within('.filtered-search-box') do expect(page).to have_button(link_text) click_button(link_text) diff --git a/spec/features/boards/keyboard_shortcut_spec.rb b/spec/features/boards/keyboard_shortcut_spec.rb index a5fc766401f..a9cc6c49f8e 100644 --- a/spec/features/boards/keyboard_shortcut_spec.rb +++ b/spec/features/boards/keyboard_shortcut_spec.rb @@ -14,7 +14,7 @@ describe 'Issue Boards shortcut', feature: true, js: true do end it 'takes user to issue board index' do - find('body').native.send_keys('gl') + find('body').native.send_keys('gb') expect(page).to have_selector('.boards-list') wait_for_vue_resource diff --git a/spec/features/boards/modal_filter_spec.rb b/spec/features/boards/modal_filter_spec.rb index e2281a7da55..4a4c13e79c8 100644 --- a/spec/features/boards/modal_filter_spec.rb +++ b/spec/features/boards/modal_filter_spec.rb @@ -219,7 +219,7 @@ describe 'Issue Boards add issue modal filtering', :feature, :js do end def click_filter_link(link_text) - page.within('.add-issues-modal .filtered-search-input-container') do + page.within('.add-issues-modal .filtered-search-box') do expect(page).to have_button(link_text) click_button(link_text) diff --git a/spec/features/container_registry_spec.rb b/spec/features/container_registry_spec.rb index 203e55a36f2..b86609e07c5 100644 --- a/spec/features/container_registry_spec.rb +++ b/spec/features/container_registry_spec.rb @@ -1,45 +1,61 @@ require 'spec_helper' describe "Container Registry" do + let(:user) { create(:user) } let(:project) { create(:empty_project) } - let(:repository) { project.container_registry_repository } - let(:tag_name) { 'latest' } - let(:tags) { [tag_name] } + + let(:container_repository) do + create(:container_repository, name: 'my/image') + end before do - login_as(:user) - project.team << [@user, :developer] - stub_container_registry_tags(*tags) + login_as(user) + project.add_developer(user) stub_container_registry_config(enabled: true) - allow(Auth::ContainerRegistryAuthenticationService).to receive(:full_access_token).and_return('token') + stub_container_registry_tags(repository: :any, tags: []) end - describe 'GET /:project/container_registry' do + context 'when there are no image repositories' do + scenario 'user visits container registry main page' do + visit_container_registry + + expect(page).to have_content 'No container image repositories' + end + end + + context 'when there are image repositories' do before do - visit namespace_project_container_registry_index_path(project.namespace, project) + stub_container_registry_tags(repository: %r{my/image}, tags: %w[latest]) + project.container_repositories << container_repository end - context 'when no tags' do - let(:tags) { [] } + scenario 'user wants to see multi-level container repository' do + visit_container_registry - it { expect(page).to have_content('No images in Container Registry for this project') } + expect(page).to have_content('my/image') end - context 'when there are tags' do - it { expect(page).to have_content(tag_name) } - it { expect(page).to have_content('d7a513a66') } - end - end + scenario 'user removes entire container repository' do + visit_container_registry - describe 'DELETE /:project/container_registry/tag' do - before do - visit namespace_project_container_registry_index_path(project.namespace, project) + expect_any_instance_of(ContainerRepository) + .to receive(:delete_tags!).and_return(true) + + click_on 'Remove repository' end - it do - expect_any_instance_of(::ContainerRegistry::Tag).to receive(:delete).and_return(true) + scenario 'user removes a specific tag from container repository' do + visit_container_registry - click_on 'Remove' + expect_any_instance_of(ContainerRegistry::Tag) + .to receive(:delete).and_return(true) + + click_on 'Remove tag' end end + + def visit_container_registry + visit namespace_project_container_registry_index_path( + project.namespace, project) + end end diff --git a/spec/features/dashboard/group_spec.rb b/spec/features/dashboard/group_spec.rb index d5f8470fab0..1d4b86ed4b4 100644 --- a/spec/features/dashboard/group_spec.rb +++ b/spec/features/dashboard/group_spec.rb @@ -5,16 +5,18 @@ RSpec.describe 'Dashboard Group', feature: true do login_as(:user) end - it 'creates new grpup' do + it 'creates new group', js: true do visit dashboard_groups_path - click_link 'New Group' + click_link 'New group' + new_path = 'Samurai' + new_description = 'Tokugawa Shogunate' - fill_in 'group_path', with: 'Samurai' - fill_in 'group_description', with: 'Tokugawa Shogunate' + fill_in 'group_path', with: new_path + fill_in 'group_description', with: new_description click_button 'Create group' - expect(current_path).to eq group_path(Group.find_by(name: 'Samurai')) - expect(page).to have_content('Samurai') - expect(page).to have_content('Tokugawa Shogunate') + expect(current_path).to eq group_path(Group.find_by(name: new_path)) + expect(page).to have_content(new_path) + expect(page).to have_content(new_description) end end diff --git a/spec/features/dashboard/issuables_counter_spec.rb b/spec/features/dashboard/issuables_counter_spec.rb index a1718912fc6..4fca7577e74 100644 --- a/spec/features/dashboard/issuables_counter_spec.rb +++ b/spec/features/dashboard/issuables_counter_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'Navigation bar counter', feature: true, js: true, caching: true do +describe 'Navigation bar counter', feature: true, caching: true do let(:user) { create(:user) } let(:project) { create(:empty_project, namespace: user.namespace) } let(:issue) { create(:issue, project: project) } @@ -13,33 +13,48 @@ describe 'Navigation bar counter', feature: true, js: true, caching: true do end it 'reflects dashboard issues count' do - visit issues_dashboard_path + visit issues_path expect_counters('issues', '1') issue.update(assignee: nil) - visit issues_dashboard_path - expect_counters('issues', '1') + Timecop.travel(3.minutes.from_now) do + visit issues_path + + expect_counters('issues', '0') + end end it 'reflects dashboard merge requests count' do - visit merge_requests_dashboard_path + visit merge_requests_path expect_counters('merge_requests', '1') merge_request.update(assignee: nil) - visit merge_requests_dashboard_path - expect_counters('merge_requests', '1') + Timecop.travel(3.minutes.from_now) do + visit merge_requests_path + + expect_counters('merge_requests', '0') + end + end + + def issues_path + issues_dashboard_path(assignee_id: user.id) + end + + def merge_requests_path + merge_requests_dashboard_path(assignee_id: user.id) end def expect_counters(issuable_type, count) - dashboard_count = find('li.active') - find('.global-dropdown-toggle').click + dashboard_count = find('.nav-links li.active') nav_count = find(".dashboard-shortcuts-#{issuable_type}") + header_count = find(".header-content .#{issuable_type.tr('_', '-')}-count") - expect(nav_count).to have_content(count) expect(dashboard_count).to have_content(count) + expect(nav_count).to have_content(count) + expect(header_count).to have_content(count) end end diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb new file mode 100644 index 00000000000..508ca38d7e5 --- /dev/null +++ b/spec/features/dashboard/merge_requests_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +describe 'Dashboard Merge Requests' do + let(:current_user) { create :user } + let(:project) do + create(:empty_project) do |project| + project.add_master(current_user) + end + end + + before do + login_as(current_user) + end + + it 'should show an empty state' do + visit merge_requests_dashboard_path(assignee_id: current_user.id) + + expect(page).to have_selector('.empty-state') + end + + context 'if there are merge requests' do + before do + create(:merge_request, assignee: current_user, source_project: project) + + visit merge_requests_dashboard_path(assignee_id: current_user.id) + end + + it 'should not show an empty state' do + expect(page).not_to have_selector('.empty-state') + end + end +end diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb index c4e58d14f75..f1789fc9d43 100644 --- a/spec/features/dashboard/projects_spec.rb +++ b/spec/features/dashboard/projects_spec.rb @@ -7,7 +7,6 @@ RSpec.describe 'Dashboard Projects', feature: true do before do project.team << [user, :developer] login_as user - visit dashboard_projects_path end it 'shows the project the user in a member of in the list' do @@ -15,15 +14,19 @@ RSpec.describe 'Dashboard Projects', feature: true do expect(page).to have_content('awesome stuff') end - describe "with a pipeline" do - let(:pipeline) { create(:ci_pipeline, :success, project: project, sha: project.commit.sha) } + describe "with a pipeline", redis: true do + let!(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit.sha) } before do - pipeline + # Since the cache isn't updated when a new pipeline is created + # we need the pipeline to advance in the pipeline since the cache was created + # by visiting the login page. + pipeline.succeed end it 'shows that the last pipeline passed' do visit dashboard_projects_path + expect(page).to have_xpath("//a[@href='#{pipelines_namespace_project_commit_path(project.namespace, project, project.commit)}']") end end diff --git a/spec/features/dashboard/shortcuts_spec.rb b/spec/features/dashboard/shortcuts_spec.rb index 3642c0bfb5b..4c9adcabe34 100644 --- a/spec/features/dashboard/shortcuts_spec.rb +++ b/spec/features/dashboard/shortcuts_spec.rb @@ -1,31 +1,49 @@ require 'spec_helper' feature 'Dashboard shortcuts', feature: true, js: true do - before do - login_as :user - visit dashboard_projects_path - end + context 'logged in' do + before do + login_as :user + visit root_dashboard_path + end + + scenario 'Navigate to tabs' do + find('body').native.send_keys([:shift, 'P']) + + check_page_title('Projects') + + find('body').native.send_key([:shift, 'I']) + + check_page_title('Issues') - scenario 'Navigate to tabs' do - find('body').native.send_key('g') - find('body').native.send_key('p') + find('body').native.send_key([:shift, 'M']) + + check_page_title('Merge Requests') + + find('body').native.send_keys([:shift, 'T']) + + check_page_title('Todos') + end + end - check_page_title('Projects') + context 'logged out' do + before do + visit explore_root_path + end - find('body').native.send_key('g') - find('body').native.send_key('i') + scenario 'Navigate to tabs' do + find('body').native.send_keys([:shift, 'P']) - check_page_title('Issues') + expect(page).to have_content('No projects found') - find('body').native.send_key('g') - find('body').native.send_key('m') + find('body').native.send_keys([:shift, 'G']) - check_page_title('Merge Requests') + expect(page).to have_content('No public groups') - find('body').native.send_key('g') - find('body').native.send_key('t') + find('body').native.send_keys([:shift, 'S']) - check_page_title('Todos') + expect(page).to have_selector('.snippets-list-holder') + end end def check_page_title(title) diff --git a/spec/features/discussion_comments/commit_spec.rb b/spec/features/discussion_comments/commit_spec.rb new file mode 100644 index 00000000000..96e0b78f6b9 --- /dev/null +++ b/spec/features/discussion_comments/commit_spec.rb @@ -0,0 +1,18 @@ +require 'spec_helper' + +describe 'Discussion Comments Merge Request', :feature, :js do + include RepoHelpers + + let(:user) { create(:user) } + let(:project) { create(:project) } + let(:merge_request) { create(:merge_request, source_project: project) } + + before do + project.add_master(user) + login_as(user) + + visit namespace_project_commit_path(project.namespace, project, sample_commit.id) + end + + it_behaves_like 'discussion comments', 'commit' +end diff --git a/spec/features/discussion_comments/issue_spec.rb b/spec/features/discussion_comments/issue_spec.rb new file mode 100644 index 00000000000..ccc9efccd18 --- /dev/null +++ b/spec/features/discussion_comments/issue_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe 'Discussion Comments Issue', :feature, :js do + let(:user) { create(:user) } + let(:project) { create(:empty_project) } + let(:issue) { create(:issue, project: project) } + + before do + project.add_master(user) + login_as(user) + + visit namespace_project_issue_path(project.namespace, project, issue) + end + + it_behaves_like 'discussion comments', 'issue' +end diff --git a/spec/features/discussion_comments/merge_request_spec.rb b/spec/features/discussion_comments/merge_request_spec.rb new file mode 100644 index 00000000000..f99ebeb9cd9 --- /dev/null +++ b/spec/features/discussion_comments/merge_request_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe 'Discussion Comments Merge Request', :feature, :js do + let(:user) { create(:user) } + let(:project) { create(:project) } + let(:merge_request) { create(:merge_request, source_project: project) } + + before do + project.add_master(user) + login_as(user) + + visit namespace_project_merge_request_path(project.namespace, project, merge_request) + end + + it_behaves_like 'discussion comments', 'merge request' +end diff --git a/spec/features/discussion_comments/snippets_spec.rb b/spec/features/discussion_comments/snippets_spec.rb new file mode 100644 index 00000000000..19a306511b2 --- /dev/null +++ b/spec/features/discussion_comments/snippets_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe 'Discussion Comments Issue', :feature, :js do + let(:user) { create(:user) } + let(:project) { create(:empty_project) } + let(:snippet) { create(:project_snippet, :private, project: project, author: user) } + + before do + project.add_master(user) + login_as(user) + + visit namespace_project_snippet_path(project.namespace, project, snippet) + end + + it_behaves_like 'discussion comments', 'snippet' +end diff --git a/spec/features/gitlab_flavored_markdown_spec.rb b/spec/features/gitlab_flavored_markdown_spec.rb index 84d73d693bc..876f33dd03e 100644 --- a/spec/features/gitlab_flavored_markdown_spec.rb +++ b/spec/features/gitlab_flavored_markdown_spec.rb @@ -48,7 +48,9 @@ describe "GitLab Flavored Markdown", feature: true do end end - describe "for issues" do + describe "for issues", feature: true, js: true do + include WaitForVueResource + before do @other_issue = create(:issue, author: @user, @@ -79,6 +81,14 @@ describe "GitLab Flavored Markdown", feature: true do expect(page).to have_link(fred.to_reference) end + + it "renders updated subject once edited somewhere else in issues#show" do + visit namespace_project_issue_path(project.namespace, project, @issue) + @issue.update(title: "fix #{@other_issue.to_reference} and update") + + wait_for_vue_resource + expect(page).to have_text("fix #{@other_issue.to_reference} and update") + end end describe "for merge requests" do diff --git a/spec/features/groups/empty_states_spec.rb b/spec/features/groups/empty_states_spec.rb new file mode 100644 index 00000000000..fef8e41bffe --- /dev/null +++ b/spec/features/groups/empty_states_spec.rb @@ -0,0 +1,70 @@ +require 'spec_helper' + +feature 'Groups Merge Requests Empty States' do + let(:group) { create(:group) } + let(:user) { create(:group_member, :developer, user: create(:user), group: group ).user } + + before do + login_as(user) + end + + context 'group has a project' do + let(:project) { create(:empty_project, namespace: group) } + + before do + project.add_master(user) + end + + context 'the project has a merge request' do + before do + create(:merge_request, source_project: project) + + visit merge_requests_group_path(group) + end + + it 'should not display an empty state' do + expect(page).not_to have_selector('.empty-state') + end + end + + context 'the project has no merge requests', :js do + before do + visit merge_requests_group_path(group) + end + + it 'should display an empty state' do + expect(page).to have_selector('.empty-state') + end + + it 'should show a new merge request button' do + within '.empty-state' do + expect(page).to have_content('New merge request') + end + end + + it 'the new merge request button opens a project dropdown' do + within '.empty-state' do + find('.new-project-item-select-button').click + end + + expect(page).to have_selector('.ajax-project-dropdown') + end + end + end + + context 'group without a project' do + before do + visit merge_requests_group_path(group) + end + + it 'should display an empty state' do + expect(page).to have_selector('.empty-state') + end + + it 'should not show a new merge request button' do + within '.empty-state' do + expect(page).not_to have_link('New merge request') + end + end + end +end diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb index c90cc06a8f5..3d32c47bf09 100644 --- a/spec/features/groups_spec.rb +++ b/spec/features/groups_spec.rb @@ -83,20 +83,43 @@ feature 'Group', feature: true do end end - describe 'create a nested group' do + describe 'create a nested group', js: true do let(:group) { create(:group, path: 'foo') } - before do - visit subgroups_group_path(group) - click_link 'New Subgroup' + context 'as admin' do + before do + visit subgroups_group_path(group) + click_link 'New Subgroup' + end + + it 'creates a nested group' do + fill_in 'Group path', with: 'bar' + click_button 'Create group' + + expect(current_path).to eq(group_path('foo/bar')) + expect(page).to have_content("Group 'bar' was successfully created.") + end end - it 'creates a nested group' do - fill_in 'Group path', with: 'bar' - click_button 'Create group' + context 'as group owner' do + let(:user) { create(:user) } - expect(current_path).to eq(group_path('foo/bar')) - expect(page).to have_content("Group 'bar' was successfully created.") + before do + group.add_owner(user) + logout + login_as(user) + + visit subgroups_group_path(group) + click_link 'New Subgroup' + end + + it 'creates a nested group' do + fill_in 'Group path', with: 'bar' + click_button 'Create group' + + expect(current_path).to eq(group_path('foo/bar')) + expect(page).to have_content("Group 'bar' was successfully created.") + end end end @@ -130,7 +153,7 @@ feature 'Group', feature: true do end it 'removes group' do - click_link 'Remove Group' + click_link 'Remove group' expect(page).to have_content "scheduled for deletion" end diff --git a/spec/features/issues/award_emoji_spec.rb b/spec/features/issues/award_emoji_spec.rb index 16e453bc328..8e67ab028d7 100644 --- a/spec/features/issues/award_emoji_spec.rb +++ b/spec/features/issues/award_emoji_spec.rb @@ -2,6 +2,7 @@ require 'rails_helper' describe 'Awards Emoji', feature: true do include WaitForAjax + include WaitForVueResource let!(:project) { create(:project, :public) } let!(:user) { create(:user) } @@ -22,10 +23,11 @@ describe 'Awards Emoji', feature: true do # The `heart_tip` emoji is not valid anymore so we need to skip validation issue.award_emoji.build(user: user, name: 'heart_tip').save!(validate: false) visit namespace_project_issue_path(project.namespace, project, issue) + wait_for_vue_resource end # Regression test: https://gitlab.com/gitlab-org/gitlab-ce/issues/29529 - it 'does not shows a 500 page' do + it 'does not shows a 500 page', js: true do expect(page).to have_text(issue.title) end end @@ -35,6 +37,7 @@ describe 'Awards Emoji', feature: true do before do visit namespace_project_issue_path(project.namespace, project, issue) + wait_for_vue_resource end it 'increments the thumbsdown emoji', js: true do diff --git a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb index 572bca3de21..58f897cba3e 100644 --- a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb +++ b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb @@ -4,7 +4,7 @@ feature 'Resolving all open discussions in a merge request from an issue', featu let(:user) { create(:user) } let(:project) { create(:project) } let(:merge_request) { create(:merge_request, source_project: project) } - let!(:discussion) { Discussion.for_diff_notes([create(:diff_note_on_merge_request, noteable: merge_request, project: project)]).first } + let!(:discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion } describe 'as a user with access to the project' do before do diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb index 4dcc56a97d1..3d1a9ed1722 100644 --- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb @@ -194,7 +194,7 @@ describe 'Dropdown assignee', :feature, :js do new_user = create(:user) project.team << [new_user, :master] - find('.filtered-search-input-container .clear-search').click + find('.filtered-search-box .clear-search').click filtered_search.set('assignee') filtered_search.send_keys(':') diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb index 1772a120045..990e3b3e60c 100644 --- a/spec/features/issues/filtered_search/dropdown_author_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb @@ -172,7 +172,7 @@ describe 'Dropdown author', js: true, feature: true do new_user = create(:user) project.team << [new_user, :master] - find('.filtered-search-input-container .clear-search').click + find('.filtered-search-box .clear-search').click filtered_search.set('author') send_keys_to_filtered_search(':') diff --git a/spec/features/issues/filtered_search/dropdown_hint_spec.rb b/spec/features/issues/filtered_search/dropdown_hint_spec.rb index bc8cbe30e66..cae01f37b6b 100644 --- a/spec/features/issues/filtered_search/dropdown_hint_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_hint_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe 'Dropdown hint', js: true, feature: true do +describe 'Dropdown hint', :js, :feature do include FilteredSearchHelpers include WaitForAjax @@ -9,10 +9,6 @@ describe 'Dropdown hint', js: true, feature: true do let(:filtered_search) { find('.filtered-search') } let(:js_dropdown_hint) { '#js-dropdown-hint' } - def dropdown_hint_size - page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size - end - def click_hint(text) find('#js-dropdown-hint .filter-dropdown .filter-dropdown-item', text: text).click end @@ -46,14 +42,16 @@ describe 'Dropdown hint', js: true, feature: true do it 'does not filter `Press Enter or click to search`' do filtered_search.set('randomtext') - expect(page).to have_css(js_dropdown_hint, text: 'Press Enter or click to search', visible: false) - expect(dropdown_hint_size).to eq(0) + hint_dropdown = find(js_dropdown_hint) + + expect(hint_dropdown).to have_content('Press Enter or click to search') + expect(hint_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 0) end it 'filters with text' do filtered_search.set('a') - expect(dropdown_hint_size).to eq(3) + expect(find(js_dropdown_hint)).to have_selector('.filter-dropdown .filter-dropdown-item', count: 3) end end diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb index b192064b693..abe5d61e38c 100644 --- a/spec/features/issues/filtered_search/dropdown_label_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb @@ -28,12 +28,8 @@ describe 'Dropdown label', js: true, feature: true do filter_dropdown.find('.filter-dropdown-item', text: text).click end - def dropdown_label_size - filter_dropdown.all('.filter-dropdown-item').size - end - def clear_search_field - find('.filtered-search-input-container .clear-search').click + find('.filtered-search-box .clear-search').click end before do @@ -81,7 +77,7 @@ describe 'Dropdown label', js: true, feature: true do filtered_search.set('label:') expect(filter_dropdown).to have_content(bug_label.title) - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) end end @@ -97,7 +93,8 @@ describe 'Dropdown label', js: true, feature: true do expect(filter_dropdown.find('.filter-dropdown-item', text: bug_label.title)).to be_visible expect(filter_dropdown.find('.filter-dropdown-item', text: uppercase_label.title)).to be_visible - expect(dropdown_label_size).to eq(2) + + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 2) clear_search_field init_label_search @@ -106,14 +103,14 @@ describe 'Dropdown label', js: true, feature: true do expect(filter_dropdown.find('.filter-dropdown-item', text: bug_label.title)).to be_visible expect(filter_dropdown.find('.filter-dropdown-item', text: uppercase_label.title)).to be_visible - expect(dropdown_label_size).to eq(2) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 2) end it 'filters by multiple words with or without symbol' do filtered_search.send_keys('Hig') expect(filter_dropdown.find('.filter-dropdown-item', text: two_words_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) clear_search_field init_label_search @@ -121,14 +118,14 @@ describe 'Dropdown label', js: true, feature: true do filtered_search.send_keys('~Hig') expect(filter_dropdown.find('.filter-dropdown-item', text: two_words_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) end it 'filters by multiple words containing single quotes with or without symbol' do filtered_search.send_keys('won\'t') expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_single_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) clear_search_field init_label_search @@ -136,14 +133,14 @@ describe 'Dropdown label', js: true, feature: true do filtered_search.send_keys('~won\'t') expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_single_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) end it 'filters by multiple words containing double quotes with or without symbol' do filtered_search.send_keys('won"t') expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) clear_search_field init_label_search @@ -151,14 +148,14 @@ describe 'Dropdown label', js: true, feature: true do filtered_search.send_keys('~won"t') expect(filter_dropdown.find('.filter-dropdown-item', text: wont_fix_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) end it 'filters by special characters with or without symbol' do filtered_search.send_keys('^+') expect(filter_dropdown.find('.filter-dropdown-item', text: special_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) clear_search_field init_label_search @@ -166,7 +163,7 @@ describe 'Dropdown label', js: true, feature: true do filtered_search.send_keys('~^+') expect(filter_dropdown.find('.filter-dropdown-item', text: special_label.title)).to be_visible - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) end end @@ -280,13 +277,13 @@ describe 'Dropdown label', js: true, feature: true do create(:label, project: project, title: 'bug-label') init_label_search - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) create(:label, project: project) clear_search_field init_label_search - expect(dropdown_label_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown-item', count: 1) end end end diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb index ce96a420699..448259057b0 100644 --- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb @@ -65,7 +65,7 @@ describe 'Dropdown milestone', :feature, :js do it 'should load all the milestones when opened' do filtered_search.set('milestone:') - expect(dropdown_milestone_size).to be > 0 + expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 6) end end @@ -84,37 +84,37 @@ describe 'Dropdown milestone', :feature, :js do it 'filters by name' do filtered_search.send_keys('v1') - expect(dropdown_milestone_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) end it 'filters by case insensitive name' do filtered_search.send_keys('V1') - expect(dropdown_milestone_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) end it 'filters by name with symbol' do filtered_search.send_keys('%v1') - expect(dropdown_milestone_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) end it 'filters by case insensitive name with symbol' do filtered_search.send_keys('%V1') - expect(dropdown_milestone_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) end it 'filters by special characters' do filtered_search.send_keys('(+') - expect(dropdown_milestone_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) end it 'filters by special characters with symbol' do filtered_search.send_keys('%(+') - expect(dropdown_milestone_size).to eq(1) + expect(filter_dropdown).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) end end @@ -252,7 +252,7 @@ describe 'Dropdown milestone', :feature, :js do expect(initial_size).to be > 0 create(:milestone, project: project) - find('.filtered-search-input-container .clear-search').click + find('.filtered-search-box .clear-search').click filtered_search.set('milestone:') expect(dropdown_milestone_size).to eq(initial_size) diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb index 004e335dd38..6f00066de4d 100644 --- a/spec/features/issues/filtered_search/filter_issues_spec.rb +++ b/spec/features/issues/filtered_search/filter_issues_spec.rb @@ -1,6 +1,7 @@ require 'spec_helper' describe 'Filter issues', js: true, feature: true do + include Devise::Test::IntegrationHelpers include FilteredSearchHelpers include WaitForAjax @@ -42,16 +43,17 @@ describe 'Filter issues', js: true, feature: true do project.team << [user2, :master] group.add_developer(user) group.add_developer(user2) - login_as(user) - create(:issue, project: project) - create(:issue, title: "Bug report 1", project: project) - create(:issue, title: "Bug report 2", project: project) - create(:issue, title: "issue with 'single quotes'", project: project) - create(:issue, title: "issue with \"double quotes\"", project: project) - create(:issue, title: "issue with !@\#{$%^&*()-+", project: project) - create(:issue, title: "issue by assignee", project: project, milestone: milestone, author: user, assignee: user) - create(:issue, title: "issue by assignee with searchTerm", project: project, milestone: milestone, author: user, assignee: user) + sign_in(user) + + create(:issue, project: project) + create(:issue, project: project, title: "Bug report 1") + create(:issue, project: project, title: "Bug report 2") + create(:issue, project: project, title: "issue with 'single quotes'") + create(:issue, project: project, title: "issue with \"double quotes\"") + create(:issue, project: project, title: "issue with !@\#{$%^&*()-+") + create(:issue, project: project, title: "issue by assignee", milestone: milestone, author: user, assignee: user) + create(:issue, project: project, title: "issue by assignee with searchTerm", milestone: milestone, author: user, assignee: user) issue = create(:issue, title: "Bug 2", @@ -756,10 +758,10 @@ describe 'Filter issues', js: true, feature: true do expect_issues_list_count(2) - sort_toggle = find('.filtered-search-container .dropdown-toggle') + sort_toggle = find('.filtered-search-wrapper .dropdown-toggle') sort_toggle.click - find('.filtered-search-container .dropdown-menu li a', text: 'Oldest updated').click + find('.filtered-search-wrapper .dropdown-menu li a', text: 'Oldest updated').click wait_for_ajax expect(find('.issues-list .issue:first-of-type .issue-title-text a')).to have_content(old_issue.title) diff --git a/spec/features/issues/filtered_search/recent_searches_spec.rb b/spec/features/issues/filtered_search/recent_searches_spec.rb new file mode 100644 index 00000000000..f506065a242 --- /dev/null +++ b/spec/features/issues/filtered_search/recent_searches_spec.rb @@ -0,0 +1,92 @@ +require 'spec_helper' + +describe 'Recent searches', js: true, feature: true do + include FilteredSearchHelpers + include WaitForAjax + + let!(:group) { create(:group) } + let!(:project) { create(:project, group: group) } + let!(:user) { create(:user) } + + before do + Capybara.ignore_hidden_elements = false + project.add_master(user) + group.add_developer(user) + create(:issue, project: project) + login_as(user) + + remove_recent_searches + end + + after do + Capybara.ignore_hidden_elements = true + end + + it 'searching adds to recent searches' do + visit namespace_project_issues_path(project.namespace, project) + + input_filtered_search('foo', submit: true) + input_filtered_search('bar', submit: true) + + items = all('.filtered-search-history-dropdown-item', visible: false) + + expect(items.count).to eq(2) + expect(items[0].text).to eq('bar') + expect(items[1].text).to eq('foo') + end + + it 'visiting URL with search params adds to recent searches' do + visit namespace_project_issues_path(project.namespace, project, label_name: 'foo', search: 'bar') + visit namespace_project_issues_path(project.namespace, project, label_name: 'qux', search: 'garply') + + items = all('.filtered-search-history-dropdown-item', visible: false) + + expect(items.count).to eq(2) + expect(items[0].text).to eq('label:~qux garply') + expect(items[1].text).to eq('label:~foo bar') + end + + it 'saved recent searches are restored last on the list' do + set_recent_searches('["saved1", "saved2"]') + + visit namespace_project_issues_path(project.namespace, project, search: 'foo') + + items = all('.filtered-search-history-dropdown-item', visible: false) + + expect(items.count).to eq(3) + expect(items[0].text).to eq('foo') + expect(items[1].text).to eq('saved1') + expect(items[2].text).to eq('saved2') + end + + it 'clicking item fills search input' do + set_recent_searches('["foo", "bar"]') + visit namespace_project_issues_path(project.namespace, project) + + all('.filtered-search-history-dropdown-item', visible: false)[0].trigger('click') + wait_for_filtered_search('foo') + + expect(find('.filtered-search').value.strip).to eq('foo') + end + + it 'clear recent searches button, clears recent searches' do + set_recent_searches('["foo"]') + visit namespace_project_issues_path(project.namespace, project) + + items_before = all('.filtered-search-history-dropdown-item', visible: false) + + expect(items_before.count).to eq(1) + + find('.filtered-search-history-clear-button', visible: false).trigger('click') + items_after = all('.filtered-search-history-dropdown-item', visible: false) + + expect(items_after.count).to eq(0) + end + + it 'shows flash error when failed to parse saved history' do + set_recent_searches('fail') + visit namespace_project_issues_path(project.namespace, project) + + expect(find('.flash-alert')).to have_text('An error occured while parsing recent searches') + end +end diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb index 59244d65eec..28137f11b92 100644 --- a/spec/features/issues/filtered_search/search_bar_spec.rb +++ b/spec/features/issues/filtered_search/search_bar_spec.rb @@ -26,7 +26,7 @@ describe 'Search bar', js: true, feature: true do filtered_search.native.send_keys(:down) page.within '#js-dropdown-hint' do - expect(page).to have_selector('.dropdown-active') + expect(page).to have_selector('.droplab-item-active') end end @@ -44,7 +44,7 @@ describe 'Search bar', js: true, feature: true do filtered_search.set(search_text) expect(filtered_search.value).to eq(search_text) - find('.filtered-search-input-container .clear-search').click + find('.filtered-search-box .clear-search').click expect(filtered_search.value).to eq('') end @@ -55,7 +55,7 @@ describe 'Search bar', js: true, feature: true do it 'hides after clicked' do filtered_search.set('a') - find('.filtered-search-input-container .clear-search').click + find('.filtered-search-box .clear-search').click expect(page).to have_css('.clear-search', visible: false) end @@ -79,28 +79,30 @@ describe 'Search bar', js: true, feature: true do filtered_search.set('author') - expect(page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size).to eq(1) + expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: 1) - find('.filtered-search-input-container .clear-search').click + find('.filtered-search-box .clear-search').click filtered_search.click - expect(page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size).to eq(original_size) + expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: original_size) end it 'resets the dropdown filters' do + filtered_search.click + + hint_offset = get_left_style(find('#js-dropdown-hint')['style']) + filtered_search.set('a') - hint_style = page.find('#js-dropdown-hint')['style'] - hint_offset = get_left_style(hint_style) filtered_search.set('author:') - expect(page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size).to eq(0) + find('#js-dropdown-hint', visible: false) - find('.filtered-search-input-container .clear-search').click + find('.filtered-search-box .clear-search').click filtered_search.click - expect(page.all('#js-dropdown-hint .filter-dropdown .filter-dropdown-item').size).to be > 0 - expect(get_left_style(page.find('#js-dropdown-hint')['style'])).to eq(hint_offset) + expect(find('#js-dropdown-hint')).to have_selector('.filter-dropdown .filter-dropdown-item', count: 4) + expect(get_left_style(find('#js-dropdown-hint')['style'])).to eq(hint_offset) end end end diff --git a/spec/features/issues/move_spec.rb b/spec/features/issues/move_spec.rb index f89b4db9e62..6c09903a2f6 100644 --- a/spec/features/issues/move_spec.rb +++ b/spec/features/issues/move_spec.rb @@ -37,8 +37,8 @@ feature 'issue move to another project' do edit_issue(issue) end - scenario 'moving issue to another project' do - first('#move_to_project_id', visible: false).set(new_project.id) + scenario 'moving issue to another project', js: true do + find('#move_to_project_id', visible: false).set(new_project.id) click_button('Save changes') expect(current_url).to include project_path(new_project) diff --git a/spec/features/issues/spam_issues_spec.rb b/spec/features/issues/spam_issues_spec.rb index 4bc9b49f889..6001476d0ca 100644 --- a/spec/features/issues/spam_issues_spec.rb +++ b/spec/features/issues/spam_issues_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -describe 'New issue', feature: true do +describe 'New issue', feature: true, js: true do include StubENV let(:project) { create(:project, :public) } diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index 7afceb88cf9..362d167befa 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -601,10 +601,10 @@ describe 'Issues', feature: true do expect(page.find_field("issue_description").value).to have_content 'banana_sample' end - it 'adds double newline to end of attachment markdown' do + it "doesn't add double newline to end of a single attachment markdown" do dropzone_file Rails.root.join('spec', 'fixtures', 'banana_sample.gif') - expect(page.find_field("issue_description").value).to match /\n\n$/ + expect(page.find_field("issue_description").value).not_to match /\n\n$/ end end @@ -695,4 +695,21 @@ describe 'Issues', feature: true do end end end + + describe 'title issue#show', js: true do + include WaitForVueResource + + it 'updates the title', js: true do + issue = create(:issue, author: @user, assignee: @user, project: project, title: 'new title') + + visit namespace_project_issue_path(project.namespace, project, issue) + + expect(page).to have_text("new title") + + issue.update(title: "updated title") + + wait_for_vue_resource + expect(page).to have_text("updated title") + end + end end diff --git a/spec/features/login_spec.rb b/spec/features/login_spec.rb index f32d1f78b40..11d417c253d 100644 --- a/spec/features/login_spec.rb +++ b/spec/features/login_spec.rb @@ -199,52 +199,125 @@ feature 'Login', feature: true do describe 'with required two-factor authentication enabled' do let(:user) { create(:user) } - before(:each) { stub_application_setting(require_two_factor_authentication: true) } + # TODO: otp_grace_period_started_at - context 'with grace period defined' do - before(:each) do - stub_application_setting(two_factor_grace_period: 48) - login_with(user) - end + context 'global setting' do + before(:each) { stub_application_setting(require_two_factor_authentication: true) } - context 'within the grace period' do - it 'redirects to two-factor configuration page' do - expect(current_path).to eq profile_two_factor_auth_path - expect(page).to have_content('You must enable Two-Factor Authentication for your account before') + context 'with grace period defined' do + before(:each) do + stub_application_setting(two_factor_grace_period: 48) + login_with(user) end - it 'allows skipping two-factor configuration', js: true do - expect(current_path).to eq profile_two_factor_auth_path + context 'within the grace period' do + it 'redirects to two-factor configuration page' do + expect(current_path).to eq profile_two_factor_auth_path + expect(page).to have_content('The global settings require you to enable Two-Factor Authentication for your account. You need to do this before ') + end - click_link 'Configure it later' - expect(current_path).to eq root_path + it 'allows skipping two-factor configuration', js: true do + expect(current_path).to eq profile_two_factor_auth_path + + click_link 'Configure it later' + expect(current_path).to eq root_path + end end - end - context 'after the grace period' do - let(:user) { create(:user, otp_grace_period_started_at: 9999.hours.ago) } + context 'after the grace period' do + let(:user) { create(:user, otp_grace_period_started_at: 9999.hours.ago) } - it 'redirects to two-factor configuration page' do - expect(current_path).to eq profile_two_factor_auth_path - expect(page).to have_content('You must enable Two-Factor Authentication for your account.') + it 'redirects to two-factor configuration page' do + expect(current_path).to eq profile_two_factor_auth_path + expect(page).to have_content( + 'The global settings require you to enable Two-Factor Authentication for your account.' + ) + end + + it 'disallows skipping two-factor configuration', js: true do + expect(current_path).to eq profile_two_factor_auth_path + expect(page).not_to have_link('Configure it later') + end + end + end + + context 'without grace period defined' do + before(:each) do + stub_application_setting(two_factor_grace_period: 0) + login_with(user) end - it 'disallows skipping two-factor configuration', js: true do + it 'redirects to two-factor configuration page' do expect(current_path).to eq profile_two_factor_auth_path - expect(page).not_to have_link('Configure it later') + expect(page).to have_content( + 'The global settings require you to enable Two-Factor Authentication for your account.' + ) end end end - context 'without grace period defined' do - before(:each) do - stub_application_setting(two_factor_grace_period: 0) - login_with(user) + context 'group setting' do + before do + group1 = create :group, name: 'Group 1', require_two_factor_authentication: true + group1.add_user(user, GroupMember::DEVELOPER) + group2 = create :group, name: 'Group 2', require_two_factor_authentication: true + group2.add_user(user, GroupMember::DEVELOPER) end - it 'redirects to two-factor configuration page' do - expect(current_path).to eq profile_two_factor_auth_path - expect(page).to have_content('You must enable Two-Factor Authentication for your account.') + context 'with grace period defined' do + before(:each) do + stub_application_setting(two_factor_grace_period: 48) + login_with(user) + end + + context 'within the grace period' do + it 'redirects to two-factor configuration page' do + expect(current_path).to eq profile_two_factor_auth_path + expect(page).to have_content( + 'The group settings for Group 1 and Group 2 require you to enable ' \ + 'Two-Factor Authentication for your account. You need to do this ' \ + 'before ') + end + + it 'allows skipping two-factor configuration', js: true do + expect(current_path).to eq profile_two_factor_auth_path + + click_link 'Configure it later' + expect(current_path).to eq root_path + end + end + + context 'after the grace period' do + let(:user) { create(:user, otp_grace_period_started_at: 9999.hours.ago) } + + it 'redirects to two-factor configuration page' do + expect(current_path).to eq profile_two_factor_auth_path + expect(page).to have_content( + 'The group settings for Group 1 and Group 2 require you to enable ' \ + 'Two-Factor Authentication for your account.' + ) + end + + it 'disallows skipping two-factor configuration', js: true do + expect(current_path).to eq profile_two_factor_auth_path + expect(page).not_to have_link('Configure it later') + end + end + end + + context 'without grace period defined' do + before(:each) do + stub_application_setting(two_factor_grace_period: 0) + login_with(user) + end + + it 'redirects to two-factor configuration page' do + expect(current_path).to eq profile_two_factor_auth_path + expect(page).to have_content( + 'The group settings for Group 1 and Group 2 require you to enable ' \ + 'Two-Factor Authentication for your account.' + ) + end end end end diff --git a/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb index 7f11db3c417..77b7ba4ac7a 100644 --- a/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb +++ b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb @@ -19,7 +19,7 @@ feature 'Check if mergeable with unresolved discussions', js: true, feature: tru it 'does not allow to merge' do visit_merge_request(merge_request) - expect(page).not_to have_button 'Accept Merge Request' + expect(page).not_to have_button 'Accept merge request' expect(page).to have_content('This merge request has unresolved discussions') end end @@ -32,7 +32,7 @@ feature 'Check if mergeable with unresolved discussions', js: true, feature: tru it 'allows MR to be merged' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end end @@ -46,7 +46,7 @@ feature 'Check if mergeable with unresolved discussions', js: true, feature: tru it 'does not allow to merge' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end @@ -58,7 +58,7 @@ feature 'Check if mergeable with unresolved discussions', js: true, feature: tru it 'allows MR to be merged' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end end diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb index f1ad4a55246..3a4ec07b2b0 100644 --- a/spec/features/merge_requests/create_new_mr_spec.rb +++ b/spec/features/merge_requests/create_new_mr_spec.rb @@ -15,7 +15,7 @@ feature 'Create New Merge Request', feature: true, js: true do it 'selects the source branch sha when a tag with the same name exists' do visit namespace_project_merge_requests_path(project.namespace, project) - click_link 'New Merge Request' + click_link 'New merge request' expect(page).to have_content('Source branch') expect(page).to have_content('Target branch') @@ -26,9 +26,9 @@ feature 'Create New Merge Request', feature: true, js: true do end it 'selects the target branch sha when a tag with the same name exists' do - visit namespace_project_merge_requests_path(project.namespace, project) - - click_link 'New Merge Request' + visit namespace_project_merge_requests_path(project.namespace, project) + + click_link 'New merge request' expect(page).to have_content('Source branch') expect(page).to have_content('Target branch') @@ -42,7 +42,7 @@ feature 'Create New Merge Request', feature: true, js: true do it 'generates a diff for an orphaned branch' do visit namespace_project_merge_requests_path(project.namespace, project) - click_link 'New Merge Request' + page.has_link?('New Merge Request') ? click_link("New Merge Request") : click_link('New merge request') expect(page).to have_content('Source branch') expect(page).to have_content('Target branch') @@ -70,6 +70,18 @@ feature 'Create New Merge Request', feature: true, js: true do visit new_namespace_project_merge_request_path(project.namespace, project, merge_request: { target_project_id: private_project.id }) expect(page).not_to have_content private_project.path_with_namespace + expect(page).to have_content project.path_with_namespace + end + end + + context 'when source project cannot be viewed by the current user' do + it 'does not leak the private project name & namespace' do + private_project = create(:project, :private) + + visit new_namespace_project_merge_request_path(project.namespace, project, merge_request: { source_project_id: private_project.id }) + + expect(page).not_to have_content private_project.path_with_namespace + expect(page).to have_content project.path_with_namespace end end diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb index a6c72b0b3ac..218d95a88b8 100644 --- a/spec/features/merge_requests/diff_notes_avatars_spec.rb +++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb @@ -164,9 +164,7 @@ feature 'Diff note avatars', feature: true, js: true do context 'multiple comments' do before do - create(:diff_note_on_merge_request, project: project, noteable: merge_request, position: position) - create(:diff_note_on_merge_request, project: project, noteable: merge_request, position: position) - create(:diff_note_on_merge_request, project: project, noteable: merge_request, position: position) + create_list(:diff_note_on_merge_request, 3, project: project, noteable: merge_request, in_reply_to: note) visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, view: view) diff --git a/spec/features/merge_requests/diff_notes_resolve_spec.rb b/spec/features/merge_requests/diff_notes_resolve_spec.rb index 69164aabdb2..0e23c3a8849 100644 --- a/spec/features/merge_requests/diff_notes_resolve_spec.rb +++ b/spec/features/merge_requests/diff_notes_resolve_spec.rb @@ -191,13 +191,15 @@ feature 'Diff notes resolve', feature: true, js: true do context 'multiple notes' do before do - create(:diff_note_on_merge_request, project: project, noteable: merge_request) + create(:diff_note_on_merge_request, project: project, noteable: merge_request, in_reply_to: note) visit_merge_request end it 'does not mark discussion as resolved when resolving single note' do page.first '.diff-content .note' do first('.line-resolve-btn').click + + expect(page).to have_selector('.note-action-button .loading') expect(first('.line-resolve-btn')['data-original-title']).to eq("Resolved by #{user.name}") end diff --git a/spec/features/merge_requests/discussion_spec.rb b/spec/features/merge_requests/discussion_spec.rb new file mode 100644 index 00000000000..f59d0faa274 --- /dev/null +++ b/spec/features/merge_requests/discussion_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +feature 'Merge Request Discussions', feature: true do + before do + login_as :admin + end + + context "Diff discussions" do + let(:merge_request) { create(:merge_request, importing: true) } + let(:project) { merge_request.source_project } + let!(:old_merge_request_diff) { merge_request.merge_request_diffs.create(diff_refs: outdated_diff_refs) } + let!(:new_merge_request_diff) { merge_request.merge_request_diffs.create } + + let!(:outdated_discussion) { create(:diff_note_on_merge_request, project: project, noteable: merge_request, position: outdated_position).to_discussion } + let!(:active_discussion) { create(:diff_note_on_merge_request, noteable: merge_request, project: project).to_discussion } + + let(:outdated_position) do + Gitlab::Diff::Position.new( + old_path: "files/ruby/popen.rb", + new_path: "files/ruby/popen.rb", + old_line: nil, + new_line: 9, + diff_refs: outdated_diff_refs + ) + end + + let(:outdated_diff_refs) { project.commit("874797c3a73b60d2187ed6e2fcabd289ff75171e").diff_refs } + + before(:each) do + visit namespace_project_merge_request_path(project.namespace, project, merge_request) + end + + context 'active discussions' do + it 'shows a link to the diff' do + within(".discussion[data-discussion-id='#{active_discussion.id}']") do + path = diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, anchor: active_discussion.line_code) + expect(page).to have_link('the diff', href: path) + end + end + end + + context 'outdated discussions' do + it 'shows a link to the outdated diff' do + within(".discussion[data-discussion-id='#{outdated_discussion.id}']") do + path = diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, diff_id: old_merge_request_diff.id, anchor: outdated_discussion.line_code) + expect(page).to have_link('an outdated diff', href: path) + end + end + end + end +end diff --git a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb index 79105b1ee46..497240803d4 100644 --- a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb +++ b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb @@ -32,7 +32,7 @@ feature 'Merge immediately', :feature, :js do page.within '.mr-widget-body' do find('.dropdown-toggle').click - click_link 'Merge Immediately' + click_link 'Merge immediately' expect(find('.js-merge-when-pipeline-succeeds-button')).to have_content('Merge in progress') diff --git a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb index ed7193b9777..cd540ca113a 100644 --- a/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb +++ b/spec/features/merge_requests/merge_when_pipeline_succeeds_spec.rb @@ -28,25 +28,25 @@ feature 'Merge When Pipeline Succeeds', :feature, :js do visit_merge_request(merge_request) end - it 'displays the Merge When Pipeline Succeeds button' do - expect(page).to have_button "Merge When Pipeline Succeeds" + it 'displays the Merge when pipeline succeeds button' do + expect(page).to have_button "Merge when pipeline succeeds" end - describe 'enabling Merge When Pipeline Succeeds' do - shared_examples 'Merge When Pipeline Succeeds activator' do - it 'activates the Merge When Pipeline Succeeds feature' do - click_button "Merge When Pipeline Succeeds" + describe 'enabling Merge when pipeline succeeds' do + shared_examples 'Merge when pipeline succeeds activator' do + it 'activates the Merge when pipeline succeeds feature' do + click_button "Merge when pipeline succeeds" expect(page).to have_content "Set by #{user.name} to be merged automatically when the pipeline succeeds." expect(page).to have_content "The source branch will not be removed." - expect(page).to have_link "Cancel Automatic Merge" + expect(page).to have_link "Cancel automatic merge" visit_merge_request(merge_request) # Needed to refresh the page expect(page).to have_content /enabled an automatic merge when the pipeline for \h{8} succeeds/i end end context "when enabled immediately" do - it_behaves_like 'Merge When Pipeline Succeeds activator' + it_behaves_like 'Merge when pipeline succeeds activator' end context 'when enabled after pipeline status changed' do @@ -60,16 +60,16 @@ feature 'Merge When Pipeline Succeeds', :feature, :js do expect(page).to have_content "Pipeline ##{pipeline.id} running" end - it_behaves_like 'Merge When Pipeline Succeeds activator' + it_behaves_like 'Merge when pipeline succeeds activator' end context 'when enabled after it was previously canceled' do before do - click_button "Merge When Pipeline Succeeds" - click_link "Cancel Automatic Merge" + click_button "Merge when pipeline succeeds" + click_link "Cancel automatic merge" end - it_behaves_like 'Merge When Pipeline Succeeds activator' + it_behaves_like 'Merge when pipeline succeeds activator' end context 'when it was enabled and then canceled' do @@ -83,10 +83,23 @@ feature 'Merge When Pipeline Succeeds', :feature, :js do end before do - click_link "Cancel Automatic Merge" + click_link "Cancel automatic merge" end - it_behaves_like 'Merge When Pipeline Succeeds activator' + it_behaves_like 'Merge when pipeline succeeds activator' + end + end + + describe 'enabling Merge when pipeline succeeds via dropdown' do + it 'activates the Merge when pipeline succeeds feature' do + click_button 'Select merge moment' + within('.js-merge-dropdown') do + click_link 'Merge when pipeline succeeds' + end + + expect(page).to have_content "Set by #{user.name} to be merged automatically when the pipeline succeeds." + expect(page).to have_content "The source branch will not be removed." + expect(page).to have_link "Cancel automatic merge" end end end @@ -110,18 +123,18 @@ feature 'Merge When Pipeline Succeeds', :feature, :js do end it 'allows to cancel the automatic merge' do - click_link "Cancel Automatic Merge" + click_link "Cancel automatic merge" - expect(page).to have_button "Merge When Pipeline Succeeds" + expect(page).to have_button "Merge when pipeline succeeds" visit_merge_request(merge_request) # refresh the page expect(page).to have_content "canceled the automatic merge" end it "allows the user to remove the source branch" do - expect(page).to have_link "Remove Source Branch When Merged" + expect(page).to have_link "Remove source branch when merged" - click_link "Remove Source Branch When Merged" + click_link "Remove source branch when merged" expect(page).to have_content "The source branch will be removed" end @@ -141,7 +154,7 @@ feature 'Merge When Pipeline Succeeds', :feature, :js do it "does not allow to enable merge when pipeline succeeds" do visit_merge_request(merge_request) - expect(page).not_to have_link 'Merge When Pipeline Succeeds' + expect(page).not_to have_link 'Merge when pipeline succeeds' end end diff --git a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb index 447764566e0..4a590e3bf68 100644 --- a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb +++ b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb @@ -14,7 +14,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end @@ -38,8 +38,8 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'does not allow to merge immediately' do visit_merge_request(merge_request) - expect(page).to have_button 'Merge When Pipeline Succeeds' - expect(page).not_to have_button 'Select Merge Moment' + expect(page).to have_button 'Merge when pipeline succeeds' + expect(page).not_to have_button 'Select merge moment' end end @@ -49,7 +49,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'does not allow MR to be merged' do visit_merge_request(merge_request) - expect(page).not_to have_button 'Accept Merge Request' + expect(page).not_to have_button 'Accept merge request' expect(page).to have_content('Please retry the job or push a new commit to fix the failure.') end end @@ -60,7 +60,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'does not allow MR to be merged' do visit_merge_request(merge_request) - expect(page).not_to have_button 'Accept Merge Request' + expect(page).not_to have_button 'Accept merge request' expect(page).to have_content('Please retry the job or push a new commit to fix the failure.') end end @@ -71,7 +71,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end @@ -81,7 +81,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end end @@ -97,10 +97,10 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged immediately', js: true do visit_merge_request(merge_request) - expect(page).to have_button 'Merge When Pipeline Succeeds' + expect(page).to have_button 'Merge when pipeline succeeds' - click_button 'Select Merge Moment' - expect(page).to have_content 'Merge Immediately' + click_button 'Select merge moment' + expect(page).to have_content 'Merge immediately' end end @@ -110,7 +110,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end @@ -120,7 +120,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', featu it 'allows MR to be merged' do visit_merge_request(merge_request) - expect(page).to have_button 'Accept Merge Request' + expect(page).to have_button 'Accept merge request' end end end diff --git a/spec/features/merge_requests/reset_filters_spec.rb b/spec/features/merge_requests/reset_filters_spec.rb index 14511707af4..df5943f9136 100644 --- a/spec/features/merge_requests/reset_filters_spec.rb +++ b/spec/features/merge_requests/reset_filters_spec.rb @@ -14,7 +14,7 @@ feature 'Merge requests filter clear button', feature: true, js: true do let!(:mr2) { create(:merge_request, title: "Bugfix1", source_project: project, target_project: project, source_branch: "Bugfix1") } let(:merge_request_css) { '.merge-request' } - let(:clear_search_css) { '.filtered-search-input-container .clear-search' } + let(:clear_search_css) { '.filtered-search-box .clear-search' } before do mr2.labels << bug diff --git a/spec/features/merge_requests/merge_request_versions_spec.rb b/spec/features/merge_requests/versions_spec.rb index 04e85ed3f73..68a68f5d3f3 100644 --- a/spec/features/merge_requests/merge_request_versions_spec.rb +++ b/spec/features/merge_requests/versions_spec.rb @@ -36,8 +36,23 @@ feature 'Merge Request versions', js: true, feature: true do expect(page).to have_content '5 changed files' end - it 'show the message about disabled comments' do - expect(page).to have_content 'Comments are disabled' + it 'show the message about disabled comment creation' do + expect(page).to have_content 'comment creation is disabled' + end + + it 'shows comments that were last relevant at that version' do + position = Gitlab::Diff::Position.new( + old_path: ".gitmodules", + new_path: ".gitmodules", + old_line: nil, + new_line: 4, + diff_refs: merge_request_diff1.diff_refs + ) + outdated_diff_note = create(:diff_note_on_merge_request, project: project, noteable: merge_request, position: position) + outdated_diff_note.position = outdated_diff_note.original_position + outdated_diff_note.save! + + expect(page).to have_css(".diffs .notes[data-discussion-id='#{outdated_diff_note.discussion_id}']") end end diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb index c2db7d8da3c..a62c5435748 100644 --- a/spec/features/merge_requests/widget_spec.rb +++ b/spec/features/merge_requests/widget_spec.rb @@ -145,7 +145,7 @@ describe 'Merge request', :feature, :js do before do allow_any_instance_of(Repository).to receive(:merge).and_return(false) visit namespace_project_merge_request_path(project.namespace, project, merge_request) - click_button 'Accept Merge Request' + click_button 'Accept merge request' wait_for_ajax end diff --git a/spec/features/milestones/milestones_spec.rb b/spec/features/milestones/milestones_spec.rb index 8de9942c54e..2fa3e72ab08 100644 --- a/spec/features/milestones/milestones_spec.rb +++ b/spec/features/milestones/milestones_spec.rb @@ -76,6 +76,7 @@ describe 'Milestone draggable', feature: true, js: true do create(:issue, params.merge(title: 'Foo', project: project, milestone: milestone)) visit namespace_project_milestone_path(project.namespace, project, milestone) + scroll_into_view('.milestone-content') drag_to(selector: '.issues-sortable-list', list_to_index: 1) wait_for_ajax @@ -86,8 +87,13 @@ describe 'Milestone draggable', feature: true, js: true do visit namespace_project_milestone_path(project.namespace, project, milestone) page.find("a[href='#tab-merge-requests']").click + scroll_into_view('.milestone-content') drag_to(selector: '.merge_requests-sortable-list', list_to_index: 1) wait_for_ajax end + + def scroll_into_view(selector) + page.evaluate_script("document.querySelector('#{selector}').scrollIntoView();") + end end diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb index fab2d532e06..783f2e93909 100644 --- a/spec/features/notes_on_merge_requests_spec.rb +++ b/spec/features/notes_on_merge_requests_spec.rb @@ -25,7 +25,7 @@ describe 'Comments', feature: true do describe 'the note form' do it 'is valid' do is_expected.to have_css('.js-main-target-form', visible: true, count: 1) - expect(find('.js-main-target-form input[type=submit]').value). + expect(find('.js-main-target-form .js-comment-button').value). to eq('Comment') page.within('.js-main-target-form') do expect(page).not_to have_link('Cancel') diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb index 99fba594651..27a20e78a43 100644 --- a/spec/features/profiles/personal_access_tokens_spec.rb +++ b/spec/features/profiles/personal_access_tokens_spec.rb @@ -41,7 +41,7 @@ describe 'Profile > Personal Access Tokens', feature: true, js: true do check "api" check "read_user" - click_on "Create Personal Access Token" + click_on "Create personal access token" expect(active_personal_access_tokens).to have_text(name) expect(active_personal_access_tokens).to have_text('In') expect(active_personal_access_tokens).to have_text('api') @@ -54,7 +54,7 @@ describe 'Profile > Personal Access Tokens', feature: true, js: true do visit profile_personal_access_tokens_path fill_in "Name", with: 'My PAT' - expect { click_on "Create Personal Access Token" }.not_to change { PersonalAccessToken.count } + expect { click_on "Create personal access token" }.not_to change { PersonalAccessToken.count } expect(page).to have_content("Name cannot be nil") end end diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb new file mode 100644 index 00000000000..01cd268ffe8 --- /dev/null +++ b/spec/features/projects/blobs/blob_show_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +feature 'File blob', feature: true do + include WaitForAjax + include TreeHelper + + let(:project) { create(:project, :public, :test_repo) } + let(:merge_request) { create(:merge_request, source_project: project, source_branch: 'feature', target_branch: 'master') } + let(:branch) { 'master' } + let(:file_path) { project.repository.ls_files(project.repository.root_ref)[1] } + + context 'anonymous' do + context 'from blob file path' do + before do + visit namespace_project_blob_path(project.namespace, project, tree_join(branch, file_path)) + end + + it 'updates content' do + expect(page).to have_link 'Edit' + end + end + end +end diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb index a820d07ab3b..aab5a72678e 100644 --- a/spec/features/projects/blobs/edit_spec.rb +++ b/spec/features/projects/blobs/edit_spec.rb @@ -2,44 +2,135 @@ require 'spec_helper' feature 'Editing file blob', feature: true, js: true do include WaitForAjax + include TreeHelper - given(:user) { create(:user) } - given(:role) { :developer } - given(:merge_request) { create(:merge_request, source_branch: 'feature', target_branch: 'master') } - given(:project) { merge_request.target_project } + let(:project) { create(:project, :public, :test_repo) } + let(:merge_request) { create(:merge_request, source_project: project, source_branch: 'feature', target_branch: 'master') } + let(:branch) { 'master' } + let(:file_path) { project.repository.ls_files(project.repository.root_ref)[1] } - background do - login_as(user) - project.team << [user, role] - end - - def edit_and_commit - wait_for_ajax - first('.file-actions').click_link 'Edit' - execute_script('ace.edit("editor").setValue("class NextFeature\nend\n")') - click_button 'Commit Changes' - end + context 'as a developer' do + let(:user) { create(:user) } + let(:role) { :developer } - context 'from MR diff' do before do - visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) - edit_and_commit + project.team << [user, role] + login_as(user) + end + + def edit_and_commit + wait_for_ajax + find('.js-edit-blob').click + execute_script('ace.edit("editor").setValue("class NextFeature\nend\n")') + click_button 'Commit changes' + end + + context 'from MR diff' do + before do + visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) + edit_and_commit + end + + it 'returns me to the mr' do + expect(page).to have_content(merge_request.title) + end end - scenario 'returns me to the mr' do - expect(page).to have_content(merge_request.title) + context 'from blob file path' do + before do + visit namespace_project_blob_path(project.namespace, project, tree_join(branch, file_path)) + edit_and_commit + end + + it 'updates content' do + expect(page).to have_content 'successfully committed' + expect(page).to have_content 'NextFeature' + end end end - context 'from blob file path' do - before do - visit namespace_project_blob_path(project.namespace, project, '/feature/files/ruby/feature.rb') - edit_and_commit + context 'visit blob edit' do + context 'redirects to sign in and returns' do + context 'as developer' do + let(:user) { create(:user) } + + before do + project.team << [user, :developer] + visit namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path)) + end + + it 'redirects to sign in and returns' do + expect(page).to have_current_path(new_user_session_path) + + login_as(user) + + expect(page).to have_current_path(namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path))) + end + end + + context 'as guest' do + let(:user) { create(:user) } + + before do + visit namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path)) + end + + it 'redirects to sign in and returns' do + expect(page).to have_current_path(new_user_session_path) + + login_as(user) + + expect(page).to have_current_path(namespace_project_blob_path(project.namespace, project, tree_join(branch, file_path))) + end + end + end + + context 'as developer' do + let(:user) { create(:user) } + let(:protected_branch) { 'protected-branch' } + + before do + project.team << [user, :developer] + project.repository.add_branch(user, protected_branch, 'master') + create(:protected_branch, project: project, name: protected_branch) + login_as(user) + end + + context 'on some branch' do + before do + visit namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path)) + end + + it 'shows blob editor with same branch' do + expect(page).to have_current_path(namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path))) + expect(find('.js-target-branch .dropdown-toggle-text').text).to eq(branch) + end + end + + context 'with protected branch' do + before do + visit namespace_project_edit_blob_path(project.namespace, project, tree_join(protected_branch, file_path)) + end + + it 'shows blob editor with patch branch' do + expect(find('.js-target-branch .dropdown-toggle-text').text).to eq('patch-1') + end + end end - scenario 'updates content' do - expect(page).to have_content 'successfully committed' - expect(page).to have_content 'NextFeature' + context 'as master' do + let(:user) { create(:user) } + + before do + project.team << [user, :master] + login_as(user) + visit namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path)) + end + + it 'shows blob editor with same branch' do + expect(page).to have_current_path(namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path))) + expect(find('.js-target-branch .dropdown-toggle-text').text).to eq(branch) + end end end end diff --git a/spec/features/projects/blobs/user_create_spec.rb b/spec/features/projects/blobs/user_create_spec.rb index d214a531138..fa1a753afcb 100644 --- a/spec/features/projects/blobs/user_create_spec.rb +++ b/spec/features/projects/blobs/user_create_spec.rb @@ -22,7 +22,7 @@ feature 'New blob creation', feature: true, js: true do end def commit_file - click_button 'Commit Changes' + click_button 'Commit changes' end context 'with default target branch' do diff --git a/spec/features/projects/builds_spec.rb b/spec/features/projects/builds_spec.rb index 2116721b224..ab10434e10c 100644 --- a/spec/features/projects/builds_spec.rb +++ b/spec/features/projects/builds_spec.rb @@ -205,21 +205,13 @@ feature 'Builds', :feature do it 'loads job trace' do expect(page).to have_content 'BUILD TRACE' - build.append_trace(' and more trace', 11) + build.trace.write do |stream| + stream.append(' and more trace', 11) + end expect(page).to have_content 'BUILD TRACE and more trace' end end - - context 'when build does not have an initial trace' do - let(:build) { create(:ci_build, pipeline: pipeline) } - - it 'loads new trace' do - build.append_trace('build trace', 0) - - expect(page).to have_content 'build trace' - end - end end feature 'Variables' do @@ -390,7 +382,7 @@ feature 'Builds', :feature do it 'sends the right headers' do expect(page.status_code).to eq(200) expect(page.response_headers['Content-Type']).to eq('text/plain; charset=utf-8') - expect(page.response_headers['X-Sendfile']).to eq(build.path_to_trace) + expect(page.response_headers['X-Sendfile']).to eq(build.trace.send(:current_path)) end end @@ -409,43 +401,24 @@ feature 'Builds', :feature do context 'storage form' do let(:existing_file) { Tempfile.new('existing-trace-file').path } - let(:non_existing_file) do - file = Tempfile.new('non-existing-trace-file') - path = file.path - file.unlink - path - end - context 'when build has trace in file' do - before do - Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile') - build.run! - visit namespace_project_build_path(project.namespace, project, build) + before do + Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile') - allow_any_instance_of(Project).to receive(:ci_id).and_return(nil) - allow_any_instance_of(Ci::Build).to receive(:path_to_trace).and_return(existing_file) - allow_any_instance_of(Ci::Build).to receive(:old_path_to_trace).and_return(non_existing_file) + build.run! - page.within('.js-build-sidebar') { click_link 'Raw' } - end + allow_any_instance_of(Gitlab::Ci::Trace).to receive(:paths) + .and_return(paths) - it 'sends the right headers' do - expect(page.status_code).to eq(200) - expect(page.response_headers['Content-Type']).to eq('text/plain; charset=utf-8') - expect(page.response_headers['X-Sendfile']).to eq(existing_file) - end + visit namespace_project_build_path(project.namespace, project, build) end - context 'when build has trace in old file' do - before do - Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile') - build.run! - visit namespace_project_build_path(project.namespace, project, build) - - allow_any_instance_of(Project).to receive(:ci_id).and_return(999) - allow_any_instance_of(Ci::Build).to receive(:path_to_trace).and_return(non_existing_file) - allow_any_instance_of(Ci::Build).to receive(:old_path_to_trace).and_return(existing_file) + context 'when build has trace in file' do + let(:paths) do + [existing_file] + end + before do page.within('.js-build-sidebar') { click_link 'Raw' } end @@ -457,20 +430,10 @@ feature 'Builds', :feature do end context 'when build has trace in DB' do - before do - Capybara.current_session.driver.header('X-Sendfile-Type', 'X-Sendfile') - build.run! - visit namespace_project_build_path(project.namespace, project, build) - - allow_any_instance_of(Project).to receive(:ci_id).and_return(nil) - allow_any_instance_of(Ci::Build).to receive(:path_to_trace).and_return(non_existing_file) - allow_any_instance_of(Ci::Build).to receive(:old_path_to_trace).and_return(non_existing_file) - - page.within('.js-build-sidebar') { click_link 'Raw' } - end + let(:paths) { [] } it 'sends the right headers' do - expect(page.status_code).to eq(404) + expect(page.status_code).not_to have_link('Raw') end end end diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb index 641e2cf7402..cf393afccbb 100644 --- a/spec/features/projects/environments/environments_spec.rb +++ b/spec/features/projects/environments/environments_spec.rb @@ -23,6 +23,46 @@ feature 'Environments page', :feature, :js do expect(page).to have_link('Available') expect(page).to have_link('Stopped') end + + describe 'with one available environment' do + given(:environment) { create(:environment, project: project, state: :available) } + + describe 'in available tab page' do + it 'should show one environment' do + visit namespace_project_environments_path(project.namespace, project, scope: 'available') + expect(page).to have_css('.environments-container') + expect(page.all('tbody > tr').length).to eq(1) + end + end + + describe 'in stopped tab page' do + it 'should show no environments' do + visit namespace_project_environments_path(project.namespace, project, scope: 'stopped') + expect(page).to have_css('.environments-container') + expect(page).to have_content('You don\'t have any environments right now') + end + end + end + + describe 'with one stopped environment' do + given(:environment) { create(:environment, project: project, state: :stopped) } + + describe 'in available tab page' do + it 'should show no environments' do + visit namespace_project_environments_path(project.namespace, project, scope: 'available') + expect(page).to have_css('.environments-container') + expect(page).to have_content('You don\'t have any environments right now') + end + end + + describe 'in stopped tab page' do + it 'should show one environment' do + visit namespace_project_environments_path(project.namespace, project, scope: 'stopped') + expect(page).to have_css('.environments-container') + expect(page.all('tbody > tr').length).to eq(1) + end + end + end end context 'without environments' do diff --git a/spec/features/projects/files/creating_a_file_spec.rb b/spec/features/projects/files/creating_a_file_spec.rb index ae448706130..5d7bd3dc4ce 100644 --- a/spec/features/projects/files/creating_a_file_spec.rb +++ b/spec/features/projects/files/creating_a_file_spec.rb @@ -19,7 +19,7 @@ feature 'User wants to create a file', feature: true do file_content = find('#file-content') file_content.set options[:file_content] || 'Some content' - click_button 'Commit Changes' + click_button 'Commit changes' end scenario 'file name contains Chinese characters' do diff --git a/spec/features/projects/files/editing_a_file_spec.rb b/spec/features/projects/files/editing_a_file_spec.rb index 36a80d7575d..3e544316f28 100644 --- a/spec/features/projects/files/editing_a_file_spec.rb +++ b/spec/features/projects/files/editing_a_file_spec.rb @@ -27,7 +27,7 @@ feature 'User wants to edit a file', feature: true do scenario 'file has been updated since the user opened the edit page' do Files::UpdateService.new(project, user, commit_params).execute - click_button 'Commit Changes' + click_button 'Commit changes' expect(page).to have_content 'Someone edited the file the same time you did.' end diff --git a/spec/features/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/projects/files/project_owner_creates_license_file_spec.rb index 6b281e6d21d..8ff0f5898ec 100644 --- a/spec/features/projects/files/project_owner_creates_license_file_spec.rb +++ b/spec/features/projects/files/project_owner_creates_license_file_spec.rb @@ -29,7 +29,7 @@ feature 'project owner creates a license file', feature: true, js: true do expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") fill_in :commit_message, with: 'Add a LICENSE file', visible: true - click_button 'Commit Changes' + click_button 'Commit changes' expect(current_path).to eq( namespace_project_blob_path(project.namespace, project, 'master/LICENSE')) @@ -53,7 +53,7 @@ feature 'project owner creates a license file', feature: true, js: true do expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}") fill_in :commit_message, with: 'Add a LICENSE file', visible: true - click_button 'Commit Changes' + click_button 'Commit changes' expect(current_path).to eq( namespace_project_blob_path(project.namespace, project, 'master/LICENSE')) @@ -63,7 +63,7 @@ feature 'project owner creates a license file', feature: true, js: true do def select_template(template) page.within('.js-license-selector-wrap') do - click_button 'Apply a License template' + click_button 'Apply a license template' click_link template wait_for_ajax end diff --git a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb index 87322ac2584..1a1910455a1 100644 --- a/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb +++ b/spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb @@ -30,7 +30,7 @@ feature 'project owner sees a link to create a license file in empty project', f fill_in :commit_message, with: 'Add a LICENSE file', visible: true # Remove pre-receive hook so we can push without auth FileUtils.rm_f(File.join(project.repository.path, 'hooks', 'pre-receive')) - click_button 'Commit Changes' + click_button 'Commit changes' expect(current_path).to eq( namespace_project_blob_path(project.namespace, project, 'master/LICENSE')) @@ -40,7 +40,7 @@ feature 'project owner sees a link to create a license file in empty project', f def select_template(template) page.within('.js-license-selector-wrap') do - click_button 'Apply a License template' + click_button 'Apply a license template' click_link template wait_for_ajax end diff --git a/spec/features/projects/files/template_type_dropdown_spec.rb b/spec/features/projects/files/template_type_dropdown_spec.rb index 5ee5e5b4c4e..9fcf12e6cb9 100644 --- a/spec/features/projects/files/template_type_dropdown_spec.rb +++ b/spec/features/projects/files/template_type_dropdown_spec.rb @@ -48,7 +48,7 @@ feature 'Template type dropdown selector', js: true do context 'user previews changes' do before do - click_link 'Preview Changes' + click_link 'Preview changes' end scenario 'type selector is hidden and shown correctly' do @@ -102,7 +102,7 @@ def check_type_selector_display(is_visible) end def try_selecting_all_types - try_selecting_template_type('LICENSE', 'Apply a License template') + try_selecting_template_type('LICENSE', 'Apply a license template') try_selecting_template_type('Dockerfile', 'Apply a Dockerfile template') try_selecting_template_type('.gitlab-ci.yml', 'Apply a GitLab CI Yaml template') try_selecting_template_type('.gitignore', 'Apply a .gitignore template') @@ -130,6 +130,6 @@ end def create_and_edit_file(file_name) visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: file_name) - click_button "Commit Changes" + click_button "Commit changes" visit namespace_project_edit_blob_path(project.namespace, project, File.join(project.default_branch, file_name)) end diff --git a/spec/features/projects/files/undo_template_spec.rb b/spec/features/projects/files/undo_template_spec.rb index 5479ea34610..c51851d3f94 100644 --- a/spec/features/projects/files/undo_template_spec.rb +++ b/spec/features/projects/files/undo_template_spec.rb @@ -17,7 +17,7 @@ feature 'Template Undo Button', js: true do end scenario 'reverts template application' do - try_template_undo('http://www.apache.org/licenses/', 'Apply a License template') + try_template_undo('http://www.apache.org/licenses/', 'Apply a license template') end end @@ -29,7 +29,7 @@ feature 'Template Undo Button', js: true do end scenario 'reverts template application' do - try_template_undo('http://www.apache.org/licenses/', 'Apply a License template') + try_template_undo('http://www.apache.org/licenses/', 'Apply a license template') end end end diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb index 2d1106ea3e8..583f479ec18 100644 --- a/spec/features/projects/import_export/import_file_spec.rb +++ b/spec/features/projects/import_export/import_file_spec.rb @@ -69,12 +69,8 @@ feature 'Import/Export - project import integration test', feature: true, js: tr select2(namespace.id, from: '#project_namespace_id') - # click on disabled element - find(:link, 'GitLab export').trigger('click') - - page.within('.flash-container') do - expect(page).to have_content('Please enter path and name') - end + # Check for tooltip disabled import button + expect(find('.import_gitlab_project')['title']).to eq('Please enter a valid project name.') end end diff --git a/spec/features/projects/merge_request_button_spec.rb b/spec/features/projects/merge_request_button_spec.rb index b6728960fb8..05f3162f13c 100644 --- a/spec/features/projects/merge_request_button_spec.rb +++ b/spec/features/projects/merge_request_button_spec.rb @@ -1,13 +1,13 @@ require 'spec_helper' feature 'Merge Request button', feature: true do - shared_examples 'Merge Request button only shown when allowed' do + shared_examples 'Merge request button only shown when allowed' do let(:user) { create(:user) } let(:project) { create(:project, :public) } let(:forked_project) { create(:project, :public, forked_from_project: project) } context 'not logged in' do - it 'does not show Create Merge Request button' do + it 'does not show Create merge request button' do visit url within("#content-body") do @@ -22,7 +22,7 @@ feature 'Merge Request button', feature: true do project.team << [user, :developer] end - it 'shows Create Merge Request button' do + it 'shows Create merge request button' do href = new_namespace_project_merge_request_path(project.namespace, project, merge_request: { source_branch: 'feature', @@ -40,7 +40,7 @@ feature 'Merge Request button', feature: true do project.project_feature.update!(merge_requests_access_level: ProjectFeature::DISABLED) end - it 'does not show Create Merge Request button' do + it 'does not show Create merge request button' do visit url within("#content-body") do @@ -55,7 +55,7 @@ feature 'Merge Request button', feature: true do login_as(user) end - it 'does not show Create Merge Request button' do + it 'does not show Create merge request button' do visit url within("#content-body") do @@ -66,7 +66,7 @@ feature 'Merge Request button', feature: true do context 'on own fork of project' do let(:user) { forked_project.owner } - it 'shows Create Merge Request button' do + it 'shows Create merge request button' do href = new_namespace_project_merge_request_path(forked_project.namespace, forked_project, merge_request: { source_branch: 'feature', @@ -83,24 +83,24 @@ feature 'Merge Request button', feature: true do end context 'on branches page' do - it_behaves_like 'Merge Request button only shown when allowed' do - let(:label) { 'Merge Request' } + it_behaves_like 'Merge request button only shown when allowed' do + let(:label) { 'Merge request' } let(:url) { namespace_project_branches_path(project.namespace, project) } let(:fork_url) { namespace_project_branches_path(forked_project.namespace, forked_project) } end end context 'on compare page' do - it_behaves_like 'Merge Request button only shown when allowed' do - let(:label) { 'Create Merge Request' } + it_behaves_like 'Merge request button only shown when allowed' do + let(:label) { 'Create merge request' } let(:url) { namespace_project_compare_path(project.namespace, project, from: 'master', to: 'feature') } let(:fork_url) { namespace_project_compare_path(forked_project.namespace, forked_project, from: 'master', to: 'feature') } end end context 'on commits page' do - it_behaves_like 'Merge Request button only shown when allowed' do - let(:label) { 'Create Merge Request' } + it_behaves_like 'Merge request button only shown when allowed' do + let(:label) { 'Create merge request' } let(:url) { namespace_project_commits_path(project.namespace, project, 'feature') } let(:fork_url) { namespace_project_commits_path(forked_project.namespace, forked_project, 'feature') } end diff --git a/spec/features/projects/merge_requests/list_spec.rb b/spec/features/projects/merge_requests/list_spec.rb index 5dd58ad66a7..7e8a796c55d 100644 --- a/spec/features/projects/merge_requests/list_spec.rb +++ b/spec/features/projects/merge_requests/list_spec.rb @@ -17,4 +17,28 @@ feature 'Merge Requests List' do expect(page).not_to have_selector('.js-new-board-list') end + + it 'should show an empty state' do + visit namespace_project_merge_requests_path(project.namespace, project) + + expect(page).to have_selector('.empty-state') + end + + it 'empty state should have a create merge request button' do + visit namespace_project_merge_requests_path(project.namespace, project) + + expect(page).to have_link 'New merge request', href: new_namespace_project_merge_request_path(project.namespace, project) + end + + context 'if there are merge requests' do + before do + create(:merge_request, assignee: user, source_project: project) + + visit namespace_project_merge_requests_path(project.namespace, project) + end + + it 'should not show an empty state' do + expect(page).not_to have_selector('.empty-state') + end + end end diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb index 52196ce49bd..c66b9a34b86 100644 --- a/spec/features/projects/new_project_spec.rb +++ b/spec/features/projects/new_project_spec.rb @@ -71,6 +71,22 @@ feature "New project", feature: true do end end end + + context "with subgroup namespace" do + let(:group) { create(:group, :private, owner: user) } + let(:subgroup) { create(:group, parent: group) } + + before do + group.add_master(user) + visit new_project_path(namespace_id: subgroup.id) + end + + it "selects the group namespace" do + namespace = find("#project_namespace_id option[selected]") + + expect(namespace.text).to eq subgroup.full_path + end + end end context 'Import project options' do diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb index 76cb240ea98..035c57eaa47 100644 --- a/spec/features/projects/settings/pipelines_settings_spec.rb +++ b/spec/features/projects/settings/pipelines_settings_spec.rb @@ -32,5 +32,16 @@ feature "Pipelines settings", feature: true do expect(page).to have_button('Save changes', disabled: false) expect(page).to have_field('Test coverage parsing', with: 'coverage_regex') end + + scenario 'updates auto_cancel_pending_pipelines' do + page.check('Auto-cancel redundant, pending pipelines') + click_on 'Save changes' + + expect(page.status_code).to eq(200) + expect(page).to have_button('Save changes', disabled: false) + + checkbox = find_field('project_auto_cancel_pending_pipelines') + expect(checkbox).to be_checked + end end end diff --git a/spec/features/projects/wiki/markdown_preview_spec.rb b/spec/features/projects/wiki/markdown_preview_spec.rb index a1c386ddc18..43d8b45669e 100644 --- a/spec/features/projects/wiki/markdown_preview_spec.rb +++ b/spec/features/projects/wiki/markdown_preview_spec.rb @@ -24,12 +24,16 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t context "while creating a new wiki page" do context "when there are no spaces or hyphens in the page name" do it "rewrites relative links as expected" do - click_link 'New Page' - fill_in :new_wiki_path, with: 'a/b/c/d' - click_button 'Create Page' + click_link 'New page' + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: 'a/b/c/d' + click_button 'Create page' + end - fill_in :wiki_content, with: wiki_content - click_on "Preview" + page.within '.wiki-form' do + fill_in :wiki_content, with: wiki_content + click_on "Preview" + end expect(page).to have_content("regular link") @@ -42,12 +46,16 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t context "when there are spaces in the page name" do it "rewrites relative links as expected" do - click_link 'New Page' - fill_in :new_wiki_path, with: 'a page/b page/c page/d page' - click_button 'Create Page' + click_link 'New page' + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: 'a page/b page/c page/d page' + click_button 'Create page' + end - fill_in :wiki_content, with: wiki_content - click_on "Preview" + page.within '.wiki-form' do + fill_in :wiki_content, with: wiki_content + click_on "Preview" + end expect(page).to have_content("regular link") @@ -60,12 +68,16 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t context "when there are hyphens in the page name" do it "rewrites relative links as expected" do - click_link 'New Page' - fill_in :new_wiki_path, with: 'a-page/b-page/c-page/d-page' - click_button 'Create Page' - - fill_in :wiki_content, with: wiki_content - click_on "Preview" + click_link 'New page' + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: 'a-page/b-page/c-page/d-page' + click_button 'Create page' + end + + page.within '.wiki-form' do + fill_in :wiki_content, with: wiki_content + click_on "Preview" + end expect(page).to have_content("regular link") @@ -79,11 +91,17 @@ feature 'Projects > Wiki > User previews markdown changes', feature: true, js: t context "while editing a wiki page" do def create_wiki_page(path) - click_link 'New Page' - fill_in :new_wiki_path, with: path - click_button 'Create Page' - fill_in :wiki_content, with: 'content' - click_on "Create page" + click_link 'New page' + + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: path + click_button 'Create page' + end + + page.within '.wiki-form' do + fill_in :wiki_content, with: 'content' + click_on "Create page" + end end context "when there are no spaces or hyphens in the page name" do diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb index fff8b9f3447..1ffac8cd542 100644 --- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb @@ -15,10 +15,15 @@ feature 'Projects > Wiki > User creates wiki page', feature: true do let(:project) { create(:project, namespace: user.namespace) } context 'when wiki is empty' do + scenario 'commit message field has value "Create home"' do + expect(page).to have_field('wiki[message]', with: 'Create home') + end + scenario 'directly from the wiki home page' do fill_in :wiki_content, with: 'My awesome wiki!' - click_button 'Create page' - + page.within '.wiki-form' do + click_button 'Create page' + end expect(page).to have_content('Home') expect(page).to have_content("Last edited by #{user.name}") expect(page).to have_content('My awesome wiki!') @@ -32,13 +37,20 @@ feature 'Projects > Wiki > User creates wiki page', feature: true do context 'via the "new wiki page" page' do scenario 'when the wiki page has a single word name', js: true do - click_link 'New Page' + click_link 'New page' - fill_in :new_wiki_path, with: 'foo' - click_button 'Create Page' + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: 'foo' + click_button 'Create page' + end - fill_in :wiki_content, with: 'My awesome wiki!' - click_button 'Create page' + # Commit message field should have correct value. + expect(page).to have_field('wiki[message]', with: 'Create foo') + + page.within '.wiki-form' do + fill_in :wiki_content, with: 'My awesome wiki!' + click_button 'Create page' + end expect(page).to have_content('Foo') expect(page).to have_content("Last edited by #{user.name}") @@ -46,13 +58,20 @@ feature 'Projects > Wiki > User creates wiki page', feature: true do end scenario 'when the wiki page has spaces in the name', js: true do - click_link 'New Page' + click_link 'New page' - fill_in :new_wiki_path, with: 'Spaces in the name' - click_button 'Create Page' + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: 'Spaces in the name' + click_button 'Create page' + end - fill_in :wiki_content, with: 'My awesome wiki!' - click_button 'Create page' + # Commit message field should have correct value. + expect(page).to have_field('wiki[message]', with: 'Create spaces in the name') + + page.within '.wiki-form' do + fill_in :wiki_content, with: 'My awesome wiki!' + click_button 'Create page' + end expect(page).to have_content('Spaces in the name') expect(page).to have_content("Last edited by #{user.name}") @@ -60,13 +79,20 @@ feature 'Projects > Wiki > User creates wiki page', feature: true do end scenario 'when the wiki page has hyphens in the name', js: true do - click_link 'New Page' + click_link 'New page' - fill_in :new_wiki_path, with: 'hyphens-in-the-name' - click_button 'Create Page' + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: 'hyphens-in-the-name' + click_button 'Create page' + end - fill_in :wiki_content, with: 'My awesome wiki!' - click_button 'Create page' + # Commit message field should have correct value. + expect(page).to have_field('wiki[message]', with: 'Create hyphens in the name') + + page.within '.wiki-form' do + fill_in :wiki_content, with: 'My awesome wiki!' + click_button 'Create page' + end expect(page).to have_content('Hyphens in the name') expect(page).to have_content("Last edited by #{user.name}") @@ -80,9 +106,15 @@ feature 'Projects > Wiki > User creates wiki page', feature: true do let(:project) { create(:project, namespace: create(:group, :public)) } context 'when wiki is empty' do + scenario 'commit message field has value "Create home"' do + expect(page).to have_field('wiki[message]', with: 'Create home') + end + scenario 'directly from the wiki home page' do fill_in :wiki_content, with: 'My awesome wiki!' - click_button 'Create page' + page.within '.wiki-form' do + click_button 'Create page' + end expect(page).to have_content('Home') expect(page).to have_content("Last edited by #{user.name}") @@ -96,13 +128,20 @@ feature 'Projects > Wiki > User creates wiki page', feature: true do end scenario 'via the "new wiki page" page', js: true do - click_link 'New Page' + click_link 'New page' - fill_in :new_wiki_path, with: 'foo' - click_button 'Create Page' + page.within '#modal-new-wiki' do + fill_in :new_wiki_path, with: 'foo' + click_button 'Create page' + end - fill_in :wiki_content, with: 'My awesome wiki!' - click_button 'Create page' + # Commit message field should have correct value. + expect(page).to have_field('wiki[message]', with: 'Create foo') + + page.within '.wiki-form' do + fill_in :wiki_content, with: 'My awesome wiki!' + click_button 'Create page' + end expect(page).to have_content('Foo') expect(page).to have_content("Last edited by #{user.name}") diff --git a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb index aedc0333cb9..86cf520ea80 100644 --- a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb @@ -19,6 +19,9 @@ feature 'Projects > Wiki > User updates wiki page', feature: true do scenario 'success when the wiki content is not empty' do click_link 'Edit' + # Commit message field should have correct value. + expect(page).to have_field('wiki[message]', with: 'Update home') + fill_in :wiki_content, with: 'My awesome wiki!' click_button 'Save changes' @@ -48,6 +51,9 @@ feature 'Projects > Wiki > User updates wiki page', feature: true do scenario 'the home page' do click_link 'Edit' + # Commit message field should have correct value. + expect(page).to have_field('wiki[message]', with: 'Update home') + fill_in :wiki_content, with: 'My awesome wiki!' click_button 'Save changes' diff --git a/spec/features/protected_branches/access_control_ce_spec.rb b/spec/features/protected_branches/access_control_ce_spec.rb index e4aca25a339..eb3cea775da 100644 --- a/spec/features/protected_branches/access_control_ce_spec.rb +++ b/spec/features/protected_branches/access_control_ce_spec.rb @@ -2,7 +2,9 @@ RSpec.shared_examples "protected branches > access control > CE" do ProtectedBranch::PushAccessLevel.human_access_levels.each do |(access_type_id, access_type_name)| it "allows creating protected branches that #{access_type_name} can push to" do visit namespace_project_protected_branches_path(project.namespace, project) + set_protected_branch_name('master') + within('.new_protected_branch') do allowed_to_push_button = find(".js-allowed-to-push") @@ -11,6 +13,7 @@ RSpec.shared_examples "protected branches > access control > CE" do within(".dropdown.open .dropdown-menu") { click_on access_type_name } end end + click_on "Protect" expect(ProtectedBranch.count).to eq(1) @@ -19,7 +22,9 @@ RSpec.shared_examples "protected branches > access control > CE" do it "allows updating protected branches so that #{access_type_name} can push to them" do visit namespace_project_protected_branches_path(project.namespace, project) + set_protected_branch_name('master') + click_on "Protect" expect(ProtectedBranch.count).to eq(1) @@ -34,6 +39,7 @@ RSpec.shared_examples "protected branches > access control > CE" do end wait_for_ajax + expect(ProtectedBranch.last.push_access_levels.map(&:access_level)).to include(access_type_id) end end @@ -41,7 +47,9 @@ RSpec.shared_examples "protected branches > access control > CE" do ProtectedBranch::MergeAccessLevel.human_access_levels.each do |(access_type_id, access_type_name)| it "allows creating protected branches that #{access_type_name} can merge to" do visit namespace_project_protected_branches_path(project.namespace, project) + set_protected_branch_name('master') + within('.new_protected_branch') do allowed_to_merge_button = find(".js-allowed-to-merge") @@ -50,6 +58,7 @@ RSpec.shared_examples "protected branches > access control > CE" do within(".dropdown.open .dropdown-menu") { click_on access_type_name } end end + click_on "Protect" expect(ProtectedBranch.count).to eq(1) @@ -58,7 +67,9 @@ RSpec.shared_examples "protected branches > access control > CE" do it "allows updating protected branches so that #{access_type_name} can merge to them" do visit namespace_project_protected_branches_path(project.namespace, project) + set_protected_branch_name('master') + click_on "Protect" expect(ProtectedBranch.count).to eq(1) @@ -73,6 +84,7 @@ RSpec.shared_examples "protected branches > access control > CE" do end wait_for_ajax + expect(ProtectedBranch.last.merge_access_levels.map(&:access_level)).to include(access_type_id) end end diff --git a/spec/features/protected_tags/access_control_ce_spec.rb b/spec/features/protected_tags/access_control_ce_spec.rb new file mode 100644 index 00000000000..5b2baf8616c --- /dev/null +++ b/spec/features/protected_tags/access_control_ce_spec.rb @@ -0,0 +1,46 @@ +RSpec.shared_examples "protected tags > access control > CE" do + ProtectedTag::CreateAccessLevel.human_access_levels.each do |(access_type_id, access_type_name)| + it "allows creating protected tags that #{access_type_name} can create" do + visit namespace_project_protected_tags_path(project.namespace, project) + + set_protected_tag_name('master') + + within('.js-new-protected-tag') do + allowed_to_create_button = find(".js-allowed-to-create") + + unless allowed_to_create_button.text == access_type_name + allowed_to_create_button.click + within(".dropdown.open .dropdown-menu") { click_on access_type_name } + end + end + + click_on "Protect" + + expect(ProtectedTag.count).to eq(1) + expect(ProtectedTag.last.create_access_levels.map(&:access_level)).to eq([access_type_id]) + end + + it "allows updating protected tags so that #{access_type_name} can create them" do + visit namespace_project_protected_tags_path(project.namespace, project) + + set_protected_tag_name('master') + + click_on "Protect" + + expect(ProtectedTag.count).to eq(1) + + within(".protected-tags-list") do + find(".js-allowed-to-create").click + + within('.js-allowed-to-create-container') do + expect(first("li")).to have_content("Roles") + click_on access_type_name + end + end + + wait_for_ajax + + expect(ProtectedTag.last.create_access_levels.map(&:access_level)).to include(access_type_id) + end + end +end diff --git a/spec/features/protected_tags_spec.rb b/spec/features/protected_tags_spec.rb new file mode 100644 index 00000000000..09e8c850de3 --- /dev/null +++ b/spec/features/protected_tags_spec.rb @@ -0,0 +1,94 @@ +require 'spec_helper' +Dir["./spec/features/protected_tags/*.rb"].sort.each { |f| require f } + +feature 'Projected Tags', feature: true, js: true do + include WaitForAjax + + let(:user) { create(:user, :admin) } + let(:project) { create(:project) } + + before { login_as(user) } + + def set_protected_tag_name(tag_name) + find(".js-protected-tag-select").click + find(".dropdown-input-field").set(tag_name) + click_on("Create wildcard #{tag_name}") + end + + describe "explicit protected tags" do + it "allows creating explicit protected tags" do + visit namespace_project_protected_tags_path(project.namespace, project) + set_protected_tag_name('some-tag') + click_on "Protect" + + within(".protected-tags-list") { expect(page).to have_content('some-tag') } + expect(ProtectedTag.count).to eq(1) + expect(ProtectedTag.last.name).to eq('some-tag') + end + + it "displays the last commit on the matching tag if it exists" do + commit = create(:commit, project: project) + project.repository.add_tag(user, 'some-tag', commit.id) + + visit namespace_project_protected_tags_path(project.namespace, project) + set_protected_tag_name('some-tag') + click_on "Protect" + + within(".protected-tags-list") { expect(page).to have_content(commit.id[0..7]) } + end + + it "displays an error message if the named tag does not exist" do + visit namespace_project_protected_tags_path(project.namespace, project) + set_protected_tag_name('some-tag') + click_on "Protect" + + within(".protected-tags-list") { expect(page).to have_content('tag was removed') } + end + end + + describe "wildcard protected tags" do + it "allows creating protected tags with a wildcard" do + visit namespace_project_protected_tags_path(project.namespace, project) + set_protected_tag_name('*-stable') + click_on "Protect" + + within(".protected-tags-list") { expect(page).to have_content('*-stable') } + expect(ProtectedTag.count).to eq(1) + expect(ProtectedTag.last.name).to eq('*-stable') + end + + it "displays the number of matching tags" do + project.repository.add_tag(user, 'production-stable', 'master') + project.repository.add_tag(user, 'staging-stable', 'master') + + visit namespace_project_protected_tags_path(project.namespace, project) + set_protected_tag_name('*-stable') + click_on "Protect" + + within(".protected-tags-list") { expect(page).to have_content("2 matching tags") } + end + + it "displays all the tags matching the wildcard" do + project.repository.add_tag(user, 'production-stable', 'master') + project.repository.add_tag(user, 'staging-stable', 'master') + project.repository.add_tag(user, 'development', 'master') + + visit namespace_project_protected_tags_path(project.namespace, project) + set_protected_tag_name('*-stable') + click_on "Protect" + + visit namespace_project_protected_tags_path(project.namespace, project) + click_on "2 matching tags" + + within(".protected-tags-list") do + expect(page).to have_content("production-stable") + expect(page).to have_content("staging-stable") + expect(page).not_to have_content("development") + end + end + end + + describe "access control" do + include_examples "protected tags > access control > CE" + end +end diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb index a6560a81096..e8ad28a00f0 100644 --- a/spec/features/search_spec.rb +++ b/spec/features/search_spec.rb @@ -119,13 +119,15 @@ describe "Search", feature: true do visit namespace_project_path(project.namespace, project) page.within '.search' do - fill_in 'search', with: 'def' + fill_in 'search', with: 'application.js' click_button 'Go' end click_link "Code" expect(page).to have_selector('.file-content .code') + + expect(page).to have_selector("span.line[lang='javascript']") end end @@ -162,6 +164,8 @@ describe "Search", feature: true do end context 'click the links in the category search dropdown', js: true do + let!(:merge_request) { create(:merge_request, source_project: project, author: user, assignee: user) } + before do page.find('#search').click end diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb index 1a66d1a6a1e..6ecdc8cbb71 100644 --- a/spec/features/security/project/internal_access_spec.rb +++ b/spec/features/security/project/internal_access_spec.rb @@ -443,9 +443,12 @@ describe "Internal Project Access", feature: true do end describe "GET /:project_path/container_registry" do + let(:container_repository) { create(:container_repository) } + before do - stub_container_registry_tags('latest') + stub_container_registry_tags(repository: :any, tags: ['latest']) stub_container_registry_config(enabled: true) + project.container_repositories << container_repository end subject { namespace_project_container_registry_index_path(project.namespace, project) } diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb index ad3bd60a313..a8fc0624588 100644 --- a/spec/features/security/project/private_access_spec.rb +++ b/spec/features/security/project/private_access_spec.rb @@ -432,9 +432,12 @@ describe "Private Project Access", feature: true do end describe "GET /:project_path/container_registry" do + let(:container_repository) { create(:container_repository) } + before do - stub_container_registry_tags('latest') + stub_container_registry_tags(repository: :any, tags: ['latest']) stub_container_registry_config(enabled: true) + project.container_repositories << container_repository end subject { namespace_project_container_registry_index_path(project.namespace, project) } diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb index e06aab4e0b2..c4d2f50ca14 100644 --- a/spec/features/security/project/public_access_spec.rb +++ b/spec/features/security/project/public_access_spec.rb @@ -443,9 +443,12 @@ describe "Public Project Access", feature: true do end describe "GET /:project_path/container_registry" do + let(:container_repository) { create(:container_repository) } + before do - stub_container_registry_tags('latest') + stub_container_registry_tags(repository: :any, tags: ['latest']) stub_container_registry_config(enabled: true) + project.container_repositories << container_repository end subject { namespace_project_container_registry_index_path(project.namespace, project) } diff --git a/spec/features/tags/master_views_tags_spec.rb b/spec/features/tags/master_views_tags_spec.rb index 555f84c4772..922ac15a2eb 100644 --- a/spec/features/tags/master_views_tags_spec.rb +++ b/spec/features/tags/master_views_tags_spec.rb @@ -16,7 +16,7 @@ feature 'Master views tags', feature: true do fill_in :commit_message, with: 'Add a README file', visible: true # Remove pre-receive hook so we can push without auth FileUtils.rm_f(File.join(project.repository.path, 'hooks', 'pre-receive')) - click_button 'Commit Changes' + click_button 'Commit changes' visit namespace_project_tags_path(project.namespace, project) end diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb index c1ae6db00c6..81fa2de1cc3 100644 --- a/spec/features/triggers_spec.rb +++ b/spec/features/triggers_spec.rb @@ -77,6 +77,59 @@ feature 'Triggers', feature: true, js: true do expect(page.find('.flash-notice')).to have_content 'Trigger was successfully updated.' expect(page.find('.triggers-list')).to have_content new_trigger_title end + + context 'scheduled triggers' do + let!(:trigger) do + create(:ci_trigger, owner: user, project: @project, description: trigger_title) + end + + context 'enabling schedule' do + before do + visit edit_namespace_project_trigger_path(@project.namespace, @project, trigger) + end + + scenario 'do fill form with valid data and save' do + find('#trigger_trigger_schedule_attributes_active').click + fill_in 'trigger_trigger_schedule_attributes_cron', with: '1 * * * *' + fill_in 'trigger_trigger_schedule_attributes_cron_timezone', with: 'UTC' + fill_in 'trigger_trigger_schedule_attributes_ref', with: 'master' + click_button 'Save trigger' + + expect(page.find('.flash-notice')).to have_content 'Trigger was successfully updated.' + end + + scenario 'do not fill form with valid data and save' do + find('#trigger_trigger_schedule_attributes_active').click + click_button 'Save trigger' + + expect(page).to have_content 'The form contains the following errors' + end + end + + context 'disabling schedule' do + before do + trigger.create_trigger_schedule( + project: trigger.project, + active: true, + ref: 'master', + cron: '1 * * * *', + cron_timezone: 'UTC') + + visit edit_namespace_project_trigger_path(@project.namespace, @project, trigger) + end + + scenario 'disable and save form' do + find('#trigger_trigger_schedule_attributes_active').click + click_button 'Save trigger' + expect(page.find('.flash-notice')).to have_content 'Trigger was successfully updated.' + + visit edit_namespace_project_trigger_path(@project.namespace, @project, trigger) + checkbox = find_field('trigger_trigger_schedule_attributes_active') + + expect(checkbox).not_to be_checked + end + end + end end describe 'trigger "Take ownership" workflow' do diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb index 28373098123..c877cfdd978 100644 --- a/spec/features/u2f_spec.rb +++ b/spec/features/u2f_spec.rb @@ -6,18 +6,18 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do before { allow_any_instance_of(U2fHelper).to receive(:inject_u2f_api?).and_return(true) } def manage_two_factor_authentication - click_on 'Manage Two-Factor Authentication' - expect(page).to have_content("Setup New U2F Device") + click_on 'Manage two-factor authentication' + expect(page).to have_content("Setup new U2F device") wait_for_ajax end def register_u2f_device(u2f_device = nil, name: 'My device') u2f_device ||= FakeU2fDevice.new(page, name) u2f_device.respond_to_u2f_registration - click_on 'Setup New U2F Device' + click_on 'Setup new U2F device' expect(page).to have_content('Your device was successfully set up') fill_in "Pick a name", with: name - click_on 'Register U2F Device' + click_on 'Register U2F device' u2f_device end @@ -34,9 +34,9 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do it 'does not allow registering a new device' do visit profile_account_path - click_on 'Enable Two-Factor Authentication' + click_on 'Enable two-factor authentication' - expect(page).to have_button('Setup New U2F Device', disabled: true) + expect(page).to have_button('Setup new U2F device', disabled: true) end end @@ -111,9 +111,9 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do # Have the "u2f device" respond with bad data page.execute_script("u2f.register = function(_,_,_,callback) { callback('bad response'); };") - click_on 'Setup New U2F Device' + click_on 'Setup new U2F device' expect(page).to have_content('Your device was successfully set up') - click_on 'Register U2F Device' + click_on 'Register U2F device' expect(U2fRegistration.count).to eq(0) expect(page).to have_content("The form contains the following error") @@ -126,9 +126,9 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do # Failed registration page.execute_script("u2f.register = function(_,_,_,callback) { callback('bad response'); };") - click_on 'Setup New U2F Device' + click_on 'Setup new U2F device' expect(page).to have_content('Your device was successfully set up') - click_on 'Register U2F Device' + click_on 'Register U2F device' expect(page).to have_content("The form contains the following error") # Successful registration |