diff options
author | Lin Jen-Shin <godfat@godfat.org> | 2016-08-18 19:34:10 +0800 |
---|---|---|
committer | Lin Jen-Shin <godfat@godfat.org> | 2016-08-18 19:34:10 +0800 |
commit | 62127dc95a28d6e7018a72c1a643dbf828a806d4 (patch) | |
tree | 29af38b74b3baf28829a50ddc6aa3186cee94e94 /spec/features | |
parent | 17d0406546885bedf2196c61a5991092b3fbe7c0 (diff) | |
parent | 2c1062f81e3c39cf8a45185c203995a43b91bf65 (diff) | |
download | gitlab-ce-62127dc95a28d6e7018a72c1a643dbf828a806d4.tar.gz |
Merge remote-tracking branch 'upstream/master' into artifacts-from-ref-and-build-name
* upstream/master: (359 commits)
Add new image to show the 'Reset template' button
Refactor description templates documentation
Remove index from pipeline toggles
Hide `Create new list button` on Issues and MRs pages
Remove params from build; general refactor
Style build container box; add check mark to active build
Display jobs as scrolling list in sidebar
Move stages and jobs to build sidebar
Removed vue assets
Move skipped tests to end of array
Remove unused data attributes
Update changelog
Style build dropdowns
Populate dropdowns with current build on pageload
Selecting stage updates builds dropdown
Add data attributes to builds
Change active state of list items; style dropdown items
Hide dropdown if all tests fit on one line; add counter to dropdown
Add overflow tests to dropdown
Order by build status
...
Diffstat (limited to 'spec/features')
-rw-r--r-- | spec/features/boards/boards_spec.rb | 598 | ||||
-rw-r--r-- | spec/features/merge_requests/conflicts_spec.rb | 72 | ||||
-rw-r--r-- | spec/features/merge_requests/create_new_mr_spec.rb | 19 | ||||
-rw-r--r-- | spec/features/merge_requests/pipelines_spec.rb | 48 | ||||
-rw-r--r-- | spec/features/projects/issues/list_spec.rb | 20 | ||||
-rw-r--r-- | spec/features/projects/merge_requests/list_spec.rb | 20 | ||||
-rw-r--r-- | spec/features/projects/pipelines_spec.rb | 6 |
7 files changed, 781 insertions, 2 deletions
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb new file mode 100644 index 00000000000..e4c5a10ce7e --- /dev/null +++ b/spec/features/boards/boards_spec.rb @@ -0,0 +1,598 @@ +require 'rails_helper' + +describe 'Issue Boards', feature: true, js: true do + include WaitForAjax + + let(:project) { create(:empty_project, :public) } + let(:user) { create(:user) } + let!(:user2) { create(:user) } + + before do + project.create_board + project.board.lists.create(list_type: :backlog) + project.board.lists.create(list_type: :done) + + project.team << [user, :master] + project.team << [user2, :master] + + login_as(user) + end + + context 'no lists' do + before do + visit namespace_project_board_path(project.namespace, project) + wait_for_vue_resource + expect(page).to have_selector('.board', count: 3) + end + + it 'shows blank state' do + expect(page).to have_content('Welcome to your Issue Board!') + end + + it 'hides the blank state when clicking nevermind button' do + page.within(find('.board-blank-state')) do + click_button("Nevermind, I'll use my own") + end + expect(page).to have_selector('.board', count: 2) + end + + it 'creates default lists' do + lists = ['Backlog', 'Development', 'Testing', 'Production', 'Ready', 'Done'] + + page.within(find('.board-blank-state')) do + click_button('Add default lists') + end + wait_for_vue_resource + + expect(page).to have_selector('.board', count: 6) + + page.all('.board').each_with_index do |list, i| + expect(list.find('.board-title')).to have_content(lists[i]) + end + end + end + + context 'with lists' do + let(:milestone) { create(:milestone, project: project) } + + let(:planning) { create(:label, project: project, name: 'Planning') } + let(:development) { create(:label, project: project, name: 'Development') } + let(:testing) { create(:label, project: project, name: 'Testing') } + let(:bug) { create(:label, project: project, name: 'Bug') } + let!(:backlog) { create(:label, project: project, name: 'Backlog') } + let!(:done) { create(:label, project: project, name: 'Done') } + + let!(:list1) { create(:list, board: project.board, label: planning, position: 0) } + let!(:list2) { create(:list, board: project.board, label: development, position: 1) } + + let!(:confidential_issue) { create(:issue, :confidential, project: project, author: user) } + let!(:issue1) { create(:issue, project: project, assignee: user) } + let!(:issue2) { create(:issue, project: project, author: user2) } + let!(:issue3) { create(:issue, project: project) } + let!(:issue4) { create(:issue, project: project) } + let!(:issue5) { create(:labeled_issue, project: project, labels: [planning], milestone: milestone) } + let!(:issue6) { create(:labeled_issue, project: project, labels: [planning, development]) } + let!(:issue7) { create(:labeled_issue, project: project, labels: [development]) } + let!(:issue8) { create(:closed_issue, project: project) } + let!(:issue9) { create(:labeled_issue, project: project, labels: [testing, bug]) } + + before do + visit namespace_project_board_path(project.namespace, project) + + wait_for_vue_resource + + expect(page).to have_selector('.board', count: 4) + expect(find('.board:nth-child(1)')).to have_selector('.card') + expect(find('.board:nth-child(2)')).to have_selector('.card') + expect(find('.board:nth-child(3)')).to have_selector('.card') + expect(find('.board:nth-child(4)')).to have_selector('.card') + end + + it 'shows lists' do + expect(page).to have_selector('.board', count: 4) + end + + it 'shows issues in lists' do + page.within(find('.board:nth-child(2)')) do + expect(page.find('.board-header')).to have_content('2') + expect(page).to have_selector('.card', count: 2) + end + + page.within(find('.board:nth-child(3)')) do + expect(page.find('.board-header')).to have_content('2') + expect(page).to have_selector('.card', count: 2) + end + end + + it 'shows confidential issues with icon' do + page.within(find('.board', match: :first)) do + expect(page).to have_selector('.confidential-icon', count: 1) + end + end + + it 'allows user to delete board' do + page.within(find('.board:nth-child(2)')) do + find('.board-delete').click + end + + wait_for_vue_resource + + expect(page).to have_selector('.board', count: 3) + end + + it 'removes checkmark in new list dropdown after deleting' do + click_button 'Create new list' + wait_for_ajax + + page.within(find('.board:nth-child(2)')) do + find('.board-delete').click + end + + wait_for_vue_resource + + expect(page).to have_selector('.board', count: 3) + expect(find(".js-board-list-#{planning.id}", visible: false)).not_to have_css('.is-active') + end + + it 'infinite scrolls list' do + 50.times do + create(:issue, project: project) + end + + visit namespace_project_board_path(project.namespace, project) + wait_for_vue_resource + + page.within(find('.board', match: :first)) do + expect(page.find('.board-header')).to have_content('20') + expect(page).to have_selector('.card', count: 20) + + evaluate_script("document.querySelectorAll('.board .board-list')[0].scrollTop = document.querySelectorAll('.board .board-list')[0].scrollHeight") + + expect(page.find('.board-header')).to have_content('40') + expect(page).to have_selector('.card', count: 40) + end + end + + context 'backlog' do + it 'shows issues in backlog with no labels' do + page.within(find('.board', match: :first)) do + expect(page.find('.board-header')).to have_content('6') + expect(page).to have_selector('.card', count: 6) + end + end + + it 'is searchable' do + page.within(find('.board', match: :first)) do + find('.form-control').set issue1.title + + expect(page).to have_selector('.card', count: 1) + end + end + + it 'clears search' do + page.within(find('.board', match: :first)) do + find('.form-control').set issue1.title + + expect(page).to have_selector('.card', count: 1) + + find('.board-search-clear-btn').click + + expect(page).to have_selector('.card', count: 6) + end + end + + it 'moves issue from backlog into list' do + drag_to(list_to_index: 1) + + page.within(find('.board', match: :first)) do + expect(page.find('.board-header')).to have_content('5') + expect(page).to have_selector('.card', count: 5) + end + + page.within(find('.board:nth-child(2)')) do + expect(page.find('.board-header')).to have_content('3') + expect(page).to have_selector('.card', count: 3) + end + end + end + + context 'done' do + it 'shows list of done issues' do + expect(find('.board:nth-child(4)')).to have_selector('.card', count: 1) + end + + it 'moves issue to done' do + drag_to(list_from_index: 0, list_to_index: 3) + + expect(find('.board:nth-child(4)')).to have_selector('.card', count: 2) + expect(find('.board:nth-child(4)')).to have_content(issue9.title) + expect(find('.board:nth-child(4)')).not_to have_content(planning.title) + end + + it 'removes all of the same issue to done' do + drag_to(list_from_index: 1, list_to_index: 3) + + expect(find('.board:nth-child(2)')).to have_selector('.card', count: 1) + expect(find('.board:nth-child(3)')).to have_selector('.card', count: 1) + expect(find('.board:nth-child(4)')).to have_content(issue6.title) + expect(find('.board:nth-child(4)')).not_to have_content(planning.title) + end + end + + context 'lists' do + it 'changes position of list' do + drag_to(list_from_index: 1, list_to_index: 2, selector: '.board-header') + + expect(find('.board:nth-child(2)')).to have_content(development.title) + expect(find('.board:nth-child(2)')).to have_content(planning.title) + end + + it 'issue moves between lists' do + drag_to(list_from_index: 1, card_index: 1, list_to_index: 2) + + expect(find('.board:nth-child(2)')).to have_selector('.card', count: 1) + expect(find('.board:nth-child(3)')).to have_selector('.card', count: 3) + expect(find('.board:nth-child(3)')).to have_content(issue6.title) + expect(find('.board:nth-child(3)').all('.card').last).not_to have_content(development.title) + end + + it 'issue moves between lists' do + drag_to(list_from_index: 2, list_to_index: 1) + + expect(find('.board:nth-child(2)')).to have_selector('.card', count: 3) + expect(find('.board:nth-child(3)')).to have_selector('.card', count: 1) + expect(find('.board:nth-child(2)')).to have_content(issue7.title) + expect(find('.board:nth-child(2)').all('.card').first).not_to have_content(planning.title) + end + + it 'issue moves from done' do + drag_to(list_from_index: 3, list_to_index: 1) + + expect(find('.board:nth-child(2)')).to have_selector('.card', count: 3) + expect(find('.board:nth-child(2)')).to have_content(issue8.title) + end + + context 'issue card' do + it 'shows assignee' do + page.within(find('.board', match: :first)) do + expect(page).to have_selector('.avatar', count: 1) + end + end + end + + context 'new list' do + it 'shows all labels in new list dropdown' do + click_button 'Create new list' + + page.within('.dropdown-menu-issues-board-new') do + expect(page).to have_content(planning.title) + expect(page).to have_content(development.title) + expect(page).to have_content(testing.title) + end + end + + it 'creates new list for label' do + click_button 'Create new list' + + page.within('.dropdown-menu-issues-board-new') do + click_link testing.title + end + + wait_for_vue_resource + + expect(page).to have_selector('.board', count: 5) + end + + it 'creates new list for Backlog label' do + click_button 'Create new list' + + page.within('.dropdown-menu-issues-board-new') do + click_link backlog.title + end + + wait_for_vue_resource + + expect(page).to have_selector('.board', count: 5) + end + + it 'creates new list for Done label' do + click_button 'Create new list' + + page.within('.dropdown-menu-issues-board-new') do + click_link done.title + end + + wait_for_vue_resource + + expect(page).to have_selector('.board', count: 5) + end + + it 'moves issues from backlog into new list' do + page.within(find('.board', match: :first)) do + expect(page.find('.board-header')).to have_content('6') + expect(page).to have_selector('.card', count: 6) + end + + click_button 'Create new list' + + page.within('.dropdown-menu-issues-board-new') do + click_link testing.title + end + + wait_for_vue_resource + + page.within(find('.board', match: :first)) do + expect(page.find('.board-header')).to have_content('5') + expect(page).to have_selector('.card', count: 5) + end + end + end + end + + context 'filtering' do + it 'filters by author' do + page.within '.issues-filters' do + click_button('Author') + + page.within '.dropdown-menu-author' do + click_link(user2.name) + end + wait_for_vue_resource(spinner: false) + + expect(find('.js-author-search')).to have_content(user2.name) + end + + wait_for_vue_resource + + page.within(find('.board', match: :first)) do + expect(page.find('.board-header')).to have_content('1') + expect(page).to have_selector('.card', count: 1) + end + + page.within(find('.board:nth-child(2)')) do + expect(page.find('.board-header')).to have_content('0') + expect(page).to have_selector('.card', count: 0) + end + end + + it 'filters by assignee' do + page.within '.issues-filters' do + click_button('Assignee') + + page.within '.dropdown-menu-assignee' do + click_link(user.name) + end + wait_for_vue_resource(spinner: false) + + expect(find('.js-assignee-search')).to have_content(user.name) + end + + wait_for_vue_resource + + page.within(find('.board', match: :first)) do + expect(page.find('.board-header')).to have_content('1') + expect(page).to have_selector('.card', count: 1) + end + + page.within(find('.board:nth-child(2)')) do + expect(page.find('.board-header')).to have_content('0') + expect(page).to have_selector('.card', count: 0) + end + end + + it 'filters by milestone' do + page.within '.issues-filters' do + click_button('Milestone') + + page.within '.milestone-filter' do + click_link(milestone.title) + end + wait_for_vue_resource(spinner: false) + + expect(find('.js-milestone-select')).to have_content(milestone.title) + end + + wait_for_vue_resource + + page.within(find('.board', match: :first)) do + expect(page.find('.board-header')).to have_content('0') + expect(page).to have_selector('.card', count: 0) + end + + page.within(find('.board:nth-child(2)')) do + expect(page.find('.board-header')).to have_content('1') + expect(page).to have_selector('.card', count: 1) + end + end + + it 'filters by label' do + page.within '.issues-filters' do + click_button('Label') + + page.within '.dropdown-menu-labels' do + click_link(testing.title) + wait_for_vue_resource(spinner: false) + find('.dropdown-menu-close').click + end + end + + wait_for_vue_resource + + page.within(find('.board', match: :first)) do + expect(page.find('.board-header')).to have_content('1') + expect(page).to have_selector('.card', count: 1) + end + + page.within(find('.board:nth-child(2)')) do + expect(page.find('.board-header')).to have_content('0') + expect(page).to have_selector('.card', count: 0) + end + end + + it 'infinite scrolls list with label filter' do + 50.times do + create(:labeled_issue, project: project, labels: [testing]) + end + + page.within '.issues-filters' do + click_button('Label') + + page.within '.dropdown-menu-labels' do + click_link(testing.title) + wait_for_vue_resource(spinner: false) + find('.dropdown-menu-close').click + end + end + + wait_for_vue_resource + + page.within(find('.board', match: :first)) do + expect(page.find('.board-header')).to have_content('20') + expect(page).to have_selector('.card', count: 20) + + evaluate_script("document.querySelectorAll('.board .board-list')[0].scrollTop = document.querySelectorAll('.board .board-list')[0].scrollHeight") + + expect(page.find('.board-header')).to have_content('40') + expect(page).to have_selector('.card', count: 40) + end + end + + it 'filters by multiple labels' do + page.within '.issues-filters' do + click_button('Label') + + page.within '.dropdown-menu-labels' do + click_link(testing.title) + wait_for_vue_resource(spinner: false) + click_link(bug.title) + wait_for_vue_resource(spinner: false) + find('.dropdown-menu-close').click + end + end + + wait_for_vue_resource + + page.within(find('.board', match: :first)) do + expect(page.find('.board-header')).to have_content('1') + expect(page).to have_selector('.card', count: 1) + end + + page.within(find('.board:nth-child(2)')) do + expect(page.find('.board-header')).to have_content('0') + expect(page).to have_selector('.card', count: 0) + end + end + + it 'filters by no label' do + page.within '.issues-filters' do + click_button('Label') + + page.within '.dropdown-menu-labels' do + click_link("No Label") + wait_for_vue_resource(spinner: false) + find('.dropdown-menu-close').click + end + end + + wait_for_vue_resource + + page.within(find('.board', match: :first)) do + expect(page.find('.board-header')).to have_content('5') + expect(page).to have_selector('.card', count: 5) + end + + page.within(find('.board:nth-child(2)')) do + expect(page.find('.board-header')).to have_content('0') + expect(page).to have_selector('.card', count: 0) + end + end + + it 'filters by clicking label button on issue' do + page.within(find('.board', match: :first)) do + expect(page).to have_selector('.card', count: 6) + click_button(bug.title) + wait_for_vue_resource(spinner: false) + end + + page.within(find('.board', match: :first)) do + expect(page.find('.board-header')).to have_content('1') + expect(page).to have_selector('.card', count: 1) + end + + page.within(find('.board:nth-child(2)')) do + expect(page.find('.board-header')).to have_content('0') + expect(page).to have_selector('.card', count: 0) + end + + page.within('.labels-filter') do + expect(find('.dropdown-toggle-text')).to have_content(bug.title) + end + end + + it 'removes label filter by clicking label button on issue' do + page.within(find('.board', match: :first)) do + page.within(find('.card', match: :first)) do + click_button(bug.title) + end + wait_for_vue_resource(spinner: false) + + expect(page).to have_selector('.card', count: 1) + end + + wait_for_vue_resource + + page.within('.labels-filter') do + expect(find('.dropdown-toggle-text')).to have_content(bug.title) + end + end + end + end + + context 'signed out user' do + before do + logout + visit namespace_project_board_path(project.namespace, project) + wait_for_vue_resource + end + + it 'does not show create new list' do + expect(page).not_to have_selector('.js-new-board-list') + end + end + + context 'as guest user' do + let(:user_guest) { create(:user) } + + before do + project.team << [user_guest, :guest] + logout + login_as(user_guest) + visit namespace_project_board_path(project.namespace, project) + wait_for_vue_resource + end + + it 'does not show create new list' do + expect(page).not_to have_selector('.js-new-board-list') + end + end + + def drag_to(list_from_index: 0, card_index: 0, to_index: 0, list_to_index: 0, selector: '.board-list') + evaluate_script("simulateDrag({scrollable: document.getElementById('board-app'), from: {el: $('#{selector}').eq(#{list_from_index}).get(0), index: #{card_index}}, to: {el: $('.board-list').eq(#{list_to_index}).get(0), index: #{to_index}}});") + + Timeout.timeout(Capybara.default_max_wait_time) do + loop until page.evaluate_script('window.SIMULATE_DRAG_ACTIVE').zero? + end + + wait_for_vue_resource + end + + def wait_for_vue_resource(spinner: true) + Timeout.timeout(Capybara.default_max_wait_time) do + loop until page.evaluate_script('Vue.activeResources').zero? + end + + if spinner + expect(find('.boards-list')).not_to have_selector('.fa-spinner') + end + end +end diff --git a/spec/features/merge_requests/conflicts_spec.rb b/spec/features/merge_requests/conflicts_spec.rb new file mode 100644 index 00000000000..930c36ade2b --- /dev/null +++ b/spec/features/merge_requests/conflicts_spec.rb @@ -0,0 +1,72 @@ +require 'spec_helper' + +feature 'Merge request conflict resolution', js: true, feature: true do + include WaitForAjax + + let(:user) { create(:user) } + let(:project) { create(:project) } + + def create_merge_request(source_branch) + create(:merge_request, source_branch: source_branch, target_branch: 'conflict-start', source_project: project) do |mr| + mr.mark_as_unmergeable + end + end + + context 'when a merge request can be resolved in the UI' do + let(:merge_request) { create_merge_request('conflict-resolvable') } + + before do + project.team << [user, :developer] + login_as(user) + + visit namespace_project_merge_request_path(project.namespace, project, merge_request) + end + + it 'shows a link to the conflict resolution page' do + expect(page).to have_link('conflicts', href: /\/conflicts\Z/) + end + + context 'visiting the conflicts resolution page' do + before { click_link('conflicts', href: /\/conflicts\Z/) } + + it 'shows the conflicts' do + begin + expect(find('#conflicts')).to have_content('popen.rb') + rescue Capybara::Poltergeist::JavascriptError + retry + end + end + end + end + + UNRESOLVABLE_CONFLICTS = { + 'conflict-too-large' => 'when the conflicts contain a large file', + 'conflict-binary-file' => 'when the conflicts contain a binary file', + 'conflict-contains-conflict-markers' => 'when the conflicts contain a file with ambiguous conflict markers', + 'conflict-missing-side' => 'when the conflicts contain a file edited in one branch and deleted in another' + } + + UNRESOLVABLE_CONFLICTS.each do |source_branch, description| + context description do + let(:merge_request) { create_merge_request(source_branch) } + + before do + project.team << [user, :developer] + login_as(user) + + visit namespace_project_merge_request_path(project.namespace, project, merge_request) + end + + it 'does not show a link to the conflict resolution page' do + expect(page).not_to have_link('conflicts', href: /\/conflicts\Z/) + end + + it 'shows an error if the conflicts page is visited directly' do + visit current_url + '/conflicts' + wait_for_ajax + + expect(find('#conflicts')).to have_content('Please try to resolve them locally.') + end + end + end +end diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb index 11c9de3c4bf..b63931d9d35 100644 --- a/spec/features/merge_requests/create_new_mr_spec.rb +++ b/spec/features/merge_requests/create_new_mr_spec.rb @@ -8,10 +8,11 @@ feature 'Create New Merge Request', feature: true, js: true do project.team << [user, :master] login_as user - visit namespace_project_merge_requests_path(project.namespace, project) end it 'generates a diff for an orphaned branch' do + visit namespace_project_merge_requests_path(project.namespace, project) + click_link 'New Merge Request' expect(page).to have_content('Source branch') expect(page).to have_content('Target branch') @@ -42,4 +43,20 @@ feature 'Create New Merge Request', feature: true, js: true do expect(page).not_to have_content private_project.to_reference end end + + it 'allows to change the diff view' do + visit new_namespace_project_merge_request_path(project.namespace, project, merge_request: { target_branch: 'master', source_branch: 'fix' }) + + click_link 'Changes' + + expect(page.find_link('Inline')[:class]).to match(/\bactive\b/) + expect(page.find_link('Side-by-side')[:class]).not_to match(/\bactive\b/) + + click_link 'Side-by-side' + + click_link 'Changes' + + expect(page.find_link('Inline')[:class]).not_to match(/\bactive\b/) + expect(page.find_link('Side-by-side')[:class]).to match(/\bactive\b/) + end end diff --git a/spec/features/merge_requests/pipelines_spec.rb b/spec/features/merge_requests/pipelines_spec.rb new file mode 100644 index 00000000000..9c4c0525267 --- /dev/null +++ b/spec/features/merge_requests/pipelines_spec.rb @@ -0,0 +1,48 @@ +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 } + + before do + project.team << [user, :master] + login_as user + end + + context 'with pipelines' do + let!(:pipeline) do + create(:ci_empty_pipeline, + project: merge_request.source_project, + ref: merge_request.source_branch, + sha: merge_request.diff_head_sha) + end + + before do + visit namespace_project_merge_request_path(project.namespace, project, merge_request) + end + + scenario 'user visits merge request pipelines tab' do + page.within('.merge-request-tabs') do + click_link('Pipelines') + end + wait_for_ajax + + expect(page).to have_selector('.pipeline-actions') + end + end + + context 'without pipelines' do + before do + visit namespace_project_merge_request_path(project.namespace, project, merge_request) + end + + scenario 'user visits merge request page' do + page.within('.merge-request-tabs') do + expect(page).to have_no_link('Pipelines') + end + end + end +end diff --git a/spec/features/projects/issues/list_spec.rb b/spec/features/projects/issues/list_spec.rb new file mode 100644 index 00000000000..3137af074ca --- /dev/null +++ b/spec/features/projects/issues/list_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +feature 'Issues List' do + let(:user) { create(:user) } + let(:project) { create(:empty_project) } + + background do + project.team << [user, :developer] + + login_as(user) + end + + scenario 'user does not see create new list button' do + create(:issue, project: project) + + visit namespace_project_issues_path(project.namespace, project) + + expect(page).not_to have_selector('.js-new-board-list') + end +end diff --git a/spec/features/projects/merge_requests/list_spec.rb b/spec/features/projects/merge_requests/list_spec.rb new file mode 100644 index 00000000000..5dd58ad66a7 --- /dev/null +++ b/spec/features/projects/merge_requests/list_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +feature 'Merge Requests List' do + let(:user) { create(:user) } + let(:project) { create(:project) } + + background do + project.team << [user, :developer] + + login_as(user) + end + + scenario 'user does not see create new list button' do + create(:merge_request, source_project: project) + + visit namespace_project_merge_requests_path(project.namespace, project) + + expect(page).not_to have_selector('.js-new-board-list') + end +end diff --git a/spec/features/projects/pipelines_spec.rb b/spec/features/projects/pipelines_spec.rb index 29d150bc597..47482bc3cc9 100644 --- a/spec/features/projects/pipelines_spec.rb +++ b/spec/features/projects/pipelines_spec.rb @@ -193,7 +193,11 @@ describe "Pipelines" do end context 'playing manual build' do - before { click_link('Play') } + before do + within '.pipeline-holder' do + click_link('Play') + end + end it { expect(@manual.reload).to be_pending } end |