diff options
author | Ruben Davila <rdavila84@gmail.com> | 2017-05-02 21:20:41 +0300 |
---|---|---|
committer | Ruben Davila <rdavila84@gmail.com> | 2017-05-02 21:20:41 +0300 |
commit | bbfbcebdf69261bac6aa142f430719955e8e86b9 (patch) | |
tree | 25916a1a761cb6c8fcdac4b20b76017a7f4506d3 /spec/features | |
parent | 3b82444eb7791e58e3e0ba2f08b8ccde48e3d4c6 (diff) | |
parent | 920d55b9f8afd35e16351fb57d671acf66092e89 (diff) |
Merge branch 'master' into 28433-internationalise-cycle-analytics-page
Diffstat (limited to 'spec/features')
113 files changed, 1534 insertions, 242 deletions
diff --git a/spec/features/admin/admin_cohorts_spec.rb b/spec/features/admin/admin_cohorts_spec.rb new file mode 100644 index 00000000000..dd14ffdb2ce --- /dev/null +++ b/spec/features/admin/admin_cohorts_spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +feature 'Admin cohorts page', feature: true do + before do + login_as :admin + end + + scenario 'See users count per month' do + 2.times { create(:user) } + + visit admin_cohorts_path + + expect(page).to have_content("#{Time.now.strftime('%b %Y')} 3 0") + end +end diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb index fb519a9bf12..c5f24d412d7 100644 --- a/spec/features/admin/admin_hooks_spec.rb +++ b/spec/features/admin/admin_hooks_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe "Admin::Hooks", feature: true do +describe 'Admin::Hooks', feature: true do before do @project = create(:project) login_as :admin @@ -8,24 +8,24 @@ describe "Admin::Hooks", feature: true do @system_hook = create(:system_hook) end - describe "GET /admin/hooks" do - it "is ok" do + describe 'GET /admin/hooks' do + it 'is ok' do visit admin_root_path - page.within ".layout-nav" do - click_on "Hooks" + page.within '.layout-nav' do + click_on 'Hooks' end expect(current_path).to eq(admin_hooks_path) end - it "has hooks list" do + it 'has hooks list' do visit admin_hooks_path expect(page).to have_content(@system_hook.url) end end - describe "New Hook" do + describe 'New Hook' do let(:url) { generate(:url) } it 'adds new hook' do @@ -40,11 +40,36 @@ describe "Admin::Hooks", feature: true do end end - describe "Test" do + describe 'Update existing hook' do + let(:new_url) { generate(:url) } + + it 'updates existing hook' do + visit admin_hooks_path + + click_link 'Edit' + fill_in 'hook_url', with: new_url + check 'Enable SSL verification' + click_button 'Save changes' + + expect(page).to have_content 'SSL Verification: enabled' + expect(current_path).to eq(admin_hooks_path) + expect(page).to have_content(new_url) + end + end + + describe 'Remove existing hook' do + it 'remove existing hook' do + visit admin_hooks_path + + expect { click_link 'Remove' }.to change(SystemHook, :count).by(-1) + end + end + + describe 'Test' 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_labels_spec.rb b/spec/features/admin/admin_labels_spec.rb index 6d6c9165c83..fa3d9ee25c0 100644 --- a/spec/features/admin/admin_labels_spec.rb +++ b/spec/features/admin/admin_labels_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' RSpec.describe 'admin issues labels' do - include WaitForAjax - let!(:bug_label) { Label.create(title: 'bug', template: true) } let!(:feature_label) { Label.create(title: 'feature', template: true) } diff --git a/spec/features/admin/admin_requests_profiles_spec.rb b/spec/features/admin/admin_requests_profiles_spec.rb new file mode 100644 index 00000000000..e8ecb70306b --- /dev/null +++ b/spec/features/admin/admin_requests_profiles_spec.rb @@ -0,0 +1,69 @@ +require 'spec_helper' + +describe 'Admin::RequestsProfilesController', feature: true do + before do + FileUtils.mkdir_p(Gitlab::RequestProfiler::PROFILES_DIR) + login_as(:admin) + end + + after do + Gitlab::RequestProfiler.remove_all_profiles + end + + describe 'GET /admin/requests_profiles' do + it 'shows the current profile token' do + allow(Rails).to receive(:cache).and_return(ActiveSupport::Cache::MemoryStore.new) + + visit admin_requests_profiles_path + + expect(page).to have_content("X-Profile-Token: #{Gitlab::RequestProfiler.profile_token}") + end + + it 'lists all available profiles' do + time1 = 1.hour.ago + time2 = 2.hours.ago + time3 = 3.hours.ago + profile1 = "|gitlab-org|gitlab-ce_#{time1.to_i}.html" + profile2 = "|gitlab-org|gitlab-ce_#{time2.to_i}.html" + profile3 = "|gitlab-com|infrastructure_#{time3.to_i}.html" + + FileUtils.touch("#{Gitlab::RequestProfiler::PROFILES_DIR}/#{profile1}") + FileUtils.touch("#{Gitlab::RequestProfiler::PROFILES_DIR}/#{profile2}") + FileUtils.touch("#{Gitlab::RequestProfiler::PROFILES_DIR}/#{profile3}") + + visit admin_requests_profiles_path + + within('.panel', text: '/gitlab-org/gitlab-ce') do + expect(page).to have_selector("a[href='#{admin_requests_profile_path(profile1)}']", text: time1.to_s(:long)) + expect(page).to have_selector("a[href='#{admin_requests_profile_path(profile2)}']", text: time2.to_s(:long)) + end + + within('.panel', text: '/gitlab-com/infrastructure') do + expect(page).to have_selector("a[href='#{admin_requests_profile_path(profile3)}']", text: time3.to_s(:long)) + end + end + end + + describe 'GET /admin/requests_profiles/:profile' do + context 'when a profile exists' do + it 'displays the content of the profile' do + content = 'This is a request profile' + profile = "|gitlab-org|gitlab-ce_#{Time.now.to_i}.html" + + File.write("#{Gitlab::RequestProfiler::PROFILES_DIR}/#{profile}", content) + + visit admin_requests_profile_path(profile) + + expect(page).to have_content(content) + end + end + + context 'when a profile does not exist' do + it 'shows an error message' do + visit admin_requests_profile_path('|non|existent_12345.html') + + expect(page).to have_content('Profile not found') + end + end + end +end diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb index f6c3bc6a58d..c5b1ef1295c 100644 --- a/spec/features/admin/admin_users_spec.rb +++ b/spec/features/admin/admin_users_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe "Admin::Users", feature: true do - include WaitForAjax - let!(:user) do create(:omniauth_user, provider: 'twitter', extern_uid: '123456') end diff --git a/spec/features/atom/users_spec.rb b/spec/features/atom/users_spec.rb index 55e10a1a89b..7a2987e815d 100644 --- a/spec/features/atom/users_spec.rb +++ b/spec/features/atom/users_spec.rb @@ -53,7 +53,7 @@ describe "User Feed", feature: true do end it 'has XHTML summaries in issue descriptions' do - expect(body).to match /we have a bug!<\/p>\n\n<hr ?\/>\n\n<p dir="auto">I guess/ + expect(body).to match /<hr ?\/>/ end it 'has XHTML summaries in notes' do diff --git a/spec/features/auto_deploy_spec.rb b/spec/features/auto_deploy_spec.rb index 6f36c74c911..67b0f006854 100644 --- a/spec/features/auto_deploy_spec.rb +++ b/spec/features/auto_deploy_spec.rb @@ -1,10 +1,8 @@ require 'spec_helper' describe 'Auto deploy' do - include WaitForAjax - let(:user) { create(:user) } - let(:project) { create(:project) } + let(:project) { create(:project, :repository) } before do project.create_kubernetes_service( diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb index 248c31115ad..505e0b5c355 100644 --- a/spec/features/boards/add_issues_modal_spec.rb +++ b/spec/features/boards/add_issues_modal_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' describe 'Issue Boards add issue modal', :feature, :js do - include WaitForAjax include WaitForVueResource let(:project) { create(:empty_project, :public) } diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 30ad169e30e..a172ce1e8c0 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' describe 'Issue Boards', feature: true, js: true do - include WaitForAjax include WaitForVueResource include DragTo diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb index e6d7cf106d4..f04a1a89e96 100644 --- a/spec/features/boards/new_issue_spec.rb +++ b/spec/features/boards/new_issue_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' describe 'Issue Boards new issue', feature: true, js: true do - include WaitForAjax include WaitForVueResource let(:project) { create(:empty_project, :public) } diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb index 3332e07ec31..bafa4f05937 100644 --- a/spec/features/boards/sidebar_spec.rb +++ b/spec/features/boards/sidebar_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' describe 'Issue Boards', feature: true, js: true do - include WaitForAjax include WaitForVueResource let(:user) { create(:user) } diff --git a/spec/features/calendar_spec.rb b/spec/features/calendar_spec.rb index 35d090c4b7f..496faf87a16 100644 --- a/spec/features/calendar_spec.rb +++ b/spec/features/calendar_spec.rb @@ -1,10 +1,8 @@ require 'spec_helper' feature 'Contributions Calendar', :feature, :js do - include WaitForAjax - let(:user) { create(:user) } - let(:contributed_project) { create(:project, :public) } + let(:contributed_project) { create(:empty_project, :public) } let(:issue_note) { create(:note, project: contributed_project) } # Ex/ Sunday Jan 1, 2016 diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb index 881f1fca4d1..e6c4ab24de5 100644 --- a/spec/features/commits_spec.rb +++ b/spec/features/commits_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe 'Commits' do include CiStatusHelper - let(:project) { create(:project) } + let(:project) { create(:project, :repository) } describe 'CI' do before do diff --git a/spec/features/copy_as_gfm_spec.rb b/spec/features/copy_as_gfm_spec.rb index 55df7e45f79..f197fb44608 100644 --- a/spec/features/copy_as_gfm_spec.rb +++ b/spec/features/copy_as_gfm_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'Copy as GFM', feature: true, js: true do - include GitlabMarkdownHelper + include MarkupHelper include RepoHelpers include ActionView::Helpers::JavaScriptHelper @@ -433,7 +433,7 @@ describe 'Copy as GFM', feature: true, js: true do end describe 'Copying code' do - let(:project) { create(:project) } + let(:project) { create(:project, :repository) } context 'from a diff' do before do @@ -479,6 +479,7 @@ describe 'Copy as GFM', feature: true, js: true do context 'from a blob' do before do visit namespace_project_blob_path(project.namespace, project, File.join('master', 'files/ruby/popen.rb')) + wait_for_ajax end context 'selecting one word of text' do @@ -520,6 +521,7 @@ describe 'Copy as GFM', feature: true, js: true do context 'from a GFM code block' do before do visit namespace_project_blob_path(project.namespace, project, File.join('markdown', 'doc/api/users.md')) + wait_for_ajax end context 'selecting one word of text' do diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb index 0648c89a5c7..b93275c330b 100644 --- a/spec/features/cycle_analytics_spec.rb +++ b/spec/features/cycle_analytics_spec.rb @@ -1,11 +1,9 @@ require 'spec_helper' feature 'Cycle Analytics', feature: true, js: true do - include WaitForAjax - let(:user) { create(:user) } let(:guest) { create(:user) } - let(:project) { create(:project) } + let(:project) { create(:project, :repository) } let(:issue) { create(:issue, project: project, created_at: 2.days.ago) } let(:milestone) { create(:milestone, project: project) } let(:mr) { create_merge_request_closing_issue(issue) } diff --git a/spec/features/dashboard/datetime_on_tooltips_spec.rb b/spec/features/dashboard/datetime_on_tooltips_spec.rb index dc9d09fa396..0e9e3f78be2 100644 --- a/spec/features/dashboard/datetime_on_tooltips_spec.rb +++ b/spec/features/dashboard/datetime_on_tooltips_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'Tooltips on .timeago dates', feature: true, js: true do - include WaitForAjax - let(:user) { create(:user) } let(:project) { create(:project, name: 'test', namespace: user.namespace) } let(:created_date) { Date.yesterday.to_time } diff --git a/spec/features/dashboard/groups_list_spec.rb b/spec/features/dashboard/groups_list_spec.rb index ca04107d33a..52b4d82e856 100644 --- a/spec/features/dashboard/groups_list_spec.rb +++ b/spec/features/dashboard/groups_list_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe 'Dashboard Groups page', js: true, feature: true do - include WaitForAjax - let!(:user) { create :user } let!(:group) { create(:group) } let!(:nested_group) { create(:group, :nested) } diff --git a/spec/features/dashboard/project_member_activity_index_spec.rb b/spec/features/dashboard/project_member_activity_index_spec.rb index 49d93db58a9..16c214ae060 100644 --- a/spec/features/dashboard/project_member_activity_index_spec.rb +++ b/spec/features/dashboard/project_member_activity_index_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'Project member activity', feature: true, js: true do - include WaitForAjax - let(:user) { create(:user) } let(:project) { create(:empty_project, :public, name: 'x', namespace: user.namespace) } diff --git a/spec/features/dashboard_issues_spec.rb b/spec/features/dashboard_issues_spec.rb index 8c61cdebc4b..b6b87905231 100644 --- a/spec/features/dashboard_issues_spec.rb +++ b/spec/features/dashboard_issues_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe "Dashboard Issues filtering", feature: true, js: true do let(:user) { create(:user) } - let(:project) { create(:project) } + let(:project) { create(:empty_project) } let(:milestone) { create(:milestone, project: project) } context 'filtering by milestone' do diff --git a/spec/features/expand_collapse_diffs_spec.rb b/spec/features/expand_collapse_diffs_spec.rb index 8c64b050e19..76c77e0bc5f 100644 --- a/spec/features/expand_collapse_diffs_spec.rb +++ b/spec/features/expand_collapse_diffs_spec.rb @@ -1,10 +1,8 @@ require 'spec_helper' feature 'Expand and collapse diffs', js: true, feature: true do - include WaitForAjax - let(:branch) { 'expand-collapse-diffs' } - let(:project) { create(:project) } + let(:project) { create(:project, :repository) } before do login_as :admin diff --git a/spec/features/explore/groups_list_spec.rb b/spec/features/explore/groups_list_spec.rb index 9daaaa8e555..9828cb179a7 100644 --- a/spec/features/explore/groups_list_spec.rb +++ b/spec/features/explore/groups_list_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' -describe 'Explore Groups page', js: true, feature: true do - include WaitForAjax - +describe 'Explore Groups page', :js, :feature do let!(:user) { create :user } let!(:group) { create(:group) } let!(:public_group) { create(:group, :public) } @@ -48,19 +46,39 @@ describe 'Explore Groups page', js: true, feature: true do it 'shows non-archived projects count' do # Initially project is not archived expect(find('.js-groups-list-holder .content-list li:first-child .stats span:first-child')).to have_text("1") - + # Archive project empty_project.archive! visit explore_groups_path # Check project count expect(find('.js-groups-list-holder .content-list li:first-child .stats span:first-child')).to have_text("0") - + # Unarchive project empty_project.unarchive! visit explore_groups_path # Check project count - expect(find('.js-groups-list-holder .content-list li:first-child .stats span:first-child')).to have_text("1") + expect(find('.js-groups-list-holder .content-list li:first-child .stats span:first-child')).to have_text("1") + end + + describe 'landing component' do + it 'should show a landing component' do + expect(page).to have_content('Below you will find all the groups that are public.') + end + + it 'should be dismissable' do + find('.dismiss-button').click + + expect(page).not_to have_content('Below you will find all the groups that are public.') + end + + it 'should persistently not show once dismissed' do + find('.dismiss-button').click + + visit explore_groups_path + + expect(page).not_to have_content('Below you will find all the groups that are public.') + end end end diff --git a/spec/features/gitlab_flavored_markdown_spec.rb b/spec/features/gitlab_flavored_markdown_spec.rb index 876f33dd03e..01b1aee4fd3 100644 --- a/spec/features/gitlab_flavored_markdown_spec.rb +++ b/spec/features/gitlab_flavored_markdown_spec.rb @@ -1,28 +1,28 @@ require 'spec_helper' describe "GitLab Flavored Markdown", feature: true do - let(:project) { create(:project) } + let(:project) { create(:empty_project) } let(:issue) { create(:issue, project: project) } - let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } let(:fred) do - u = create(:user, name: "fred") - project.team << [u, :master] - u + create(:user, name: 'fred') do |user| + project.add_master(user) + end end before do - allow_any_instance_of(Commit).to receive(:title). - and_return("fix #{issue.to_reference}\n\nask #{fred.to_reference} for details") + login_as(:user) + project.add_developer(@user) end - let(:commit) { project.commit } + describe "for commits" do + let(:project) { create(:project, :repository) } + let(:commit) { project.commit } - before do - login_as :user - project.team << [@user, :developer] - end + before do + allow_any_instance_of(Commit).to receive(:title). + and_return("fix #{issue.to_reference}\n\nask #{fred.to_reference} for details") + end - describe "for commits" do it "renders title in commits#index" do visit namespace_project_commits_path(project.namespace, project, 'master', limit: 1) @@ -92,6 +92,8 @@ describe "GitLab Flavored Markdown", feature: true do end describe "for merge requests" do + let(:project) { create(:project, :repository) } + before do @merge_request = create(:merge_request, source_project: project, target_project: project, title: "fix #{issue.to_reference}") end diff --git a/spec/features/global_search_spec.rb b/spec/features/global_search_spec.rb index f6409e00f22..4b22b07494d 100644 --- a/spec/features/global_search_spec.rb +++ b/spec/features/global_search_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature 'Global search', feature: true do let(:user) { create(:user) } - let(:project) { create(:project, namespace: user.namespace) } + let(:project) { create(:empty_project, namespace: user.namespace) } before do project.team << [user, :master] diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb index 1b3747c390b..45f57845c74 100644 --- a/spec/features/groups/issues_spec.rb +++ b/spec/features/groups/issues_spec.rb @@ -23,4 +23,20 @@ feature 'Group issues page', feature: true do it_behaves_like "an autodiscoverable RSS feed without a private token" end end + + context 'assignee', :js do + let(:access_level) { ProjectFeature::ENABLED } + let(:user) { user_in_group } + let(:user2) { user_outside_group } + let(:path) { issues_group_path(group) } + + it 'filters by only group users' do + click_button('Assignee') + + wait_for_ajax + + expect(find('.dropdown-menu-assignee')).to have_link(user.name) + expect(find('.dropdown-menu-assignee')).not_to have_link(user2.name) + end + end end diff --git a/spec/features/groups/members/list_spec.rb b/spec/features/groups/members/list_spec.rb index 14c193f7450..543879bd21d 100644 --- a/spec/features/groups/members/list_spec.rb +++ b/spec/features/groups/members/list_spec.rb @@ -1,6 +1,8 @@ require 'spec_helper' feature 'Groups members list', feature: true do + include Select2Helper + let(:user1) { create(:user, name: 'John Doe') } let(:user2) { create(:user, name: 'Mary Jane') } let(:group) { create(:group) } @@ -30,7 +32,7 @@ feature 'Groups members list', feature: true do expect(second_row).to be_blank end - it 'updates user to owner level', :js do + scenario 'update user to owner level', :js do group.add_owner(user1) group.add_developer(user2) @@ -38,13 +40,52 @@ feature 'Groups members list', feature: true do page.within(second_row) do click_button('Developer') - click_link('Owner') expect(page).to have_button('Owner') end end + scenario 'add user to group', :js do + group.add_owner(user1) + + visit group_group_members_path(group) + + add_user(user2.id, 'Reporter') + + page.within(second_row) do + expect(page).to have_content(user2.name) + expect(page).to have_button('Reporter') + end + end + + scenario 'add yourself to group when already an owner', :js do + group.add_owner(user1) + + visit group_group_members_path(group) + + add_user(user1.id, 'Reporter') + + page.within(first_row) do + expect(page).to have_content(user1.name) + expect(page).to have_content('Owner') + end + end + + scenario 'invite user to group', :js do + group.add_owner(user1) + + visit group_group_members_path(group) + + add_user('test@example.com', 'Reporter') + + page.within(second_row) do + expect(page).to have_content('test@example.com') + expect(page).to have_content('Invited') + expect(page).to have_button('Reporter') + end + end + def first_row page.all('ul.content-list > li')[0] end @@ -52,4 +93,13 @@ feature 'Groups members list', feature: true do def second_row page.all('ul.content-list > li')[1] end + + def add_user(id, role) + page.within ".users-group-form" do + select2(id, from: "#user_ids", multiple: true) + select(role, from: "access_level") + end + + click_button "Add to group" + end end diff --git a/spec/features/issuables/issuable_list_spec.rb b/spec/features/issuables/issuable_list_spec.rb index 3dc872ae520..f3ec80bb149 100644 --- a/spec/features/issuables/issuable_list_spec.rb +++ b/spec/features/issuables/issuable_list_spec.rb @@ -68,7 +68,7 @@ describe 'issuable list', feature: true do source_project: project, source_branch: generate(:branch)) - MergeRequestsClosingIssues.create!(issue: issue, merge_request: merge_request) + create(:merge_requests_closing_issues, issue: issue, merge_request: merge_request) end end end diff --git a/spec/features/issues/award_emoji_spec.rb b/spec/features/issues/award_emoji_spec.rb index 8e67ab028d7..71df3c949db 100644 --- a/spec/features/issues/award_emoji_spec.rb +++ b/spec/features/issues/award_emoji_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' describe 'Awards Emoji', feature: true do - include WaitForAjax include WaitForVueResource let!(:project) { create(:project, :public) } diff --git a/spec/features/issues/bulk_assignment_labels_spec.rb b/spec/features/issues/bulk_assignment_labels_spec.rb index 2f59630b4fb..1de50d6d77e 100644 --- a/spec/features/issues/bulk_assignment_labels_spec.rb +++ b/spec/features/issues/bulk_assignment_labels_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' feature 'Issues > Labels bulk assignment', feature: true do - include WaitForAjax - let(:user) { create(:user) } let!(:project) { create(:project) } let!(:issue1) { create(:issue, project: project, title: "Issue 1") } diff --git a/spec/features/issues/create_issue_for_single_discussion_in_merge_request.rb b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb index 88e2cc60d79..3a5a79e03f4 100644 --- a/spec/features/issues/create_issue_for_single_discussion_in_merge_request.rb +++ b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb @@ -4,7 +4,7 @@ feature 'Resolve an open discussion in a merge request by creating an issue', fe let(:user) { create(:user) } let(:project) { create(:project, only_allow_merge_if_all_discussions_are_resolved: true) } 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 @@ -74,8 +74,8 @@ feature 'Resolve an open discussion in a merge request by creating an issue', fe it 'Shows a notice to ask someone else to resolve the discussions' do expect(page).to have_content("The discussion at #{merge_request.to_reference}"\ - "(discussion #{discussion.first_note.id}) will stay unresolved."\ - "Ask someone with permission to resolve it.") + " (discussion #{discussion.first_note.id}) will stay unresolved."\ + " Ask someone with permission to resolve it.") end end end diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb index 3d1a9ed1722..0b573d7cef4 100644 --- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb @@ -2,7 +2,6 @@ require 'rails_helper' describe 'Dropdown assignee', :feature, :js do include FilteredSearchHelpers - include WaitForAjax let!(:project) { create(:empty_project) } let!(:user) { create(:user, name: 'administrator', username: 'root') } diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb index 990e3b3e60c..0579d6c80ab 100644 --- a/spec/features/issues/filtered_search/dropdown_author_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb @@ -2,7 +2,6 @@ require 'rails_helper' describe 'Dropdown author', js: true, feature: true do include FilteredSearchHelpers - include WaitForAjax let!(:project) { create(:empty_project) } let!(:user) { create(:user, name: 'administrator', username: 'root') } diff --git a/spec/features/issues/filtered_search/dropdown_hint_spec.rb b/spec/features/issues/filtered_search/dropdown_hint_spec.rb index cae01f37b6b..b9a37cfcc22 100644 --- a/spec/features/issues/filtered_search/dropdown_hint_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_hint_spec.rb @@ -2,7 +2,6 @@ require 'rails_helper' describe 'Dropdown hint', :js, :feature do include FilteredSearchHelpers - include WaitForAjax let!(:project) { create(:empty_project) } let!(:user) { create(:user) } diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb index 6f00066de4d..c824aa6a414 100644 --- a/spec/features/issues/filtered_search/filter_issues_spec.rb +++ b/spec/features/issues/filtered_search/filter_issues_spec.rb @@ -3,7 +3,6 @@ require 'spec_helper' describe 'Filter issues', js: true, feature: true do include Devise::Test::IntegrationHelpers include FilteredSearchHelpers - include WaitForAjax let!(:group) { create(:group) } let!(:project) { create(:project, group: group) } @@ -13,7 +12,7 @@ describe 'Filter issues', js: true, feature: true do let!(:wontfix) { create(:label, project: project, title: "Won't fix") } let!(:bug_label) { create(:label, project: project, title: 'bug') } - let!(:caps_sensitive_label) { create(:label, project: project, title: 'CAPS_sensitive') } + let!(:caps_sensitive_label) { create(:label, project: project, title: 'CaPs') } let!(:milestone) { create(:milestone, title: "8", project: project, start_date: 2.days.ago) } let!(:multiple_words_label) { create(:label, project: project, title: "Two words") } diff --git a/spec/features/issues/filtered_search/recent_searches_spec.rb b/spec/features/issues/filtered_search/recent_searches_spec.rb index f506065a242..08fe3b4553b 100644 --- a/spec/features/issues/filtered_search/recent_searches_spec.rb +++ b/spec/features/issues/filtered_search/recent_searches_spec.rb @@ -2,7 +2,6 @@ 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) } diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb index 28137f11b92..3ea95aed0a6 100644 --- a/spec/features/issues/filtered_search/search_bar_spec.rb +++ b/spec/features/issues/filtered_search/search_bar_spec.rb @@ -2,7 +2,6 @@ require 'rails_helper' describe 'Search bar', js: true, feature: true do include FilteredSearchHelpers - include WaitForAjax let!(:project) { create(:empty_project) } let!(:user) { create(:user) } diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb index 7135565294b..ad29911248f 100644 --- a/spec/features/issues/gfm_autocomplete_spec.rb +++ b/spec/features/issues/gfm_autocomplete_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' feature 'GFM autocomplete', feature: true, js: true do - include WaitForAjax let(:user) { create(:user, name: '💃speciąl someone💃', username: 'someone.special') } let(:project) { create(:project) } let(:label) { create(:label, project: project, title: 'special+') } @@ -46,6 +45,33 @@ feature 'GFM autocomplete', feature: true, js: true do expect(find('#at-view-58')).not_to have_selector('.cur:first-of-type') end + it 'does not open autocomplete menu when ":" is prefixed by a number and letters' do + note = find('#note_note') + + # Number. + page.within '.timeline-content-form' do + note.native.send_keys('7:') + end + + expect(page).not_to have_selector('.atwho-view') + + # ASCII letter. + page.within '.timeline-content-form' do + note.set('') + note.native.send_keys('w:') + end + + expect(page).not_to have_selector('.atwho-view') + + # Non-ASCII letter. + page.within '.timeline-content-form' do + note.set('') + note.native.send_keys('Ё:') + end + + expect(page).not_to have_selector('.atwho-view') + end + it 'selects the first item for assignee dropdowns' do page.within '.timeline-content-form' do find('#note_note').native.send_keys('') diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb index 85585587fb1..baacd7edb86 100644 --- a/spec/features/issues/issue_sidebar_spec.rb +++ b/spec/features/issues/issue_sidebar_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' feature 'Issue Sidebar', feature: true do - include WaitForAjax include MobileHelpers let(:project) { create(:project, :public) } diff --git a/spec/features/issues/update_issues_spec.rb b/spec/features/issues/update_issues_spec.rb index ae5da3877a8..7fa83c1fcf7 100644 --- a/spec/features/issues/update_issues_spec.rb +++ b/spec/features/issues/update_issues_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' feature 'Multiple issue updating from issues#index', feature: true do - include WaitForAjax - let!(:project) { create(:project) } let!(:issue) { create(:issue, project: project) } let!(:user) { create(:user)} diff --git a/spec/features/issues/user_uses_slash_commands_spec.rb b/spec/features/issues/user_uses_slash_commands_spec.rb index 0a9cd11ad6e..4cd6c1171ac 100644 --- a/spec/features/issues/user_uses_slash_commands_spec.rb +++ b/spec/features/issues/user_uses_slash_commands_spec.rb @@ -2,7 +2,6 @@ require 'rails_helper' feature 'Issues > User uses slash commands', feature: true, js: true do include SlashCommandsHelpers - include WaitForAjax it_behaves_like 'issuable record that supports slash commands in its description and notes', :issue do let(:issuable) { create(:issue, project: project) } diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index 362d167befa..81cc8513454 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -4,22 +4,14 @@ describe 'Issues', feature: true do include DropzoneHelper include IssueHelpers include SortingHelper - include WaitForAjax - let(:project) { create(:project, :public) } + let(:project) { create(:empty_project, :public) } before do login_as :user user2 = create(:user) project.team << [[@user, user2], :developer] - - project.repository.create_file( - @user, - '.gitlab/issue_templates/bug.md', - 'this is a test "bug" template', - message: 'added issue template', - branch_name: 'master') end describe 'Edit issue' do @@ -378,7 +370,7 @@ describe 'Issues', feature: true do end describe 'when I want to reset my incoming email token' do - let(:project1) { create(:project, namespace: @user.namespace) } + let(:project1) { create(:empty_project, namespace: @user.namespace) } let!(:issue) { create(:issue, project: project1) } before do @@ -414,7 +406,8 @@ describe 'Issues', feature: true do it 'will not send ajax request when no data is changed' do page.within '.labels' do click_link 'Edit' - first('.dropdown-menu-close').click + + find('.dropdown-menu-close', match: :first).click expect(page).not_to have_selector('.block-loading') end @@ -609,7 +602,16 @@ describe 'Issues', feature: true do end context 'form filled by URL parameters' do + let(:project) { create(:project, :public, :repository) } + before do + project.repository.create_file( + @user, + '.gitlab/issue_templates/bug.md', + 'this is a test "bug" template', + message: 'added issue template', + branch_name: 'master') + visit new_namespace_project_issue_path(project.namespace, project, issuable_template: 'bug') end diff --git a/spec/features/markdown_spec.rb b/spec/features/markdown_spec.rb index 894df13a2dc..ba930de937d 100644 --- a/spec/features/markdown_spec.rb +++ b/spec/features/markdown_spec.rb @@ -26,7 +26,7 @@ require 'erb' describe 'GitLab Markdown', feature: true do include Capybara::Node::Matchers - include GitlabMarkdownHelper + include MarkupHelper include MarkdownMatchers # Sometimes it can be useful to see the parsed output of the Markdown document diff --git a/spec/features/merge_requests/conflicts_spec.rb b/spec/features/merge_requests/conflicts_spec.rb index 18508a44184..43977ad2fc5 100644 --- a/spec/features/merge_requests/conflicts_spec.rb +++ b/spec/features/merge_requests/conflicts_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'Merge request conflict resolution', js: true, feature: true do - include WaitForAjax - let(:user) { create(:user) } let(:project) { create(:project) } diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb index 3a4ec07b2b0..f0fec625108 100644 --- a/spec/features/merge_requests/create_new_mr_spec.rb +++ b/spec/features/merge_requests/create_new_mr_spec.rb @@ -20,13 +20,14 @@ feature 'Create New Merge Request', feature: true, js: true do expect(page).to have_content('Target branch') first('.js-source-branch').click - first('.dropdown-source-branch .dropdown-content a', text: 'v1.1.0').click + first('.dropdown-source-branch .dropdown-content') + find('.dropdown-source-branch .dropdown-content a', match: :first).click expect(page).to have_content "b83d6e3" 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) + visit namespace_project_merge_requests_path(project.namespace, project) click_link 'New merge request' @@ -34,6 +35,7 @@ feature 'Create New Merge Request', feature: true, js: true do expect(page).to have_content('Target branch') first('.js-target-branch').click + first('.dropdown-target-branch .dropdown-content') first('.dropdown-target-branch .dropdown-content a', text: 'v1.1.0').click expect(page).to have_content "b83d6e3" @@ -46,8 +48,8 @@ feature 'Create New Merge Request', feature: true, js: true do expect(page).to have_content('Source branch') expect(page).to have_content('Target branch') - first('.js-source-branch').click - first('.dropdown-source-branch .dropdown-content a', text: 'orphaned-branch').click + find('.js-source-branch', match: :first).click + find('.dropdown-source-branch .dropdown-content a', text: 'orphaned-branch', match: :first).click click_button "Compare branches" click_link "Changes" diff --git a/spec/features/merge_requests/deleted_source_branch_spec.rb b/spec/features/merge_requests/deleted_source_branch_spec.rb index 0952b17b63e..648678e2b1a 100644 --- a/spec/features/merge_requests/deleted_source_branch_spec.rb +++ b/spec/features/merge_requests/deleted_source_branch_spec.rb @@ -4,8 +4,6 @@ require 'spec_helper' # message to be shown by JavaScript when the source branch was deleted. # Please do not remove "js: true". describe 'Deleted source branch', feature: true, js: true do - include WaitForAjax - let(:user) { create(:user) } let(:merge_request) { create(:merge_request) } diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb index 218d95a88b8..b2e170513c4 100644 --- a/spec/features/merge_requests/diff_notes_avatars_spec.rb +++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'Diff note avatars', feature: true, js: true do - include WaitForAjax - let(:user) { create(:user) } let(:project) { create(:project, :public) } let(:merge_request) { create(:merge_request_with_diffs, source_project: project, author: user, title: "Bug NS-04") } diff --git a/spec/features/merge_requests/diffs_spec.rb b/spec/features/merge_requests/diffs_spec.rb index 4a6c76a5caf..7dee3b852ca 100644 --- a/spec/features/merge_requests/diffs_spec.rb +++ b/spec/features/merge_requests/diffs_spec.rb @@ -1,11 +1,8 @@ require 'spec_helper' feature 'Diffs URL', js: true, feature: true do - before do - login_as :admin - @merge_request = create(:merge_request) - @project = @merge_request.source_project - end + let(:project) { create(:project, :public) } + let(:merge_request) { create(:merge_request, source_project: project) } context 'when visit with */* as accept header' do before(:each) do @@ -13,9 +10,9 @@ feature 'Diffs URL', js: true, feature: true do end it 'renders the notes' do - create :note_on_merge_request, project: @project, noteable: @merge_request, note: 'Rebasing with master' + create :note_on_merge_request, project: project, noteable: merge_request, note: 'Rebasing with master' - visit diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request) + visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) # Load notes and diff through AJAX expect(page).to have_css('.note-text', visible: false, text: 'Rebasing with master') @@ -25,10 +22,9 @@ feature 'Diffs URL', js: true, feature: true do context 'when merge request has overflow' do it 'displays warning' do - allow_any_instance_of(MergeRequestDiff).to receive(:overflow?).and_return(true) - allow(Commit).to receive(:max_diff_options).and_return(max_files: 20, max_lines: 20) + allow(Commit).to receive(:max_diff_options).and_return(max_files: 3) - visit diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request) + visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) page.within('.alert') do expect(page).to have_text("Too many changes to show. Plain diff Email patch To preserve @@ -36,4 +32,35 @@ feature 'Diffs URL', js: true, feature: true do end end end + + context 'when editing file' do + let(:author_user) { create(:user) } + let(:user) { create(:user) } + let(:forked_project) { Projects::ForkService.new(project, author_user).execute } + let(:merge_request) { create(:merge_request_with_diffs, source_project: forked_project, target_project: project, author: author_user) } + let(:changelog_id) { Digest::SHA1.hexdigest("CHANGELOG") } + + context 'as author' do + it 'shows direct edit link' do + login_as(author_user) + visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) + + # Throws `Capybara::Poltergeist::InvalidSelector` if we try to use `#hash` syntax + expect(page).to have_selector("[id=\"#{changelog_id}\"] a.js-edit-blob") + end + end + + context 'as user who needs to fork' do + it 'shows fork/cancel confirmation' do + login_as(user) + visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request) + + # Throws `Capybara::Poltergeist::InvalidSelector` if we try to use `#hash` syntax + find("[id=\"#{changelog_id}\"] .js-edit-blob").click + + expect(page).to have_selector('.js-fork-suggestion-button', count: 1) + expect(page).to have_selector('.js-cancel-fork-suggestion-button', count: 1) + end + end + end end diff --git a/spec/features/merge_requests/filter_by_labels_spec.rb b/spec/features/merge_requests/filter_by_labels_spec.rb index 55f3c1863ff..32a9082b9b9 100644 --- a/spec/features/merge_requests/filter_by_labels_spec.rb +++ b/spec/features/merge_requests/filter_by_labels_spec.rb @@ -3,7 +3,6 @@ require 'rails_helper' feature 'Issue filtering by Labels', feature: true, js: true do include FilteredSearchHelpers include MergeRequestHelpers - include WaitForAjax let(:project) { create(:project, :public) } let!(:user) { create(:user) } diff --git a/spec/features/merge_requests/filter_merge_requests_spec.rb b/spec/features/merge_requests/filter_merge_requests_spec.rb index 70e3997e716..2da60e9f4ad 100644 --- a/spec/features/merge_requests/filter_merge_requests_spec.rb +++ b/spec/features/merge_requests/filter_merge_requests_spec.rb @@ -3,7 +3,6 @@ require 'rails_helper' describe 'Filter merge requests', feature: true do include FilteredSearchHelpers include MergeRequestHelpers - include WaitForAjax let!(:project) { create(:project) } let!(:group) { create(:group) } diff --git a/spec/features/merge_requests/mini_pipeline_graph_spec.rb b/spec/features/merge_requests/mini_pipeline_graph_spec.rb index 84ad8765d8f..449a60c1d05 100644 --- a/spec/features/merge_requests/mini_pipeline_graph_spec.rb +++ b/spec/features/merge_requests/mini_pipeline_graph_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' feature 'Mini Pipeline Graph', :js, :feature do - include WaitForAjax - let(:user) { create(:user) } let(:project) { create(:project, :public) } let(:merge_request) { create(:merge_request, source_project: project) } diff --git a/spec/features/merge_requests/pipelines_spec.rb b/spec/features/merge_requests/pipelines_spec.rb index 9c4c0525267..99e283ac181 100644 --- a/spec/features/merge_requests/pipelines_spec.rb +++ b/spec/features/merge_requests/pipelines_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'Pipelines for Merge Requests', feature: true, js: true do - include WaitForAjax - given(:user) { create(:user) } given(:merge_request) { create(:merge_request) } given(:project) { merge_request.target_project } diff --git a/spec/features/merge_requests/reset_filters_spec.rb b/spec/features/merge_requests/reset_filters_spec.rb index df5943f9136..275f81f50dc 100644 --- a/spec/features/merge_requests/reset_filters_spec.rb +++ b/spec/features/merge_requests/reset_filters_spec.rb @@ -3,7 +3,6 @@ require 'rails_helper' feature 'Merge requests filter clear button', feature: true, js: true do include FilteredSearchHelpers include MergeRequestHelpers - include WaitForAjax include IssueHelpers let!(:project) { create(:project, :public) } diff --git a/spec/features/merge_requests/update_merge_requests_spec.rb b/spec/features/merge_requests/update_merge_requests_spec.rb index b56fdfe5611..9ecc998785b 100644 --- a/spec/features/merge_requests/update_merge_requests_spec.rb +++ b/spec/features/merge_requests/update_merge_requests_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' feature 'Multiple merge requests updating from merge_requests#index', feature: true do - include WaitForAjax - let!(:user) { create(:user)} let!(:project) { create(:project) } let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) } diff --git a/spec/features/merge_requests/user_posts_notes.rb b/spec/features/merge_requests/user_posts_notes_spec.rb index c7cc4d6bc72..c7cc4d6bc72 100644 --- a/spec/features/merge_requests/user_posts_notes.rb +++ b/spec/features/merge_requests/user_posts_notes_spec.rb diff --git a/spec/features/merge_requests/user_uses_slash_commands_spec.rb b/spec/features/merge_requests/user_uses_slash_commands_spec.rb index a1f4eb2688b..1c0f21e5616 100644 --- a/spec/features/merge_requests/user_uses_slash_commands_spec.rb +++ b/spec/features/merge_requests/user_uses_slash_commands_spec.rb @@ -2,7 +2,6 @@ require 'rails_helper' feature 'Merge Requests > User uses slash commands', feature: true, js: true do include SlashCommandsHelpers - include WaitForAjax let(:user) { create(:user) } let(:project) { create(:project, :public) } diff --git a/spec/features/merge_requests/versions_spec.rb b/spec/features/merge_requests/versions_spec.rb index 68a68f5d3f3..7a2da623c58 100644 --- a/spec/features/merge_requests/versions_spec.rb +++ b/spec/features/merge_requests/versions_spec.rb @@ -107,14 +107,13 @@ feature 'Merge Request versions', js: true, feature: true do it 'should have 0 chages between versions' do page.within '.mr-version-compare-dropdown' do - expect(page).to have_content 'version 1' + expect(find('.dropdown-toggle')).to have_content 'version 1' end page.within '.mr-version-dropdown' do find('.btn-default').click - find(:link, 'version 1').trigger('click') + click_link 'version 1' end - expect(page).to have_content '0 changed files' end end @@ -129,12 +128,12 @@ feature 'Merge Request versions', js: true, feature: true do it 'should set the compared versions to be the same' do page.within '.mr-version-compare-dropdown' do - expect(page).to have_content 'version 2' + expect(find('.dropdown-toggle')).to have_content 'version 2' end page.within '.mr-version-dropdown' do find('.btn-default').click - find(:link, 'version 1').trigger('click') + click_link 'version 1' end page.within '.mr-version-compare-dropdown' do diff --git a/spec/features/merge_requests/widget_deployments_spec.rb b/spec/features/merge_requests/widget_deployments_spec.rb index 6676821b807..00d191ddf2c 100644 --- a/spec/features/merge_requests/widget_deployments_spec.rb +++ b/spec/features/merge_requests/widget_deployments_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'Widget Deployments Header', feature: true, js: true do - include WaitForAjax - describe 'when deployed to an environment' do given(:user) { create(:user) } given(:project) { merge_request.target_project } diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb index a62c5435748..d918181a238 100644 --- a/spec/features/merge_requests/widget_spec.rb +++ b/spec/features/merge_requests/widget_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' describe 'Merge request', :feature, :js do - include WaitForAjax - let(:user) { create(:user) } let(:project) { create(:project) } let(:merge_request) { create(:merge_request, source_project: project) } @@ -141,6 +139,27 @@ describe 'Merge request', :feature, :js do end end + context 'view merge request with MWPS enabled but automatically merge fails' do + before do + merge_request.update( + merge_when_pipeline_succeeds: true, + merge_user: merge_request.author, + merge_error: 'Something went wrong' + ) + + visit namespace_project_merge_request_path(project.namespace, project, merge_request) + end + + it 'shows information about the merge error' do + # Wait for the `ci_status` and `merge_check` requests + wait_for_ajax + + page.within('.mr-widget-body') do + expect(page).to have_content('Something went wrong') + end + end + end + context 'merge error' do before do allow_any_instance_of(Repository).to receive(:merge).and_return(false) diff --git a/spec/features/milestone_spec.rb b/spec/features/milestone_spec.rb index c3297de709a..c07de01c594 100644 --- a/spec/features/milestone_spec.rb +++ b/spec/features/milestone_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' feature 'Milestone', feature: true do - include WaitForAjax - let(:project) { create(:empty_project, :public) } let(:user) { create(:user) } diff --git a/spec/features/milestones/milestones_spec.rb b/spec/features/milestones/milestones_spec.rb index 2fa3e72ab08..50d7ca39045 100644 --- a/spec/features/milestones/milestones_spec.rb +++ b/spec/features/milestones/milestones_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' describe 'Milestone draggable', feature: true, js: true do - include WaitForAjax include DragTo let(:milestone) { create(:milestone, project: project, title: 8.14) } diff --git a/spec/features/participants_autocomplete_spec.rb b/spec/features/participants_autocomplete_spec.rb index decad589c23..449ce80bc71 100644 --- a/spec/features/participants_autocomplete_spec.rb +++ b/spec/features/participants_autocomplete_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' feature 'Member autocomplete', :js do - let(:project) { create(:project, :public) } + let(:project) { create(:empty_project, :public) } let(:user) { create(:user) } let(:author) { create(:user) } let(:note) { create(:note, noteable: noteable, project: noteable.project) } @@ -36,6 +36,7 @@ feature 'Member autocomplete', :js do end context 'adding a new note on a Merge Request' do + let(:project) { create(:project, :public, :repository) } let(:noteable) do create(:merge_request, source_project: project, target_project: project, author: author) @@ -48,6 +49,7 @@ feature 'Member autocomplete', :js do end context 'adding a new note on a Commit' do + let(:project) { create(:project, :public, :repository) } let(:noteable) { project.commit } let(:note) { create(:note_on_commit, project: project, commit_id: project.commit.id) } diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb index 01cd268ffe8..8dba2ccbafa 100644 --- a/spec/features/projects/blobs/blob_show_spec.rb +++ b/spec/features/projects/blobs/blob_show_spec.rb @@ -1,22 +1,334 @@ require 'spec_helper' -feature 'File blob', feature: true do - include WaitForAjax - include TreeHelper +feature 'File blob', :js, feature: true do + let(:project) { create(:project, :public) } - 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] } + def visit_blob(path, fragment = nil) + visit namespace_project_blob_path(project.namespace, project, File.join('master', path), anchor: fragment) + end + + context 'Ruby file' do + before do + visit_blob('files/ruby/popen.rb') + + wait_for_ajax + end + + it 'displays the blob' do + aggregate_failures do + # shows highlighted Ruby code + expect(page).to have_content("require 'fileutils'") + + # does not show a viewer switcher + expect(page).not_to have_selector('.js-blob-viewer-switcher') + + # shows an enabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)') + + # shows a raw button + expect(page).to have_link('Open raw') + end + end + end + + context 'Markdown file' do + context 'visiting directly' do + before do + visit_blob('files/markdown/ruby-style-guide.md') + + wait_for_ajax + end + + it 'displays the blob using the rich viewer' do + aggregate_failures do + # hides the simple viewer + expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false) + expect(page).to have_selector('.blob-viewer[data-type="rich"]') + + # shows rendered Markdown + expect(page).to have_link("PEP-8") + + # shows a viewer switcher + expect(page).to have_selector('.js-blob-viewer-switcher') + + # shows a disabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn.disabled') + + # shows a raw button + expect(page).to have_link('Open raw') + end + end + + context 'switching to the simple viewer' do + before do + find('.js-blob-viewer-switch-btn[data-viewer=simple]').click + + wait_for_ajax + end + + it 'displays the blob using the simple viewer' do + aggregate_failures do + # hides the rich viewer + expect(page).to have_selector('.blob-viewer[data-type="simple"]') + expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false) + + # shows highlighted Markdown code + expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)") + + # shows an enabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)') + end + end + + context 'switching to the rich viewer again' do + before do + find('.js-blob-viewer-switch-btn[data-viewer=rich]').click + + wait_for_ajax + end + + it 'displays the blob using the rich viewer' do + aggregate_failures do + # hides the simple viewer + expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false) + expect(page).to have_selector('.blob-viewer[data-type="rich"]') + + # shows an enabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)') + end + end + end + end + end + + context 'visiting with a line number anchor' do + before do + visit_blob('files/markdown/ruby-style-guide.md', 'L1') + + wait_for_ajax + end + + it 'displays the blob using the simple viewer' do + aggregate_failures do + # hides the rich viewer + expect(page).to have_selector('.blob-viewer[data-type="simple"]') + expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false) + + # highlights the line in question + expect(page).to have_selector('#LC1.hll') + + # shows highlighted Markdown code + expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)") + + # shows an enabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)') + end + end + end + end + + context 'Markdown file (stored in LFS)' do + before do + project.add_master(project.creator) + + Files::CreateService.new( + project, + project.creator, + start_branch: 'master', + branch_name: 'master', + commit_message: "Add Markdown in LFS", + file_path: 'files/lfs/file.md', + file_content: project.repository.blob_at('master', 'files/lfs/lfs_object.iso').data + ).execute + end + + context 'when LFS is enabled on the project' do + before do + allow(Gitlab.config.lfs).to receive(:enabled).and_return(true) + project.update_attribute(:lfs_enabled, true) + + visit_blob('files/lfs/file.md') + + wait_for_ajax + end + + it 'displays an error' do + aggregate_failures do + # hides the simple viewer + expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false) + expect(page).to have_selector('.blob-viewer[data-type="rich"]') + + # shows an error message + expect(page).to have_content('The rendered file could not be displayed because it is stored in LFS. You can view the source or download it instead.') + + # shows a viewer switcher + expect(page).to have_selector('.js-blob-viewer-switcher') + + # does not show a copy button + expect(page).not_to have_selector('.js-copy-blob-source-btn') + + # shows a raw button + expect(page).to have_link('Open raw') + end + end + + context 'switching to the simple viewer' do + before do + find('.js-blob-viewer-switcher .js-blob-viewer-switch-btn[data-viewer=simple]').click + + wait_for_ajax + end + + it 'displays an error' do + aggregate_failures do + # hides the rich viewer + expect(page).to have_selector('.blob-viewer[data-type="simple"]') + expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false) + + # shows an error message + expect(page).to have_content('The source could not be displayed because it is stored in LFS. You can download it instead.') + + # does not show a copy button + expect(page).not_to have_selector('.js-copy-blob-source-btn') + end + end + end + end + + context 'when LFS is disabled on the project' do + before do + visit_blob('files/lfs/file.md') + + wait_for_ajax + end + + it 'displays the blob' do + aggregate_failures do + # shows text + expect(page).to have_content('size 1575078') + + # does not show a viewer switcher + expect(page).not_to have_selector('.js-blob-viewer-switcher') + + # shows an enabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)') + + # shows a raw button + expect(page).to have_link('Open raw') + end + end + end + end + + context 'PDF file' do + before do + project.add_master(project.creator) + + Files::CreateService.new( + project, + project.creator, + start_branch: 'master', + branch_name: 'master', + commit_message: "Add PDF", + file_path: 'files/test.pdf', + file_content: project.repository.blob_at('add-pdf-file', 'files/pdf/test.pdf').data + ).execute + + visit_blob('files/test.pdf') + + wait_for_ajax + end + + it 'displays the blob' do + aggregate_failures do + # shows rendered PDF + expect(page).to have_selector('.js-pdf-viewer') + + # does not show a viewer switcher + expect(page).not_to have_selector('.js-blob-viewer-switcher') + + # does not show a copy button + expect(page).not_to have_selector('.js-copy-blob-source-btn') + + # shows a download button + expect(page).to have_link('Download') + end + end + end + + context 'ISO file (stored in LFS)' do + context 'when LFS is enabled on the project' do + before do + allow(Gitlab.config.lfs).to receive(:enabled).and_return(true) + project.update_attribute(:lfs_enabled, true) + + visit_blob('files/lfs/lfs_object.iso') + + wait_for_ajax + end + + it 'displays the blob' do + aggregate_failures do + # shows a download link + expect(page).to have_link('Download (1.5 MB)') + + # does not show a viewer switcher + expect(page).not_to have_selector('.js-blob-viewer-switcher') + + # does not show a copy button + expect(page).not_to have_selector('.js-copy-blob-source-btn') + + # shows a download button + expect(page).to have_link('Download') + end + end + end - context 'anonymous' do - context 'from blob file path' do + context 'when LFS is disabled on the project' do before do - visit namespace_project_blob_path(project.namespace, project, tree_join(branch, file_path)) + visit_blob('files/lfs/lfs_object.iso') + + wait_for_ajax end - it 'updates content' do - expect(page).to have_link 'Edit' + it 'displays the blob' do + aggregate_failures do + # shows text + expect(page).to have_content('size 1575078') + + # does not show a viewer switcher + expect(page).not_to have_selector('.js-blob-viewer-switcher') + + # shows an enabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)') + + # shows a raw button + expect(page).to have_link('Open raw') + end + end + end + end + + context 'ZIP file' do + before do + visit_blob('Gemfile.zip') + + wait_for_ajax + end + + it 'displays the blob' do + aggregate_failures do + # shows a download link + expect(page).to have_link('Download (2.11 KB)') + + # does not show a viewer switcher + expect(page).not_to have_selector('.js-blob-viewer-switcher') + + # does not show a copy button + expect(page).not_to have_selector('.js-copy-blob-source-btn') + + # shows a download button + expect(page).to have_link('Download') end end end diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb index aab5a72678e..cc5b1a7e734 100644 --- a/spec/features/projects/blobs/edit_spec.rb +++ b/spec/features/projects/blobs/edit_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' feature 'Editing file blob', feature: true, js: true do - include WaitForAjax include TreeHelper let(:project) { create(:project, :public, :test_repo) } diff --git a/spec/features/projects/blobs/user_create_spec.rb b/spec/features/projects/blobs/user_create_spec.rb index 6ea149956fe..d805450e095 100644 --- a/spec/features/projects/blobs/user_create_spec.rb +++ b/spec/features/projects/blobs/user_create_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' feature 'New blob creation', feature: true, js: true do - include WaitForAjax include TargetBranchHelpers given(:user) { create(:user) } diff --git a/spec/features/projects/commit/cherry_pick_spec.rb b/spec/features/projects/commit/cherry_pick_spec.rb index 0b972d2a439..fa67d390c47 100644 --- a/spec/features/projects/commit/cherry_pick_spec.rb +++ b/spec/features/projects/commit/cherry_pick_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' -include WaitForAjax describe 'Cherry-pick Commits' do let(:group) { create(:group) } @@ -75,8 +74,10 @@ describe 'Cherry-pick Commits' do wait_for_ajax - page.within('#modal-cherry-pick-commit .dropdown-menu .dropdown-content') do - click_link 'feature' + page.within('#modal-cherry-pick-commit .dropdown-menu') do + find('.dropdown-input input').set('feature') + wait_for_ajax + click_link "feature" end page.within('#modal-cherry-pick-commit') do diff --git a/spec/features/projects/commit/mini_pipeline_graph_spec.rb b/spec/features/projects/commit/mini_pipeline_graph_spec.rb index 30a2b2bcf8c..98c0f2c63b0 100644 --- a/spec/features/projects/commit/mini_pipeline_graph_spec.rb +++ b/spec/features/projects/commit/mini_pipeline_graph_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' feature 'Mini Pipeline Graph in Commit View', :js, :feature do - include WaitForAjax - let(:user) { create(:user) } let(:project) { create(:project, :public) } diff --git a/spec/features/projects/edit_spec.rb b/spec/features/projects/edit_spec.rb index 7c319af893b..a263781c43c 100644 --- a/spec/features/projects/edit_spec.rb +++ b/spec/features/projects/edit_spec.rb @@ -1,8 +1,6 @@ require 'rails_helper' feature 'Project edit', feature: true, js: true do - include WaitForAjax - let(:user) { create(:user) } let(:project) { create(:project) } diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb index acc3efe04e6..1e12f8542e2 100644 --- a/spec/features/projects/environments/environment_spec.rb +++ b/spec/features/projects/environments/environment_spec.rb @@ -200,7 +200,7 @@ feature 'Environment', :feature do end scenario 'user deletes the branch with running environment' do - visit namespace_project_branches_path(project.namespace, project) + visit namespace_project_branches_path(project.namespace, project, search: 'feature') remove_branch_with_hooks(project, user, 'feature') do page.within('.js-branch-feature') { find('a.btn-remove').click } diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb index 9079350186d..b080a8d500e 100644 --- a/spec/features/projects/features_visibility_spec.rb +++ b/spec/features/projects/features_visibility_spec.rb @@ -1,9 +1,6 @@ require 'spec_helper' -include WaitForAjax describe 'Edit Project Settings', feature: true do - include WaitForAjax - let(:member) { create(:user) } let!(:project) { create(:project, :public, path: 'gitlab', name: 'sample') } let!(:issue) { create(:issue, project: project) } diff --git a/spec/features/projects/files/browse_files_spec.rb b/spec/features/projects/files/browse_files_spec.rb index d281043caa3..70e96efd557 100644 --- a/spec/features/projects/files/browse_files_spec.rb +++ b/spec/features/projects/files/browse_files_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'user browses project', feature: true do +feature 'user browses project', feature: true, js: true do let(:project) { create(:project) } let(:user) { create(:user) } @@ -13,7 +13,7 @@ feature 'user browses project', feature: true do scenario "can see blame of '.gitignore'" do click_link ".gitignore" click_link 'Blame' - + expect(page).to have_content "*.rb" expect(page).to have_content "Dmitriy Zaporozhets" expect(page).to have_content "Initial commit" @@ -24,6 +24,7 @@ feature 'user browses project', feature: true do click_link 'files' click_link 'lfs' click_link 'lfs_object.iso' + wait_for_ajax expect(page).not_to have_content 'Download (1.5 MB)' expect(page).to have_content 'version https://git-lfs.github.com/spec/v1' diff --git a/spec/features/projects/files/creating_a_file_spec.rb b/spec/features/projects/files/creating_a_file_spec.rb index de6905f2b58..69744ac3948 100644 --- a/spec/features/projects/files/creating_a_file_spec.rb +++ b/spec/features/projects/files/creating_a_file_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'User wants to create a file', feature: true do - include WaitForAjax - let(:project) { create(:project) } let(:user) { create(:user) } diff --git a/spec/features/projects/files/dockerfile_dropdown_spec.rb b/spec/features/projects/files/dockerfile_dropdown_spec.rb index 32f33a3ca97..548131c7cd4 100644 --- a/spec/features/projects/files/dockerfile_dropdown_spec.rb +++ b/spec/features/projects/files/dockerfile_dropdown_spec.rb @@ -1,13 +1,14 @@ require 'spec_helper' +require 'fileutils' feature 'User wants to add a Dockerfile file', feature: true do - include WaitForAjax - before do user = create(:user) project = create(:project) project.team << [user, :master] + login_as user + visit namespace_project_new_blob_path(project.namespace, project, 'master', file_name: 'Dockerfile') end @@ -17,11 +18,14 @@ feature 'User wants to add a Dockerfile file', feature: true do scenario 'user can pick a Dockerfile file from the dropdown', js: true do find('.js-dockerfile-selector').click + wait_for_ajax + within '.dockerfile-selector' do find('.dropdown-input-field').set('HTTPd') find('.dropdown-content li', text: 'HTTPd').click end + wait_for_ajax expect(page).to have_css('.dockerfile-selector .dropdown-toggle-text', text: 'HTTPd') diff --git a/spec/features/projects/files/editing_a_file_spec.rb b/spec/features/projects/files/editing_a_file_spec.rb index 4da34108b46..7a3afafec29 100644 --- a/spec/features/projects/files/editing_a_file_spec.rb +++ b/spec/features/projects/files/editing_a_file_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'User wants to edit a file', feature: true do - include WaitForAjax - let(:project) { create(:project) } let(:user) { create(:user) } let(:commit_params) do diff --git a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb index 10b91d8990b..5c8105de4cb 100644 --- a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb +++ b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'User views files page', feature: true do - include WaitForAjax - let(:user) { create(:user) } let(:project) { create(:forked_project_with_submodules) } diff --git a/spec/features/projects/files/find_file_keyboard_spec.rb b/spec/features/projects/files/find_file_keyboard_spec.rb index 582349d8d5b..e7a6749d8ac 100644 --- a/spec/features/projects/files/find_file_keyboard_spec.rb +++ b/spec/features/projects/files/find_file_keyboard_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'Find file keyboard shortcuts', feature: true, js: true do - include WaitForAjax - let(:user) { create(:user) } let(:project) { create(:project) } diff --git a/spec/features/projects/files/find_files_spec.rb b/spec/features/projects/files/find_files_spec.rb new file mode 100644 index 00000000000..716b7591b95 --- /dev/null +++ b/spec/features/projects/files/find_files_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +feature 'Find files button in the tree header', feature: true do + given(:user) { create(:user) } + given(:project) { create(:project) } + + background do + login_as(user) + project.team << [user, :developer] + end + + scenario 'project main screen' do + visit namespace_project_path( + project.namespace, + project + ) + + expect(page).to have_selector('.tree-controls .shortcuts-find-file') + end + + scenario 'project tree screen' do + visit namespace_project_tree_path( + project.namespace, + project, + project.default_branch + ) + + expect(page).to have_selector('.tree-controls .shortcuts-find-file') + end +end diff --git a/spec/features/projects/files/gitignore_dropdown_spec.rb b/spec/features/projects/files/gitignore_dropdown_spec.rb index 9ebef505b92..e59428f8b24 100644 --- a/spec/features/projects/files/gitignore_dropdown_spec.rb +++ b/spec/features/projects/files/gitignore_dropdown_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'User wants to add a .gitignore file', feature: true do - include WaitForAjax - before do user = create(:user) project = create(:project) diff --git a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb index fca40f68b01..85b66b93fba 100644 --- a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb +++ b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'User wants to add a .gitlab-ci.yml file', feature: true do - include WaitForAjax - before do user = create(:user) project = create(:project) 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 8ff0f5898ec..249830921ac 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 @@ -1,8 +1,6 @@ require 'spec_helper' feature 'project owner creates a license file', feature: true, js: true do - include WaitForAjax - let(:project_master) { create(:user) } let(:project) { create(:project) } background do 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 1a1910455a1..70a41886985 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 @@ -1,8 +1,6 @@ require 'spec_helper' feature 'project owner sees a link to create a license file in empty project', feature: true, js: true do - include WaitForAjax - let(:project_master) { create(:user) } let(:project) { create(:empty_project) } background do diff --git a/spec/features/projects/files/undo_template_spec.rb b/spec/features/projects/files/undo_template_spec.rb index c51851d3f94..cd3af0b7d29 100644 --- a/spec/features/projects/files/undo_template_spec.rb +++ b/spec/features/projects/files/undo_template_spec.rb @@ -1,26 +1,25 @@ require 'spec_helper' -include WaitForAjax -feature 'Template Undo Button', js: true do +feature 'Template Undo Button', js: true do let(:project) { create(:project) } let(:user) { create(:user) } before do project.team << [user, :master] - login_as user + login_as user end - - context 'editing a matching file and applying a template' do + + context 'editing a matching file and applying a template' do before do - visit namespace_project_edit_blob_path(project.namespace, project, File.join(project.default_branch, "LICENSE")) + visit namespace_project_edit_blob_path(project.namespace, project, File.join(project.default_branch, "LICENSE")) select_file_template('.js-license-selector', 'Apache License 2.0') end - + scenario 'reverts template application' do try_template_undo('http://www.apache.org/licenses/', 'Apply a license template') end end - + context 'creating a non-matching file' do before do visit namespace_project_new_blob_path(project.namespace, project, 'master') diff --git a/spec/features/projects/issuable_templates_spec.rb b/spec/features/projects/issuable_templates_spec.rb index 62d0aedda48..d28a853bbc2 100644 --- a/spec/features/projects/issuable_templates_spec.rb +++ b/spec/features/projects/issuable_templates_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'issuable templates', feature: true, js: true do - include WaitForAjax - let(:user) { create(:user) } let(:project) { create(:project, :public) } @@ -163,12 +161,14 @@ feature 'issuable templates', feature: true, js: true do end def select_template(name) - first('.js-issuable-selector').click - first('.js-issuable-selector-wrap .dropdown-content a', text: name).click + find('.js-issuable-selector').click + + find('.js-issuable-selector-wrap .dropdown-content a', text: name, match: :first).click end def select_option(name) - first('.js-issuable-selector').click - first('.js-issuable-selector-wrap .dropdown-footer-list a', text: name).click + find('.js-issuable-selector').click + + find('.js-issuable-selector-wrap .dropdown-footer-list a', text: name, match: :first).click end end diff --git a/spec/features/projects/labels/update_prioritization_spec.rb b/spec/features/projects/labels/update_prioritization_spec.rb index 1e900d7e660..836f81fb16d 100644 --- a/spec/features/projects/labels/update_prioritization_spec.rb +++ b/spec/features/projects/labels/update_prioritization_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' feature 'Prioritize labels', feature: true do - include WaitForAjax include DragTo let(:user) { create(:user) } diff --git a/spec/features/projects/members/group_links_spec.rb b/spec/features/projects/members/group_links_spec.rb index cffb935ad5a..ab2b089db2e 100644 --- a/spec/features/projects/members/group_links_spec.rb +++ b/spec/features/projects/members/group_links_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'Projects > Members > Anonymous user sees members', feature: true, js: true do - include WaitForAjax - let(:user) { create(:user) } let(:group) { create(:group, :public) } let(:project) { create(:empty_project, :public) } diff --git a/spec/features/projects/members/list_spec.rb b/spec/features/projects/members/list_spec.rb new file mode 100644 index 00000000000..deea34214fb --- /dev/null +++ b/spec/features/projects/members/list_spec.rb @@ -0,0 +1,90 @@ +require 'spec_helper' + +feature 'Project members list', feature: true do + include Select2Helper + + let(:user1) { create(:user, name: 'John Doe') } + let(:user2) { create(:user, name: 'Mary Jane') } + let(:group) { create(:group) } + let(:project) { create(:project, namespace: group) } + + background do + login_as(user1) + group.add_owner(user1) + end + + scenario 'show members from project and group' do + project.add_developer(user2) + + visit_members_page + + expect(first_row.text).to include(user1.name) + expect(second_row.text).to include(user2.name) + end + + scenario 'show user once if member of both group and project' do + project.add_developer(user1) + + visit_members_page + + expect(first_row.text).to include(user1.name) + expect(second_row).to be_blank + end + + scenario 'update user acess level', :js do + project.add_developer(user2) + + visit_members_page + + page.within(second_row) do + click_button('Developer') + click_link('Reporter') + + expect(page).to have_button('Reporter') + end + end + + scenario 'add user to project', :js do + visit_members_page + + add_user(user2.id, 'Reporter') + + page.within(second_row) do + expect(page).to have_content(user2.name) + expect(page).to have_button('Reporter') + end + end + + scenario 'invite user to project', :js do + visit_members_page + + add_user('test@example.com', 'Reporter') + + page.within(second_row) do + expect(page).to have_content('test@example.com') + expect(page).to have_content('Invited') + expect(page).to have_button('Reporter') + end + end + + def first_row + page.all('ul.content-list > li')[0] + end + + def second_row + page.all('ul.content-list > li')[1] + end + + def add_user(id, role) + page.within ".users-project-form" do + select2(id, from: "#user_ids", multiple: true) + select(role, from: "access_level") + end + + click_button "Add to project" + end + + def visit_members_page + visit namespace_project_settings_members_path(project.namespace, project) + end +end diff --git a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb index c3f45be6e4b..19d14ad9af4 100644 --- a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb +++ b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' feature 'Projects > Members > Master adds member with expiration date', feature: true, js: true do - include WaitForAjax include Select2Helper include ActiveSupport::Testing::TimeHelpers diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb index de25d45f447..1bf8f710b9f 100644 --- a/spec/features/projects/members/user_requests_access_spec.rb +++ b/spec/features/projects/members/user_requests_access_spec.rb @@ -31,6 +31,17 @@ feature 'Projects > Members > User requests access', feature: true do expect(page).not_to have_content 'Leave Project' end + context 'code access is restricted' do + scenario 'user can request access' do + project.project_feature.update!(repository_access_level: ProjectFeature::PRIVATE, + builds_access_level: ProjectFeature::PRIVATE, + merge_requests_access_level: ProjectFeature::PRIVATE) + visit namespace_project_path(project.namespace, project) + + expect(page).to have_content 'Request Access' + end + end + scenario 'user is not listed in the project members page' do click_link 'Request Access' diff --git a/spec/features/projects/merge_request_button_spec.rb b/spec/features/projects/merge_request_button_spec.rb index 05f3162f13c..1370ab1c521 100644 --- a/spec/features/projects/merge_request_button_spec.rb +++ b/spec/features/projects/merge_request_button_spec.rb @@ -85,8 +85,8 @@ feature 'Merge Request button', feature: true do context 'on branches page' do 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) } + let(:url) { namespace_project_branches_path(project.namespace, project, search: 'feature') } + let(:fork_url) { namespace_project_branches_path(forked_project.namespace, forked_project, search: 'feature') } end end diff --git a/spec/features/projects/milestones/milestone_spec.rb b/spec/features/projects/milestones/milestone_spec.rb index dab78fd3571..b4fc0edbde8 100644 --- a/spec/features/projects/milestones/milestone_spec.rb +++ b/spec/features/projects/milestones/milestone_spec.rb @@ -63,4 +63,27 @@ feature 'Project milestone', :feature do expect(page).not_to have_content('Assign some issues to this milestone.') end end + + context 'when project has an issue' do + before do + create(:issue, project: project, milestone: milestone) + + visit namespace_project_milestone_path(project.namespace, project, milestone) + end + + describe 'the collapsed sidebar' do + before do + find('.milestone-sidebar .gutter-toggle').click + end + + it 'shows the total MR and issue counts' do + find('.milestone-sidebar .block', match: :first) + + aggregate_failures 'MR and issue blocks' do + expect(find('.milestone-sidebar .block.issues')).to have_content 1 + expect(find('.milestone-sidebar .block.merge-requests')).to have_content 0 + end + end + end + end end diff --git a/spec/features/projects/ref_switcher_spec.rb b/spec/features/projects/ref_switcher_spec.rb index 3b8f0b2d3f8..881ad7910dd 100644 --- a/spec/features/projects/ref_switcher_spec.rb +++ b/spec/features/projects/ref_switcher_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' feature 'Ref switcher', feature: true, js: true do - include WaitForAjax let(:user) { create(:user) } let(:project) { create(:project, :public) } diff --git a/spec/features/projects/settings/integration_settings_spec.rb b/spec/features/projects/settings/integration_settings_spec.rb new file mode 100644 index 00000000000..7909234556e --- /dev/null +++ b/spec/features/projects/settings/integration_settings_spec.rb @@ -0,0 +1,94 @@ +require 'spec_helper' + +feature 'Integration settings', feature: true do + let(:project) { create(:empty_project) } + let(:user) { create(:user) } + let(:role) { :developer } + let(:integrations_path) { namespace_project_settings_integrations_path(project.namespace, project) } + + background do + login_as(user) + project.team << [user, role] + end + + context 'for developer' do + given(:role) { :developer } + + scenario 'to be disallowed to view' do + visit integrations_path + + expect(page.status_code).to eq(404) + end + end + + context 'for master' do + given(:role) { :master } + + context 'Webhooks' do + let(:hook) { create(:project_hook, :all_events_enabled, enable_ssl_verification: true, project: project) } + let(:url) { generate(:url) } + + scenario 'show list of webhooks' do + hook + + visit integrations_path + + expect(page.status_code).to eq(200) + expect(page).to have_content(hook.url) + expect(page).to have_content('SSL Verification: enabled') + expect(page).to have_content('Push Events') + expect(page).to have_content('Tag Push Events') + expect(page).to have_content('Issues Events') + expect(page).to have_content('Confidential Issues Events') + expect(page).to have_content('Note Events') + expect(page).to have_content('Merge Requests Events') + expect(page).to have_content('Pipeline Events') + expect(page).to have_content('Wiki Page Events') + end + + scenario 'create webhook' do + visit integrations_path + + fill_in 'hook_url', with: url + check 'Tag push events' + check 'Enable SSL verification' + + click_button 'Add webhook' + + expect(page).to have_content(url) + expect(page).to have_content('SSL Verification: enabled') + expect(page).to have_content('Push Events') + expect(page).to have_content('Tag Push Events') + end + + scenario 'edit existing webhook' do + hook + visit integrations_path + + click_link 'Edit' + fill_in 'hook_url', with: url + check 'Enable SSL verification' + click_button 'Save changes' + + expect(page).to have_content 'SSL Verification: enabled' + expect(page).to have_content(url) + end + + scenario 'test existing webhook' do + WebMock.stub_request(:post, hook.url) + visit integrations_path + + click_link 'Test' + + expect(current_path).to eq(integrations_path) + end + + scenario 'remove existing webhook' do + hook + visit integrations_path + + expect { click_link 'Remove' }.to change(ProjectHook, :count).by(-1) + end + end + end +end diff --git a/spec/features/projects/snippets/show_spec.rb b/spec/features/projects/snippets/show_spec.rb new file mode 100644 index 00000000000..cedf3778c7e --- /dev/null +++ b/spec/features/projects/snippets/show_spec.rb @@ -0,0 +1,144 @@ +require 'spec_helper' + +feature 'Project snippet', :js, feature: true do + let(:user) { create(:user) } + let(:project) { create(:project, :repository) } + let(:snippet) { create(:project_snippet, project: project, file_name: file_name, content: content) } + + before do + project.team << [user, :master] + login_as(user) + end + + context 'Ruby file' do + let(:file_name) { 'popen.rb' } + let(:content) { project.repository.blob_at('master', 'files/ruby/popen.rb').data } + + before do + visit namespace_project_snippet_path(project.namespace, project, snippet) + + wait_for_ajax + end + + it 'displays the blob' do + aggregate_failures do + # shows highlighted Ruby code + expect(page).to have_content("require 'fileutils'") + + # does not show a viewer switcher + expect(page).not_to have_selector('.js-blob-viewer-switcher') + + # shows an enabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)') + + # shows a raw button + expect(page).to have_link('Open raw') + + # shows a download button + expect(page).to have_link('Download') + end + end + end + + context 'Markdown file' do + let(:file_name) { 'ruby-style-guide.md' } + let(:content) { project.repository.blob_at('master', 'files/markdown/ruby-style-guide.md').data } + + context 'visiting directly' do + before do + visit namespace_project_snippet_path(project.namespace, project, snippet) + + wait_for_ajax + end + + it 'displays the blob using the rich viewer' do + aggregate_failures do + # hides the simple viewer + expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false) + expect(page).to have_selector('.blob-viewer[data-type="rich"]') + + # shows rendered Markdown + expect(page).to have_link("PEP-8") + + # shows a viewer switcher + expect(page).to have_selector('.js-blob-viewer-switcher') + + # shows a disabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn.disabled') + + # shows a raw button + expect(page).to have_link('Open raw') + + # shows a download button + expect(page).to have_link('Download') + end + end + + context 'switching to the simple viewer' do + before do + find('.js-blob-viewer-switch-btn[data-viewer=simple]').click + + wait_for_ajax + end + + it 'displays the blob using the simple viewer' do + aggregate_failures do + # hides the rich viewer + expect(page).to have_selector('.blob-viewer[data-type="simple"]') + expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false) + + # shows highlighted Markdown code + expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)") + + # shows an enabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)') + end + end + + context 'switching to the rich viewer again' do + before do + find('.js-blob-viewer-switch-btn[data-viewer=rich]').click + + wait_for_ajax + end + + it 'displays the blob using the rich viewer' do + aggregate_failures do + # hides the simple viewer + expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false) + expect(page).to have_selector('.blob-viewer[data-type="rich"]') + + # shows an enabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)') + end + end + end + end + end + + context 'visiting with a line number anchor' do + before do + visit namespace_project_snippet_path(project.namespace, project, snippet, anchor: 'L1') + + wait_for_ajax + end + + it 'displays the blob using the simple viewer' do + aggregate_failures do + # hides the rich viewer + expect(page).to have_selector('.blob-viewer[data-type="simple"]') + expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false) + + # highlights the line in question + expect(page).to have_selector('#LC1.hll') + + # shows highlighted Markdown code + expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)") + + # shows an enabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)') + end + end + end + end +end diff --git a/spec/features/projects/user_create_dir_spec.rb b/spec/features/projects/user_create_dir_spec.rb index 2065abfb248..5dfdc465d7d 100644 --- a/spec/features/projects/user_create_dir_spec.rb +++ b/spec/features/projects/user_create_dir_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' feature 'New directory creation', feature: true, js: true do - include WaitForAjax include TargetBranchHelpers given(:user) { create(:user) } diff --git a/spec/features/projects/view_on_env_spec.rb b/spec/features/projects/view_on_env_spec.rb index 34c6a10950f..b7a41ca54e6 100644 --- a/spec/features/projects/view_on_env_spec.rb +++ b/spec/features/projects/view_on_env_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe 'View on environment', js: true do - include WaitForAjax - let(:branch_name) { 'feature' } let(:file_path) { 'files/ruby/feature.rb' } let(:project) { create(:project, :repository) } diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb index ba56030e28d..060e19596ae 100644 --- a/spec/features/projects_spec.rb +++ b/spec/features/projects_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature 'Project', feature: true do describe 'description' do - let(:project) { create(:project) } + let(:project) { create(:project, :repository) } let(:path) { namespace_project_path(project.namespace, project) } before do @@ -36,7 +36,7 @@ feature 'Project', feature: true do describe 'remove forked relationship', js: true do let(:user) { create(:user) } - let(:project) { create(:project, namespace: user.namespace) } + let(:project) { create(:empty_project, namespace: user.namespace) } before do login_with user @@ -57,7 +57,7 @@ feature 'Project', feature: true do describe 'removal', js: true do let(:user) { create(:user, username: 'test', name: 'test') } - let(:project) { create(:project, namespace: user.namespace, name: 'project1') } + let(:project) { create(:empty_project, namespace: user.namespace, name: 'project1') } before do login_with(user) @@ -75,10 +75,8 @@ feature 'Project', feature: true do end describe 'project title' do - include WaitForAjax - let(:user) { create(:user) } - let(:project) { create(:project, namespace: user.namespace) } + let(:project) { create(:empty_project, namespace: user.namespace) } before do login_with(user) @@ -94,8 +92,8 @@ feature 'Project', feature: true do describe 'project title' do let(:user) { create(:user) } - let(:project) { create(:project, namespace: user.namespace) } - let(:project2) { create(:project, namespace: user.namespace, path: 'test') } + let(:project) { create(:empty_project, namespace: user.namespace) } + let(:project2) { create(:empty_project, namespace: user.namespace, path: 'test') } let(:issue) { create(:issue, project: project) } context 'on issues page', js: true do diff --git a/spec/features/protected_branches/access_control_ce_spec.rb b/spec/features/protected_branches/access_control_ce_spec.rb index eb3cea775da..d30e7947106 100644 --- a/spec/features/protected_branches/access_control_ce_spec.rb +++ b/spec/features/protected_branches/access_control_ce_spec.rb @@ -9,7 +9,7 @@ RSpec.shared_examples "protected branches > access control > CE" do allowed_to_push_button = find(".js-allowed-to-push") unless allowed_to_push_button.text == access_type_name - allowed_to_push_button.click + allowed_to_push_button.trigger('click') within(".dropdown.open .dropdown-menu") { click_on access_type_name } end end diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb index 1a3f7b970f6..fc9b293c393 100644 --- a/spec/features/protected_branches_spec.rb +++ b/spec/features/protected_branches_spec.rb @@ -2,15 +2,13 @@ require 'spec_helper' Dir["./spec/features/protected_branches/*.rb"].sort.each { |f| require f } feature 'Projected Branches', feature: true, js: true do - include WaitForAjax - let(:user) { create(:user, :admin) } - let(:project) { create(:project) } + let(:project) { create(:project, :repository) } before { login_as(user) } def set_protected_branch_name(branch_name) - find(".js-protected-branch-select").click + find(".js-protected-branch-select").trigger('click') find(".dropdown-input-field").set(branch_name) click_on("Create wildcard #{branch_name}") end diff --git a/spec/features/protected_tags_spec.rb b/spec/features/protected_tags_spec.rb index 09e8c850de3..e3aa87ded28 100644 --- a/spec/features/protected_tags_spec.rb +++ b/spec/features/protected_tags_spec.rb @@ -2,10 +2,8 @@ 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) } + let(:project) { create(:project, :repository) } before { login_as(user) } diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb index e8ad28a00f0..da6388dcdf2 100644 --- a/spec/features/search_spec.rb +++ b/spec/features/search_spec.rb @@ -2,10 +2,9 @@ require 'spec_helper' describe "Search", feature: true do include FilteredSearchHelpers - include WaitForAjax let(:user) { create(:user) } - let(:project) { create(:project, namespace: user.namespace) } + let(:project) { create(:empty_project, namespace: user.namespace) } let!(:issue) { create(:issue, project: project, assignee: user) } let!(:issue2) { create(:issue, project: project, author: user) } @@ -62,6 +61,7 @@ describe "Search", feature: true do context 'search for comments' do context 'when comment belongs to a invalid commit' do + let(:project) { create(:project, :repository) } let(:note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'Bug here') } before { note.update_attributes(commit_id: 12345678) } @@ -103,6 +103,7 @@ describe "Search", feature: true do end it 'finds a commit' do + project = create(:project, :repository) { |p| p.add_reporter(user) } visit namespace_project_path(project.namespace, project) page.within '.search' do @@ -116,6 +117,7 @@ describe "Search", feature: true do end it 'finds a code' do + project = create(:project, :repository) { |p| p.add_reporter(user) } visit namespace_project_path(project.namespace, project) page.within '.search' do @@ -222,6 +224,8 @@ describe "Search", feature: true do end describe 'search for commits' do + let(:project) { create(:project, :repository) } + before do visit search_path(project_id: project.id) end diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb index 6ecdc8cbb71..26879a77c48 100644 --- a/spec/features/security/project/internal_access_spec.rb +++ b/spec/features/security/project/internal_access_spec.rb @@ -399,6 +399,44 @@ describe "Internal Project Access", feature: true do end end + describe 'GET /:project_path/builds/:id/trace' do + let(:pipeline) { create(:ci_pipeline, project: project) } + let(:build) { create(:ci_build, pipeline: pipeline) } + subject { trace_namespace_project_build_path(project.namespace, project, build.id) } + + context 'when allowed for public and internal' do + before do + project.update(public_builds: true) + end + + it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:owner).of(project) } + it { is_expected.to be_allowed_for(:master).of(project) } + it { is_expected.to be_allowed_for(:developer).of(project) } + it { is_expected.to be_allowed_for(:reporter).of(project) } + it { is_expected.to be_allowed_for(:guest).of(project) } + it { is_expected.to be_allowed_for(:user) } + it { is_expected.to be_denied_for(:external) } + it { is_expected.to be_denied_for(:visitor) } + end + + context 'when disallowed for public and internal' do + before do + project.update(public_builds: false) + end + + it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:owner).of(project) } + it { is_expected.to be_allowed_for(:master).of(project) } + it { is_expected.to be_allowed_for(:developer).of(project) } + it { is_expected.to be_allowed_for(:reporter).of(project) } + it { is_expected.to be_denied_for(:guest).of(project) } + it { is_expected.to be_denied_for(:user) } + it { is_expected.to be_denied_for(:external) } + it { is_expected.to be_denied_for(:visitor) } + end + end + describe "GET /:project_path/environments" do subject { namespace_project_environments_path(project.namespace, project) } @@ -428,6 +466,21 @@ describe "Internal Project Access", feature: true do it { is_expected.to be_denied_for(:visitor) } end + describe "GET /:project_path/environments/:id/deployments" do + let(:environment) { create(:environment, project: project) } + subject { namespace_project_environment_deployments_path(project.namespace, project, environment) } + + it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:owner).of(project) } + it { is_expected.to be_allowed_for(:master).of(project) } + it { is_expected.to be_allowed_for(:developer).of(project) } + it { is_expected.to be_allowed_for(:reporter).of(project) } + it { is_expected.to be_denied_for(:guest).of(project) } + it { is_expected.to be_denied_for(:user) } + it { is_expected.to be_denied_for(:external) } + it { is_expected.to be_denied_for(:visitor) } + end + describe "GET /:project_path/environments/new" do subject { new_namespace_project_environment_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 a8fc0624588..699ca4f724c 100644 --- a/spec/features/security/project/private_access_spec.rb +++ b/spec/features/security/project/private_access_spec.rb @@ -388,6 +388,38 @@ describe "Private Project Access", feature: true do end end + describe 'GET /:project_path/builds/:id/trace' do + let(:pipeline) { create(:ci_pipeline, project: project) } + let(:build) { create(:ci_build, pipeline: pipeline) } + subject { trace_namespace_project_build_path(project.namespace, project, build.id) } + + it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:owner).of(project) } + it { is_expected.to be_allowed_for(:master).of(project) } + it { is_expected.to be_allowed_for(:developer).of(project) } + it { is_expected.to be_allowed_for(:reporter).of(project) } + it { is_expected.to be_denied_for(:guest).of(project) } + it { is_expected.to be_denied_for(:user) } + it { is_expected.to be_denied_for(:external) } + it { is_expected.to be_denied_for(:visitor) } + + context 'when public builds is enabled' do + before do + project.update(public_builds: true) + end + + it { is_expected.to be_allowed_for(:guest).of(project) } + end + + context 'when public builds is disabled' do + before do + project.update(public_builds: false) + end + + it { is_expected.to be_denied_for(:guest).of(project) } + end + end + describe "GET /:project_path/environments" do subject { namespace_project_environments_path(project.namespace, project) } @@ -417,6 +449,21 @@ describe "Private Project Access", feature: true do it { is_expected.to be_denied_for(:visitor) } end + describe "GET /:project_path/environments/:id/deployments" do + let(:environment) { create(:environment, project: project) } + subject { namespace_project_environment_deployments_path(project.namespace, project, environment) } + + it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:owner).of(project) } + it { is_expected.to be_allowed_for(:master).of(project) } + it { is_expected.to be_allowed_for(:developer).of(project) } + it { is_expected.to be_allowed_for(:reporter).of(project) } + it { is_expected.to be_denied_for(:guest).of(project) } + it { is_expected.to be_denied_for(:user) } + it { is_expected.to be_denied_for(:external) } + it { is_expected.to be_denied_for(:visitor) } + end + describe "GET /:project_path/environments/new" do subject { new_namespace_project_environment_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 c4d2f50ca14..624f0d0f485 100644 --- a/spec/features/security/project/public_access_spec.rb +++ b/spec/features/security/project/public_access_spec.rb @@ -219,6 +219,44 @@ describe "Public Project Access", feature: true do end end + describe 'GET /:project_path/builds/:id/trace' do + let(:pipeline) { create(:ci_pipeline, project: project) } + let(:build) { create(:ci_build, pipeline: pipeline) } + subject { trace_namespace_project_build_path(project.namespace, project, build.id) } + + context 'when allowed for public' do + before do + project.update(public_builds: true) + end + + it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:owner).of(project) } + it { is_expected.to be_allowed_for(:master).of(project) } + it { is_expected.to be_allowed_for(:developer).of(project) } + it { is_expected.to be_allowed_for(:reporter).of(project) } + it { is_expected.to be_allowed_for(:guest).of(project) } + it { is_expected.to be_allowed_for(:user) } + it { is_expected.to be_allowed_for(:external) } + it { is_expected.to be_allowed_for(:visitor) } + end + + context 'when disallowed for public' do + before do + project.update(public_builds: false) + end + + it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:owner).of(project) } + it { is_expected.to be_allowed_for(:master).of(project) } + it { is_expected.to be_allowed_for(:developer).of(project) } + it { is_expected.to be_allowed_for(:reporter).of(project) } + it { is_expected.to be_denied_for(:guest).of(project) } + it { is_expected.to be_denied_for(:user) } + it { is_expected.to be_denied_for(:external) } + it { is_expected.to be_denied_for(:visitor) } + end + end + describe "GET /:project_path/environments" do subject { namespace_project_environments_path(project.namespace, project) } @@ -248,6 +286,21 @@ describe "Public Project Access", feature: true do it { is_expected.to be_denied_for(:visitor) } end + describe "GET /:project_path/environments/:id/deployments" do + let(:environment) { create(:environment, project: project) } + subject { namespace_project_environment_deployments_path(project.namespace, project, environment) } + + it { is_expected.to be_allowed_for(:admin) } + it { is_expected.to be_allowed_for(:owner).of(project) } + it { is_expected.to be_allowed_for(:master).of(project) } + it { is_expected.to be_allowed_for(:developer).of(project) } + it { is_expected.to be_allowed_for(:reporter).of(project) } + it { is_expected.to be_denied_for(:guest).of(project) } + it { is_expected.to be_denied_for(:user) } + it { is_expected.to be_denied_for(:external) } + it { is_expected.to be_denied_for(:visitor) } + end + describe "GET /:project_path/environments/new" do subject { new_namespace_project_environment_path(project.namespace, project) } diff --git a/spec/features/snippets/create_snippet_spec.rb b/spec/features/snippets/create_snippet_spec.rb index 5470276bf06..9409c323288 100644 --- a/spec/features/snippets/create_snippet_spec.rb +++ b/spec/features/snippets/create_snippet_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature 'Create Snippet', feature: true do +feature 'Create Snippet', :js, feature: true do before do login_as :user visit new_snippet_path @@ -9,10 +9,11 @@ feature 'Create Snippet', feature: true do scenario 'Authenticated user creates a snippet' do fill_in 'personal_snippet_title', with: 'My Snippet Title' page.within('.file-editor') do - find(:xpath, "//input[@id='personal_snippet_content']").set 'Hello World!' + find('.ace_editor').native.send_keys 'Hello World!' end click_button 'Create snippet' + wait_for_ajax expect(page).to have_content('My Snippet Title') expect(page).to have_content('Hello World!') @@ -22,10 +23,11 @@ feature 'Create Snippet', feature: true do fill_in 'personal_snippet_title', with: 'My Snippet Title' page.within('.file-editor') do find(:xpath, "//input[@id='personal_snippet_file_name']").set 'snippet+file+name' - find(:xpath, "//input[@id='personal_snippet_content']").set 'Hello World!' + find('.ace_editor').native.send_keys 'Hello World!' end click_button 'Create snippet' + wait_for_ajax expect(page).to have_content('My Snippet Title') expect(page).to have_content('snippet+file+name') diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb new file mode 100644 index 00000000000..c646039e0b1 --- /dev/null +++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' + +describe 'Comments on personal snippets', feature: true do + let!(:user) { create(:user) } + let!(:snippet) { create(:personal_snippet, :public) } + let!(:snippet_notes) do + [ + create(:note_on_personal_snippet, noteable: snippet, author: user), + create(:note_on_personal_snippet, noteable: snippet) + ] + end + let!(:other_note) { create(:note_on_personal_snippet) } + + before do + login_as user + visit snippet_path(snippet) + end + + subject { page } + + context 'viewing the snippet detail page' do + it 'contains notes for a snippet with correct action icons' do + expect(page).to have_selector('#notes-list li', count: 2) + + # comment authored by current user + page.within("#notes-list li#note_#{snippet_notes[0].id}") do + expect(page).to have_content(snippet_notes[0].note) + expect(page).to have_selector('.js-note-delete') + expect(page).to have_selector('.note-emoji-button') + end + + page.within("#notes-list li#note_#{snippet_notes[1].id}") do + expect(page).to have_content(snippet_notes[1].note) + expect(page).not_to have_selector('.js-note-delete') + expect(page).to have_selector('.note-emoji-button') + end + end + end +end diff --git a/spec/features/snippets/public_snippets_spec.rb b/spec/features/snippets/public_snippets_spec.rb index 34300ccb940..2df483818c3 100644 --- a/spec/features/snippets/public_snippets_spec.rb +++ b/spec/features/snippets/public_snippets_spec.rb @@ -1,10 +1,11 @@ require 'rails_helper' -feature 'Public Snippets', feature: true do +feature 'Public Snippets', :js, feature: true do scenario 'Unauthenticated user should see public snippets' do public_snippet = create(:personal_snippet, :public) visit snippet_path(public_snippet) + wait_for_ajax expect(page).to have_content(public_snippet.content) end diff --git a/spec/features/snippets/show_spec.rb b/spec/features/snippets/show_spec.rb new file mode 100644 index 00000000000..e36cf547f80 --- /dev/null +++ b/spec/features/snippets/show_spec.rb @@ -0,0 +1,138 @@ +require 'spec_helper' + +feature 'Snippet', :js, feature: true do + let(:project) { create(:project, :repository) } + let(:snippet) { create(:personal_snippet, :public, file_name: file_name, content: content) } + + context 'Ruby file' do + let(:file_name) { 'popen.rb' } + let(:content) { project.repository.blob_at('master', 'files/ruby/popen.rb').data } + + before do + visit snippet_path(snippet) + + wait_for_ajax + end + + it 'displays the blob' do + aggregate_failures do + # shows highlighted Ruby code + expect(page).to have_content("require 'fileutils'") + + # does not show a viewer switcher + expect(page).not_to have_selector('.js-blob-viewer-switcher') + + # shows an enabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)') + + # shows a raw button + expect(page).to have_link('Open raw') + + # shows a download button + expect(page).to have_link('Download') + end + end + end + + context 'Markdown file' do + let(:file_name) { 'ruby-style-guide.md' } + let(:content) { project.repository.blob_at('master', 'files/markdown/ruby-style-guide.md').data } + + context 'visiting directly' do + before do + visit snippet_path(snippet) + + wait_for_ajax + end + + it 'displays the blob using the rich viewer' do + aggregate_failures do + # hides the simple viewer + expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false) + expect(page).to have_selector('.blob-viewer[data-type="rich"]') + + # shows rendered Markdown + expect(page).to have_link("PEP-8") + + # shows a viewer switcher + expect(page).to have_selector('.js-blob-viewer-switcher') + + # shows a disabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn.disabled') + + # shows a raw button + expect(page).to have_link('Open raw') + + # shows a download button + expect(page).to have_link('Download') + end + end + + context 'switching to the simple viewer' do + before do + find('.js-blob-viewer-switch-btn[data-viewer=simple]').click + + wait_for_ajax + end + + it 'displays the blob using the simple viewer' do + aggregate_failures do + # hides the rich viewer + expect(page).to have_selector('.blob-viewer[data-type="simple"]') + expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false) + + # shows highlighted Markdown code + expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)") + + # shows an enabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)') + end + end + + context 'switching to the rich viewer again' do + before do + find('.js-blob-viewer-switch-btn[data-viewer=rich]').click + + wait_for_ajax + end + + it 'displays the blob using the rich viewer' do + aggregate_failures do + # hides the simple viewer + expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false) + expect(page).to have_selector('.blob-viewer[data-type="rich"]') + + # shows an enabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)') + end + end + end + end + end + + context 'visiting with a line number anchor' do + before do + visit snippet_path(snippet, anchor: 'L1') + + wait_for_ajax + end + + it 'displays the blob using the simple viewer' do + aggregate_failures do + # hides the rich viewer + expect(page).to have_selector('.blob-viewer[data-type="simple"]') + expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false) + + # highlights the line in question + expect(page).to have_selector('#LC1.hll') + + # shows highlighted Markdown code + expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)") + + # shows an enabled copy button + expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)') + end + end + end + end +end diff --git a/spec/features/task_lists_spec.rb b/spec/features/task_lists_spec.rb index a5d14aa19f1..c33692fc4a9 100644 --- a/spec/features/task_lists_spec.rb +++ b/spec/features/task_lists_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' feature 'Task Lists', feature: true do include Warden::Test::Helpers - let(:project) { create(:project) } + let(:project) { create(:empty_project) } let(:user) { create(:user) } let(:user2) { create(:user) } @@ -240,6 +240,7 @@ feature 'Task Lists', feature: true do end describe 'multiple tasks' do + let(:project) { create(:project, :repository) } let!(:merge) { create(:merge_request, :simple, description: markdown, author: user, source_project: project) } it 'renders for description' do diff --git a/spec/features/todos/todos_filtering_spec.rb b/spec/features/todos/todos_filtering_spec.rb index e8f06916d53..f32e70c2c3f 100644 --- a/spec/features/todos/todos_filtering_spec.rb +++ b/spec/features/todos/todos_filtering_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe 'Dashboard > User filters todos', feature: true, js: true do - include WaitForAjax - let(:user_1) { create(:user, username: 'user_1', name: 'user_1') } let(:user_2) { create(:user, username: 'user_2', name: 'user_2') } @@ -47,8 +45,8 @@ describe 'Dashboard > User filters todos', feature: true, js: true do wait_for_ajax - expect(find('.todos-list')).to have_content user_1.name - expect(find('.todos-list')).not_to have_content user_2.name + expect(find('.todos-list')).to have_content 'merge request' + expect(find('.todos-list')).not_to have_content 'issue' end it "shows only authors of existing todos" do diff --git a/spec/features/todos/todos_spec.rb b/spec/features/todos/todos_spec.rb index c270511c903..be5b3af417f 100644 --- a/spec/features/todos/todos_spec.rb +++ b/spec/features/todos/todos_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe 'Dashboard Todos', feature: true do - include WaitForAjax - let(:user) { create(:user) } let(:author) { create(:user) } let(:project) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) } @@ -101,6 +99,83 @@ describe 'Dashboard Todos', feature: true do end end + context 'User created todos for themself' do + before do + login_as(user) + end + + context 'issue assigned todo' do + before do + create(:todo, :assigned, user: user, project: project, target: issue, author: user) + visit dashboard_todos_path + end + + it 'shows issue assigned to yourself message' do + page.within('.js-todos-all') do + expect(page).to have_content("You assigned issue #{issue.to_reference(full: true)} to yourself") + end + end + end + + context 'marked todo' do + before do + create(:todo, :marked, user: user, project: project, target: issue, author: user) + visit dashboard_todos_path + end + + it 'shows you added a todo message' do + page.within('.js-todos-all') do + expect(page).to have_content("You added a todo for issue #{issue.to_reference(full: true)}") + expect(page).not_to have_content('to yourself') + end + end + end + + context 'mentioned todo' do + before do + create(:todo, :mentioned, user: user, project: project, target: issue, author: user) + visit dashboard_todos_path + end + + it 'shows you mentioned yourself message' do + page.within('.js-todos-all') do + expect(page).to have_content("You mentioned yourself on issue #{issue.to_reference(full: true)}") + expect(page).not_to have_content('to yourself') + end + end + end + + context 'directly_addressed todo' do + before do + create(:todo, :directly_addressed, user: user, project: project, target: issue, author: user) + visit dashboard_todos_path + end + + it 'shows you directly addressed yourself message' do + page.within('.js-todos-all') do + expect(page).to have_content("You directly addressed yourself on issue #{issue.to_reference(full: true)}") + expect(page).not_to have_content('to yourself') + end + end + end + + context 'approval todo' do + let(:merge_request) { create(:merge_request) } + + before do + create(:todo, :approval_required, user: user, project: project, target: merge_request, author: user) + visit dashboard_todos_path + end + + it 'shows you set yourself as an approver message' do + page.within('.js-todos-all') do + expect(page).to have_content("You set yourself as an approver for merge request #{merge_request.to_reference(full: true)}") + expect(page).not_to have_content('to yourself') + end + end + end + end + context 'User has done todos', js: true do before do create(:todo, :mentioned, :done, user: user, project: project, target: issue, author: author) diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb index c877cfdd978..544d2dcb87f 100644 --- a/spec/features/u2f_spec.rb +++ b/spec/features/u2f_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do - include WaitForAjax - before { allow_any_instance_of(U2fHelper).to receive(:inject_u2f_api?).and_return(true) } def manage_two_factor_authentication diff --git a/spec/features/users/projects_spec.rb b/spec/features/users/projects_spec.rb index 1d75fe434b0..373b64808f8 100644 --- a/spec/features/users/projects_spec.rb +++ b/spec/features/users/projects_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe 'Projects tab on a user profile', :feature, :js do - include WaitForAjax - let(:user) { create(:user) } let!(:project) { create(:empty_project, namespace: user.namespace) } let!(:project2) { create(:empty_project, namespace: user.namespace) } diff --git a/spec/features/users/snippets_spec.rb b/spec/features/users/snippets_spec.rb index ce7e809ec76..1546a06b80c 100644 --- a/spec/features/users/snippets_spec.rb +++ b/spec/features/users/snippets_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe 'Snippets tab on a user profile', feature: true, js: true do - include WaitForAjax - context 'when the user has snippets' do let(:user) { create(:user) } let!(:snippets) { create_list(:snippet, 2, :public, author: user) } diff --git a/spec/features/users_spec.rb b/spec/features/users_spec.rb index 2de0fbe7ab2..c43feadc808 100644 --- a/spec/features/users_spec.rb +++ b/spec/features/users_spec.rb @@ -68,7 +68,6 @@ feature 'Users', feature: true, js: true do end feature 'username validation' do - include WaitForAjax let(:loading_icon) { '.fa.fa-spinner' } let(:username_input) { 'new_user_username' } diff --git a/spec/features/variables_spec.rb b/spec/features/variables_spec.rb index a362d6fd3b6..b83a230c1f8 100644 --- a/spec/features/variables_spec.rb +++ b/spec/features/variables_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe 'Project variables', js: true do let(:user) { create(:user) } - let(:project) { create(:project) } + let(:project) { create(:empty_project) } let(:variable) { create(:ci_variable, key: 'test_key', value: 'test value') } before do |