summaryrefslogtreecommitdiff
path: root/spec/features
diff options
context:
space:
mode:
authorKamil Trzcinski <ayufan@ayufan.eu>2017-02-06 16:06:44 +0100
committerKamil Trzcinski <ayufan@ayufan.eu>2017-02-06 16:06:44 +0100
commita8825f0c7fb5da6a047813a491e6b8aebc33bb5b (patch)
tree4b676823f617ae696b11f606272c139d7007960b /spec/features
parent3cd17c9430c7575b0c1f1041947f3cd0d991f00c (diff)
parente438b30a315e092e03afa9d84f8a9e57ded3b0a2 (diff)
downloadgitlab-ce-a8825f0c7fb5da6a047813a491e6b8aebc33bb5b.tar.gz
Merge remote-tracking branch 'origin/master' into 24147-delete-env-button
Diffstat (limited to 'spec/features')
-rw-r--r--spec/features/admin/admin_builds_spec.rb34
-rw-r--r--spec/features/admin/admin_disables_git_access_protocol_spec.rb3
-rw-r--r--spec/features/admin/admin_health_check_spec.rb9
-rw-r--r--spec/features/admin/admin_runners_spec.rb3
-rw-r--r--spec/features/admin/admin_settings_spec.rb5
-rw-r--r--spec/features/admin/admin_uses_repository_checks_spec.rb9
-rw-r--r--spec/features/boards/add_issues_modal_spec.rb233
-rw-r--r--spec/features/boards/boards_spec.rb217
-rw-r--r--spec/features/boards/new_issue_spec.rb5
-rw-r--r--spec/features/boards/sidebar_spec.rb107
-rw-r--r--spec/features/copy_as_gfm_spec.rb432
-rw-r--r--spec/features/dashboard/shortcuts_spec.rb29
-rw-r--r--spec/features/environment_spec.rb4
-rw-r--r--spec/features/environments_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/dropdown_assignee_spec.rb34
-rw-r--r--spec/features/issues/filtered_search/dropdown_author_spec.rb18
-rw-r--r--spec/features/issues/filtered_search/dropdown_label_spec.rb27
-rw-r--r--spec/features/issues/filtered_search/dropdown_milestone_spec.rb17
-rw-r--r--spec/features/issues/filtered_search/filter_issues_spec.rb2
-rw-r--r--spec/features/issues/filtered_search/search_bar_spec.rb16
-rw-r--r--spec/features/issues/form_spec.rb16
-rw-r--r--spec/features/issues/gfm_autocomplete_spec.rb15
-rw-r--r--spec/features/issues/group_label_sidebar_spec.rb21
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb25
-rw-r--r--spec/features/issues/new_branch_button_spec.rb20
-rw-r--r--spec/features/login_spec.rb5
-rw-r--r--spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb4
-rw-r--r--spec/features/merge_requests/toggler_behavior_spec.rb28
-rw-r--r--spec/features/merge_requests/user_uses_slash_commands_spec.rb78
-rw-r--r--spec/features/merge_requests/widget_spec.rb34
-rw-r--r--spec/features/notes_on_merge_requests_spec.rb6
-rw-r--r--spec/features/projects/builds_spec.rb44
-rw-r--r--spec/features/projects/files/editing_a_file_spec.rb2
-rw-r--r--spec/features/projects/files/project_owner_creates_license_file_spec.rb3
-rw-r--r--spec/features/projects/import_export/export_file_spec.rb3
-rw-r--r--spec/features/projects/import_export/test_project_export.tar.gzbin682154 -> 681799 bytes
-rw-r--r--spec/features/projects/issuable_templates_spec.rb40
-rw-r--r--spec/features/projects/labels/update_prioritization_spec.rb8
-rw-r--r--spec/features/projects/merge_request_button_spec.rb108
-rw-r--r--spec/features/projects/new_project_spec.rb20
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb60
-rw-r--r--spec/features/projects/project_settings_spec.rb4
-rw-r--r--spec/features/projects/ref_switcher_spec.rb5
-rw-r--r--spec/features/projects/services/mattermost_slash_command_spec.rb9
-rw-r--r--spec/features/projects/settings/merge_requests_settings_spec.rb18
-rw-r--r--spec/features/task_lists_spec.rb44
-rw-r--r--spec/features/todos/todos_spec.rb2
47 files changed, 1517 insertions, 311 deletions
diff --git a/spec/features/admin/admin_builds_spec.rb b/spec/features/admin/admin_builds_spec.rb
index e177059d959..9d5ce876c29 100644
--- a/spec/features/admin/admin_builds_spec.rb
+++ b/spec/features/admin/admin_builds_spec.rb
@@ -9,8 +9,8 @@ describe 'Admin Builds' do
let(:pipeline) { create(:ci_pipeline) }
context 'All tab' do
- context 'when have builds' do
- it 'shows all builds' do
+ context 'when have jobs' do
+ it 'shows all jobs' do
create(:ci_build, pipeline: pipeline, status: :pending)
create(:ci_build, pipeline: pipeline, status: :running)
create(:ci_build, pipeline: pipeline, status: :success)
@@ -19,26 +19,26 @@ describe 'Admin Builds' do
visit admin_builds_path
expect(page).to have_selector('.nav-links li.active', text: 'All')
- expect(page).to have_selector('.row-content-block', text: 'All builds')
+ expect(page).to have_selector('.row-content-block', text: 'All jobs')
expect(page.all('.build-link').size).to eq(4)
expect(page).to have_link 'Cancel all'
end
end
- context 'when have no builds' do
+ context 'when have no jobs' do
it 'shows a message' do
visit admin_builds_path
expect(page).to have_selector('.nav-links li.active', text: 'All')
- expect(page).to have_content 'No builds to show'
+ expect(page).to have_content 'No jobs to show'
expect(page).not_to have_link 'Cancel all'
end
end
end
context 'Pending tab' do
- context 'when have pending builds' do
- it 'shows pending builds' do
+ context 'when have pending jobs' do
+ it 'shows pending jobs' do
build1 = create(:ci_build, pipeline: pipeline, status: :pending)
build2 = create(:ci_build, pipeline: pipeline, status: :running)
build3 = create(:ci_build, pipeline: pipeline, status: :success)
@@ -55,22 +55,22 @@ describe 'Admin Builds' do
end
end
- context 'when have no builds pending' do
+ context 'when have no jobs pending' do
it 'shows a message' do
create(:ci_build, pipeline: pipeline, status: :success)
visit admin_builds_path(scope: :pending)
expect(page).to have_selector('.nav-links li.active', text: 'Pending')
- expect(page).to have_content 'No builds to show'
+ expect(page).to have_content 'No jobs to show'
expect(page).not_to have_link 'Cancel all'
end
end
end
context 'Running tab' do
- context 'when have running builds' do
- it 'shows running builds' do
+ context 'when have running jobs' do
+ it 'shows running jobs' do
build1 = create(:ci_build, pipeline: pipeline, status: :running)
build2 = create(:ci_build, pipeline: pipeline, status: :success)
build3 = create(:ci_build, pipeline: pipeline, status: :failed)
@@ -87,22 +87,22 @@ describe 'Admin Builds' do
end
end
- context 'when have no builds running' do
+ context 'when have no jobs running' do
it 'shows a message' do
create(:ci_build, pipeline: pipeline, status: :success)
visit admin_builds_path(scope: :running)
expect(page).to have_selector('.nav-links li.active', text: 'Running')
- expect(page).to have_content 'No builds to show'
+ expect(page).to have_content 'No jobs to show'
expect(page).not_to have_link 'Cancel all'
end
end
end
context 'Finished tab' do
- context 'when have finished builds' do
- it 'shows finished builds' do
+ context 'when have finished jobs' do
+ it 'shows finished jobs' do
build1 = create(:ci_build, pipeline: pipeline, status: :pending)
build2 = create(:ci_build, pipeline: pipeline, status: :running)
build3 = create(:ci_build, pipeline: pipeline, status: :success)
@@ -117,14 +117,14 @@ describe 'Admin Builds' do
end
end
- context 'when have no builds finished' do
+ context 'when have no jobs finished' do
it 'shows a message' do
create(:ci_build, pipeline: pipeline, status: :running)
visit admin_builds_path(scope: :finished)
expect(page).to have_selector('.nav-links li.active', text: 'Finished')
- expect(page).to have_content 'No builds to show'
+ expect(page).to have_content 'No jobs to show'
expect(page).to have_link 'Cancel all'
end
end
diff --git a/spec/features/admin/admin_disables_git_access_protocol_spec.rb b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
index 66044b44495..e8e080ce3e2 100644
--- a/spec/features/admin/admin_disables_git_access_protocol_spec.rb
+++ b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
@@ -1,10 +1,13 @@
require 'rails_helper'
feature 'Admin disables Git access protocol', feature: true do
+ include StubENV
+
let(:project) { create(:empty_project, :empty_repo) }
let(:admin) { create(:admin) }
background do
+ stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
login_as(admin)
end
diff --git a/spec/features/admin/admin_health_check_spec.rb b/spec/features/admin/admin_health_check_spec.rb
index dec2dedf2b5..f7e49a56deb 100644
--- a/spec/features/admin/admin_health_check_spec.rb
+++ b/spec/features/admin/admin_health_check_spec.rb
@@ -1,9 +1,11 @@
require 'spec_helper'
feature "Admin Health Check", feature: true do
+ include StubENV
include WaitForAjax
before do
+ stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
login_as :admin
end
@@ -12,11 +14,12 @@ feature "Admin Health Check", feature: true do
visit admin_health_check_path
end
- it { page.has_text? 'Health Check' }
- it { page.has_text? 'Health information can be retrieved' }
-
it 'has a health check access token' do
+ page.has_text? 'Health Check'
+ page.has_text? 'Health information can be retrieved'
+
token = current_application_settings.health_check_access_token
+
expect(page).to have_content("Access token is #{token}")
expect(page).to have_selector('#health-check-token', text: token)
end
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index d92c66b689d..f05fbe3d062 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -1,7 +1,10 @@
require 'spec_helper'
describe "Admin Runners" do
+ include StubENV
+
before do
+ stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
login_as :admin
end
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 47fa2f14307..de42ab81fac 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -1,7 +1,10 @@
require 'spec_helper'
feature 'Admin updates settings', feature: true do
- before(:each) do
+ include StubENV
+
+ before do
+ stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
login_as :admin
visit admin_application_settings_path
end
diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb
index 661fb761809..855247de2ea 100644
--- a/spec/features/admin/admin_uses_repository_checks_spec.rb
+++ b/spec/features/admin/admin_uses_repository_checks_spec.rb
@@ -1,7 +1,12 @@
require 'rails_helper'
feature 'Admin uses repository checks', feature: true do
- before { login_as :admin }
+ include StubENV
+
+ before do
+ stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
+ login_as :admin
+ end
scenario 'to trigger a single check' do
project = create(:empty_project)
@@ -29,7 +34,7 @@ feature 'Admin uses repository checks', feature: true do
scenario 'to clear all repository checks', js: true do
visit admin_application_settings_path
-
+
expect(RepositoryCheck::ClearWorker).to receive(:perform_async)
click_link 'Clear all repository checks'
diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb
new file mode 100644
index 00000000000..2875fc1e533
--- /dev/null
+++ b/spec/features/boards/add_issues_modal_spec.rb
@@ -0,0 +1,233 @@
+require 'rails_helper'
+
+describe 'Issue Boards add issue modal', :feature, :js do
+ include WaitForAjax
+ include WaitForVueResource
+
+ let(:project) { create(:empty_project, :public) }
+ let(:board) { create(:board, project: project) }
+ let(:user) { create(:user) }
+ let!(:planning) { create(:label, project: project, name: 'Planning') }
+ let!(:label) { create(:label, project: project) }
+ let!(:list1) { create(:list, board: board, label: planning, position: 0) }
+ let!(:list2) { create(:list, board: board, label: label, position: 1) }
+ let!(:issue) { create(:issue, project: project) }
+ let!(:issue2) { create(:issue, project: project) }
+
+ before do
+ project.team << [user, :master]
+
+ login_as(user)
+
+ visit namespace_project_board_path(project.namespace, project, board)
+ wait_for_vue_resource
+ end
+
+ context 'modal interaction' do
+ it 'opens modal' do
+ click_button('Add issues')
+
+ expect(page).to have_selector('.add-issues-modal')
+ end
+
+ it 'closes modal' do
+ click_button('Add issues')
+
+ page.within('.add-issues-modal') do
+ find('.close').click
+ end
+
+ expect(page).not_to have_selector('.add-issues-modal')
+ end
+
+ it 'closes modal if cancel button clicked' do
+ click_button('Add issues')
+
+ page.within('.add-issues-modal') do
+ click_button 'Cancel'
+ end
+
+ expect(page).not_to have_selector('.add-issues-modal')
+ end
+ end
+
+ context 'issues list' do
+ before do
+ click_button('Add issues')
+
+ wait_for_vue_resource
+ end
+
+ it 'loads issues' do
+ page.within('.add-issues-modal') do
+ page.within('.nav-links') do
+ expect(page).to have_content('2')
+ end
+
+ expect(page).to have_selector('.card', count: 2)
+ end
+ end
+
+ it 'shows selected issues' do
+ page.within('.add-issues-modal') do
+ click_link 'Selected issues'
+
+ expect(page).not_to have_selector('.card')
+ end
+ end
+
+ context 'list dropdown' do
+ it 'resets after deleting list' do
+ page.within('.add-issues-modal') do
+ expect(find('.add-issues-footer')).to have_button(planning.title)
+
+ click_button 'Cancel'
+ end
+
+ first('.board-delete').click
+
+ click_button('Add issues')
+
+ wait_for_vue_resource
+
+ page.within('.add-issues-modal') do
+ expect(find('.add-issues-footer')).not_to have_button(planning.title)
+ expect(find('.add-issues-footer')).to have_button(label.title)
+ end
+ end
+ end
+
+ context 'search' do
+ it 'returns issues' do
+ page.within('.add-issues-modal') do
+ find('.form-control').native.send_keys(issue.title)
+
+ expect(page).to have_selector('.card', count: 1)
+ end
+ end
+
+ it 'returns no issues' do
+ page.within('.add-issues-modal') do
+ find('.form-control').native.send_keys('testing search')
+
+ expect(page).not_to have_selector('.card')
+ expect(page).not_to have_content("You haven't added any issues to your project yet")
+ end
+ end
+ end
+
+ context 'selecing issues' do
+ it 'selects single issue' do
+ page.within('.add-issues-modal') do
+ first('.card').click
+
+ page.within('.nav-links') do
+ expect(page).to have_content('Selected issues 1')
+ end
+ end
+ end
+
+ it 'changes button text' do
+ page.within('.add-issues-modal') do
+ first('.card').click
+
+ expect(first('.add-issues-footer .btn')).to have_content('Add 1 issue')
+ end
+ end
+
+ it 'changes button text with plural' do
+ page.within('.add-issues-modal') do
+ all('.card').each do |el|
+ el.click
+ end
+
+ expect(first('.add-issues-footer .btn')).to have_content('Add 2 issues')
+ end
+ end
+
+ it 'shows only selected issues on selected tab' do
+ page.within('.add-issues-modal') do
+ first('.card').click
+
+ click_link 'Selected issues'
+
+ expect(page).to have_selector('.card', count: 1)
+ end
+ end
+
+ it 'selects all issues' do
+ page.within('.add-issues-modal') do
+ click_button 'Select all'
+
+ expect(page).to have_selector('.is-active', count: 2)
+ end
+ end
+
+ it 'deselects all issues' do
+ page.within('.add-issues-modal') do
+ click_button 'Select all'
+
+ expect(page).to have_selector('.is-active', count: 2)
+
+ click_button 'Deselect all'
+
+ expect(page).not_to have_selector('.is-active')
+ end
+ end
+
+ it 'selects all that arent already selected' do
+ page.within('.add-issues-modal') do
+ first('.card').click
+
+ expect(page).to have_selector('.is-active', count: 1)
+
+ click_button 'Select all'
+
+ expect(page).to have_selector('.is-active', count: 2)
+ end
+ end
+
+ it 'unselects from selected tab' do
+ page.within('.add-issues-modal') do
+ first('.card').click
+
+ click_link 'Selected issues'
+
+ first('.card').click
+
+ expect(page).not_to have_selector('.is-active')
+ end
+ end
+ end
+
+ context 'adding issues' do
+ it 'adds to board' do
+ page.within('.add-issues-modal') do
+ first('.card').click
+
+ click_button 'Add 1 issue'
+ end
+
+ page.within(first('.board')) do
+ expect(page).to have_selector('.card')
+ end
+ end
+
+ it 'adds to second list' do
+ page.within('.add-issues-modal') do
+ first('.card').click
+
+ click_button planning.title
+
+ click_link label.title
+
+ click_button 'Add 1 issue'
+ end
+
+ page.within(find('.board:nth-child(2)')) do
+ expect(page).to have_selector('.card')
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index bfac5a1b8ab..34f47daf0e5 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -20,7 +20,7 @@ describe 'Issue Boards', feature: true, js: true do
before do
visit namespace_project_board_path(project.namespace, project, board)
wait_for_vue_resource
- expect(page).to have_selector('.board', count: 3)
+ expect(page).to have_selector('.board', count: 2)
end
it 'shows blank state' do
@@ -31,18 +31,18 @@ describe 'Issue Boards', feature: true, js: true 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)
+ expect(page).to have_selector('.board', count: 1)
end
it 'creates default lists' do
- lists = ['Backlog', 'To Do', 'Doing', 'Done']
+ lists = ['To Do', 'Doing', '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: 4)
+ expect(page).to have_selector('.board', count: 3)
page.all('.board').each_with_index do |list, i|
expect(list.find('.board-title')).to have_content(lists[i])
@@ -64,42 +64,41 @@ describe 'Issue Boards', feature: true, js: true do
let!(:list1) { create(:list, board: board, label: planning, position: 0) }
let!(:list2) { create(:list, board: 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!(:confidential_issue) { create(:labeled_issue, :confidential, project: project, author: user, labels: [planning]) }
+ let!(:issue1) { create(:labeled_issue, project: project, assignee: user, labels: [planning]) }
+ let!(:issue2) { create(:labeled_issue, project: project, author: user2, labels: [planning]) }
+ let!(:issue3) { create(:labeled_issue, project: project, labels: [planning]) }
+ let!(:issue4) { create(:labeled_issue, project: project, labels: [planning]) }
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, accepting]) }
+ let!(:issue9) { create(:labeled_issue, project: project, labels: [planning, testing, bug, accepting]) }
before do
visit namespace_project_board_path(project.namespace, project, board)
wait_for_vue_resource
- expect(page).to have_selector('.board', count: 4)
+ expect(page).to have_selector('.board', count: 3)
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)
+ expect(page).to have_selector('.board', count: 3)
end
it 'shows description tooltip on list title' do
- page.within('.board:nth-child(2)') do
+ page.within('.board:nth-child(1)') do
expect(find('.board-title span.has-tooltip')[:title]).to eq('Test')
end
end
it 'shows issues in lists' do
+ wait_for_board_cards(1, 8)
wait_for_board_cards(2, 2)
- wait_for_board_cards(3, 2)
end
it 'shows confidential issues with icon' do
@@ -108,19 +107,6 @@ describe 'Issue Boards', feature: true, js: true do
end
end
- it 'search backlog list' do
- page.within('#js-boards-search') do
- find('.form-control').set(issue1.title)
- end
-
- wait_for_vue_resource
-
- expect(find('.board:nth-child(1)')).to have_selector('.card', count: 1)
- expect(find('.board:nth-child(2)')).to have_selector('.card', count: 0)
- expect(find('.board:nth-child(3)')).to have_selector('.card', count: 0)
- expect(find('.board:nth-child(4)')).to have_selector('.card', count: 0)
- end
-
it 'search done list' do
page.within('#js-boards-search') do
find('.form-control').set(issue8.title)
@@ -130,8 +116,7 @@ describe 'Issue Boards', feature: true, js: true do
expect(find('.board:nth-child(1)')).to have_selector('.card', count: 0)
expect(find('.board:nth-child(2)')).to have_selector('.card', count: 0)
- expect(find('.board:nth-child(3)')).to have_selector('.card', count: 0)
- expect(find('.board:nth-child(4)')).to have_selector('.card', count: 1)
+ expect(find('.board:nth-child(3)')).to have_selector('.card', count: 1)
end
it 'search list' do
@@ -141,157 +126,135 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_vue_resource
- expect(find('.board:nth-child(1)')).to have_selector('.card', count: 0)
- expect(find('.board:nth-child(2)')).to have_selector('.card', count: 1)
+ expect(find('.board:nth-child(1)')).to have_selector('.card', count: 1)
+ expect(find('.board:nth-child(2)')).to have_selector('.card', count: 0)
expect(find('.board:nth-child(3)')).to have_selector('.card', count: 0)
- expect(find('.board:nth-child(4)')).to have_selector('.card', count: 0)
end
it 'allows user to delete board' do
- page.within(find('.board:nth-child(2)')) do
+ page.within(find('.board:nth-child(1)')) do
find('.board-delete').click
end
wait_for_vue_resource
- expect(page).to have_selector('.board', count: 3)
+ expect(page).to have_selector('.board', count: 2)
end
it 'removes checkmark in new list dropdown after deleting' do
click_button 'Add list'
wait_for_ajax
- page.within(find('.board:nth-child(2)')) do
+ page.within(find('.board:nth-child(1)')) 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')
+ expect(page).to have_selector('.board', count: 2)
end
it 'infinite scrolls list' do
50.times do
- create(:issue, project: project)
+ create(:labeled_issue, project: project, labels: [planning])
end
visit namespace_project_board_path(project.namespace, project, board)
wait_for_vue_resource
page.within(find('.board', match: :first)) do
- expect(page.find('.board-header')).to have_content('56')
+ expect(page.find('.board-header')).to have_content('58')
expect(page).to have_selector('.card', count: 20)
- expect(page).to have_content('Showing 20 of 56 issues')
+ expect(page).to have_content('Showing 20 of 58 issues')
evaluate_script("document.querySelectorAll('.board .board-list')[0].scrollTop = document.querySelectorAll('.board .board-list')[0].scrollHeight")
wait_for_vue_resource
expect(page).to have_selector('.card', count: 40)
- expect(page).to have_content('Showing 40 of 56 issues')
+ expect(page).to have_content('Showing 40 of 58 issues')
evaluate_script("document.querySelectorAll('.board .board-list')[0].scrollTop = document.querySelectorAll('.board .board-list')[0].scrollHeight")
wait_for_vue_resource
- expect(page).to have_selector('.card', count: 56)
+ expect(page).to have_selector('.card', count: 58)
expect(page).to have_content('Showing all issues')
end
end
- context 'backlog' do
- it 'shows issues in backlog with no labels' do
- wait_for_board_cards(1, 6)
- end
-
- it 'moves issue from backlog into list' do
- drag_to(list_to_index: 1)
-
- wait_for_vue_resource
- wait_for_board_cards(1, 5)
- wait_for_board_cards(2, 3)
- end
- end
-
context 'done' do
it 'shows list of done issues' do
- wait_for_board_cards(4, 1)
+ wait_for_board_cards(3, 1)
wait_for_ajax
end
it 'moves issue to done' do
- drag_to(list_from_index: 0, list_to_index: 3)
+ drag_to(list_from_index: 0, list_to_index: 2)
- wait_for_board_cards(1, 5)
+ wait_for_board_cards(1, 7)
wait_for_board_cards(2, 2)
wait_for_board_cards(3, 2)
- wait_for_board_cards(4, 2)
expect(find('.board:nth-child(1)')).not_to have_content(issue9.title)
- 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)
+ expect(find('.board:nth-child(3)')).to have_selector('.card', count: 2)
+ expect(find('.board:nth-child(3)')).to have_content(issue9.title)
+ expect(find('.board:nth-child(3)')).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)
+ drag_to(list_from_index: 0, list_to_index: 2)
- wait_for_board_cards(1, 6)
- wait_for_board_cards(2, 1)
- wait_for_board_cards(3, 1)
- wait_for_board_cards(4, 2)
+ wait_for_board_cards(1, 7)
+ wait_for_board_cards(2, 2)
+ wait_for_board_cards(3, 2)
- expect(find('.board:nth-child(2)')).not_to have_content(issue6.title)
- expect(find('.board:nth-child(4)')).to have_content(issue6.title)
- expect(find('.board:nth-child(4)')).not_to have_content(planning.title)
+ expect(find('.board:nth-child(1)')).not_to have_content(issue9.title)
+ expect(find('.board:nth-child(3)')).to have_content(issue9.title)
+ expect(find('.board:nth-child(3)')).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')
+ drag_to(list_from_index: 1, list_to_index: 0, selector: '.board-header')
- wait_for_board_cards(1, 6)
- wait_for_board_cards(2, 2)
- wait_for_board_cards(3, 2)
- wait_for_board_cards(4, 1)
+ wait_for_board_cards(1, 2)
+ wait_for_board_cards(2, 8)
+ wait_for_board_cards(3, 1)
- expect(find('.board:nth-child(2)')).to have_content(development.title)
- expect(find('.board:nth-child(2)')).to have_content(planning.title)
+ expect(find('.board:nth-child(1)')).to have_content(development.title)
+ expect(find('.board:nth-child(1)')).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)
+ drag_to(list_from_index: 0, card_index: 1, list_to_index: 1)
- wait_for_board_cards(1, 6)
- wait_for_board_cards(2, 1)
- wait_for_board_cards(3, 3)
- wait_for_board_cards(4, 1)
+ wait_for_board_cards(1, 7)
+ wait_for_board_cards(2, 2)
+ wait_for_board_cards(3, 1)
- 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)
+ expect(find('.board:nth-child(2)')).to have_content(issue6.title)
+ expect(find('.board:nth-child(2)').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)
+ drag_to(list_from_index: 1, list_to_index: 0)
- wait_for_board_cards(1, 6)
- wait_for_board_cards(2, 3)
+ wait_for_board_cards(1, 9)
+ wait_for_board_cards(2, 1)
wait_for_board_cards(3, 1)
- wait_for_board_cards(4, 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)
+ expect(find('.board:nth-child(1)')).to have_content(issue7.title)
+ expect(find('.board:nth-child(1)').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)
+ drag_to(list_from_index: 2, list_to_index: 1)
expect(find('.board:nth-child(2)')).to have_content(issue8.title)
- wait_for_board_cards(1, 6)
+ wait_for_board_cards(1, 8)
wait_for_board_cards(2, 3)
- wait_for_board_cards(3, 2)
- wait_for_board_cards(4, 0)
+ wait_for_board_cards(3, 0)
end
context 'issue card' do
@@ -324,7 +287,7 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_vue_resource
- expect(page).to have_selector('.board', count: 5)
+ expect(page).to have_selector('.board', count: 4)
end
it 'creates new list for Backlog label' do
@@ -337,7 +300,7 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_vue_resource
- expect(page).to have_selector('.board', count: 5)
+ expect(page).to have_selector('.board', count: 4)
end
it 'creates new list for Done label' do
@@ -350,7 +313,7 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_vue_resource
- expect(page).to have_selector('.board', count: 5)
+ expect(page).to have_selector('.board', count: 4)
end
it 'keeps dropdown open after adding new list' do
@@ -366,21 +329,6 @@ describe 'Issue Boards', feature: true, js: true do
expect(find('.issue-boards-search')).to have_selector('.open')
end
- it 'moves issues from backlog into new list' do
- wait_for_board_cards(1, 6)
-
- click_button 'Add list'
- wait_for_ajax
-
- page.within('.dropdown-menu-issues-board-new') do
- click_link testing.title
- end
-
- wait_for_vue_resource
-
- wait_for_board_cards(1, 5)
- end
-
it 'creates new list from a new label' do
click_button 'Add list'
@@ -397,7 +345,7 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_ajax
wait_for_vue_resource
- expect(page).to have_selector('.board', count: 5)
+ expect(page).to have_selector('.board', count: 4)
end
end
end
@@ -418,7 +366,7 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_vue_resource
wait_for_board_cards(1, 1)
- wait_for_empty_boards((2..4))
+ wait_for_empty_boards((2..3))
end
it 'filters by assignee' do
@@ -437,7 +385,7 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_vue_resource
wait_for_board_cards(1, 1)
- wait_for_empty_boards((2..4))
+ wait_for_empty_boards((2..3))
end
it 'filters by milestone' do
@@ -454,10 +402,9 @@ describe 'Issue Boards', feature: true, js: true do
end
wait_for_vue_resource
- wait_for_board_cards(1, 0)
- wait_for_board_cards(2, 1)
+ wait_for_board_cards(1, 1)
+ wait_for_board_cards(2, 0)
wait_for_board_cards(3, 0)
- wait_for_board_cards(4, 0)
end
it 'filters by label' do
@@ -474,7 +421,7 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_vue_resource
wait_for_board_cards(1, 1)
- wait_for_empty_boards((2..4))
+ wait_for_empty_boards((2..3))
end
it 'filters by label with space after reload' do
@@ -530,7 +477,7 @@ describe 'Issue Boards', feature: true, js: true do
it 'infinite scrolls list with label filter' do
50.times do
- create(:labeled_issue, project: project, labels: [testing])
+ create(:labeled_issue, project: project, labels: [planning, testing])
end
page.within '.issues-filters' do
@@ -580,32 +527,12 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_vue_resource
wait_for_board_cards(1, 1)
- wait_for_empty_boards((2..4))
- end
-
- it 'filters by no label' do
- page.within '.issues-filters' do
- click_button('Label')
- wait_for_ajax
-
- page.within '.dropdown-menu-labels' do
- click_link("No Label")
- wait_for_vue_resource
- find('.dropdown-menu-close').click
- end
- end
-
- wait_for_vue_resource
-
- wait_for_board_cards(1, 5)
- wait_for_board_cards(2, 0)
- wait_for_board_cards(3, 0)
- wait_for_board_cards(4, 1)
+ wait_for_empty_boards((2..3))
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)
+ expect(page).to have_selector('.card', count: 8)
expect(find('.card', match: :first)).to have_content(bug.title)
click_button(bug.title)
wait_for_vue_resource
@@ -614,7 +541,7 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_vue_resource
wait_for_board_cards(1, 1)
- wait_for_empty_boards((2..4))
+ wait_for_empty_boards((2..3))
page.within('.labels-filter') do
expect(find('.dropdown-toggle-text')).to have_content(bug.title)
diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb
index a03cd6fbf2d..6d14a8cf483 100644
--- a/spec/features/boards/new_issue_spec.rb
+++ b/spec/features/boards/new_issue_spec.rb
@@ -6,6 +6,7 @@ describe 'Issue Boards new issue', feature: true, js: true do
let(:project) { create(:empty_project, :public) }
let(:board) { create(:board, project: project) }
+ let!(:list) { create(:list, board: board, position: 0) }
let(:user) { create(:user) }
context 'authorized user' do
@@ -17,7 +18,7 @@ describe 'Issue Boards new issue', feature: true, js: true do
visit namespace_project_board_path(project.namespace, project, board)
wait_for_vue_resource
- expect(page).to have_selector('.board', count: 3)
+ expect(page).to have_selector('.board', count: 2)
end
it 'displays new issue button' do
@@ -25,7 +26,7 @@ describe 'Issue Boards new issue', feature: true, js: true do
end
it 'does not display new issue button in done list' do
- page.within('.board:nth-child(3)') do
+ page.within('.board:nth-child(2)') do
expect(page).not_to have_selector('.board-issue-count-holder .btn')
end
end
diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb
index 188d33e8ef4..9cc50167395 100644
--- a/spec/features/boards/sidebar_spec.rb
+++ b/spec/features/boards/sidebar_spec.rb
@@ -4,14 +4,17 @@ describe 'Issue Boards', feature: true, js: true do
include WaitForAjax
include WaitForVueResource
- let(:project) { create(:empty_project, :public) }
- let(:board) { create(:board, project: project) }
- let(:user) { create(:user) }
- let!(:label) { create(:label, project: project) }
- let!(:label2) { create(:label, project: project) }
- let!(:milestone) { create(:milestone, project: project) }
- let!(:issue2) { create(:labeled_issue, project: project, assignee: user, milestone: milestone, labels: [label]) }
- let!(:issue) { create(:issue, project: project) }
+ let(:user) { create(:user) }
+ let(:project) { create(:empty_project, :public) }
+ let!(:milestone) { create(:milestone, project: project) }
+ let!(:development) { create(:label, project: project, name: 'Development') }
+ let!(:bug) { create(:label, project: project, name: 'Bug') }
+ let!(:regression) { create(:label, project: project, name: 'Regression') }
+ let!(:stretch) { create(:label, project: project, name: 'Stretch') }
+ let!(:issue1) { create(:labeled_issue, project: project, assignee: user, milestone: milestone, labels: [development]) }
+ let!(:issue2) { create(:labeled_issue, project: project, labels: [development, stretch]) }
+ let(:board) { create(:board, project: project) }
+ let!(:list) { create(:list, board: board, label: development, position: 0) }
before do
project.team << [user, :master]
@@ -62,8 +65,22 @@ describe 'Issue Boards', feature: true, js: true do
end
page.within('.issue-boards-sidebar') do
- expect(page).to have_content(issue.title)
- expect(page).to have_content(issue.to_reference)
+ expect(page).to have_content(issue2.title)
+ expect(page).to have_content(issue2.to_reference)
+ end
+ end
+
+ it 'removes card from board when clicking remove button' do
+ page.within(first('.board')) do
+ first('.card').click
+ end
+
+ page.within('.issue-boards-sidebar') do
+ click_button 'Remove from board'
+ end
+
+ page.within(first('.board')) do
+ expect(page).to have_selector('.card', count: 1)
end
end
@@ -141,6 +158,36 @@ describe 'Issue Boards', feature: true, js: true do
end
end
end
+
+ it 'resets assignee dropdown' do
+ page.within(first('.board')) do
+ first('.card').click
+ end
+
+ page.within('.assignee') do
+ click_link 'Edit'
+
+ wait_for_ajax
+
+ page.within('.dropdown-menu-user') do
+ click_link user.name
+
+ wait_for_vue_resource
+ end
+
+ expect(page).to have_content(user.name)
+ end
+
+ page.within(first('.board')) do
+ find('.card:nth-child(2)').click
+ end
+
+ page.within('.assignee') do
+ click_link 'Edit'
+
+ expect(page).not_to have_selector('.is-active')
+ end
+ end
end
context 'milestone' do
@@ -214,22 +261,22 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_ajax
- click_link label.title
+ click_link bug.title
wait_for_vue_resource
find('.dropdown-menu-close-icon').click
page.within('.value') do
- expect(page).to have_selector('.label', count: 1)
- expect(page).to have_content(label.title)
+ expect(page).to have_selector('.label', count: 3)
+ expect(page).to have_content(bug.title)
end
end
page.within(first('.board')) do
page.within(first('.card')) do
- expect(page).to have_selector('.label', count: 1)
- expect(page).to have_content(label.title)
+ expect(page).to have_selector('.label', count: 2)
+ expect(page).to have_content(bug.title)
end
end
end
@@ -244,32 +291,32 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_ajax
- click_link label.title
- click_link label2.title
+ click_link bug.title
+ click_link regression.title
wait_for_vue_resource
find('.dropdown-menu-close-icon').click
page.within('.value') do
- expect(page).to have_selector('.label', count: 2)
- expect(page).to have_content(label.title)
- expect(page).to have_content(label2.title)
+ expect(page).to have_selector('.label', count: 4)
+ expect(page).to have_content(bug.title)
+ expect(page).to have_content(regression.title)
end
end
page.within(first('.board')) do
page.within(first('.card')) do
- expect(page).to have_selector('.label', count: 2)
- expect(page).to have_content(label.title)
- expect(page).to have_content(label2.title)
+ expect(page).to have_selector('.label', count: 3)
+ expect(page).to have_content(bug.title)
+ expect(page).to have_content(regression.title)
end
end
end
it 'removes a label' do
page.within(first('.board')) do
- find('.card:nth-child(2)').click
+ first('.card').click
end
page.within('.labels') do
@@ -277,22 +324,22 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_ajax
- click_link label.title
+ click_link stretch.title
wait_for_vue_resource
find('.dropdown-menu-close-icon').click
page.within('.value') do
- expect(page).to have_selector('.label', count: 0)
- expect(page).not_to have_content(label.title)
+ expect(page).to have_selector('.label', count: 1)
+ expect(page).not_to have_content(stretch.title)
end
end
page.within(first('.board')) do
- page.within(find('.card:nth-child(2)')) do
- expect(page).not_to have_selector('.label', count: 1)
- expect(page).not_to have_content(label.title)
+ page.within(first('.card')) do
+ expect(page).not_to have_selector('.label')
+ expect(page).not_to have_content(stretch.title)
end
end
end
diff --git a/spec/features/copy_as_gfm_spec.rb b/spec/features/copy_as_gfm_spec.rb
new file mode 100644
index 00000000000..f3a5b565122
--- /dev/null
+++ b/spec/features/copy_as_gfm_spec.rb
@@ -0,0 +1,432 @@
+require 'spec_helper'
+
+describe 'Copy as GFM', feature: true, js: true do
+ include GitlabMarkdownHelper
+ include ActionView::Helpers::JavaScriptHelper
+
+ before do
+ @feat = MarkdownFeature.new
+
+ # `markdown` helper expects a `@project` variable
+ @project = @feat.project
+
+ visit namespace_project_issue_path(@project.namespace, @project, @feat.issue)
+ end
+
+ # The filters referenced in lib/banzai/pipeline/gfm_pipeline.rb convert GitLab Flavored Markdown (GFM) to HTML.
+ # The handlers defined in app/assets/javascripts/copy_as_gfm.js.es6 consequently convert that same HTML to GFM.
+ # To make sure these filters and handlers are properly aligned, this spec tests the GFM-to-HTML-to-GFM cycle
+ # by verifying (`html_to_gfm(gfm_to_html(gfm)) == gfm`) for a number of examples of GFM for every filter, using the `verify` helper.
+
+ # These are all in a single `it` for performance reasons.
+ it 'works', :aggregate_failures do
+ verify(
+ 'nesting',
+
+ '> 1. [x] **[$`2 + 2`$ {-=-}{+=+} 2^2 ~~:thumbsup:~~](http://google.com)**'
+ )
+
+ verify(
+ 'a real world example from the gitlab-ce README',
+
+ <<-GFM.strip_heredoc
+ # GitLab
+
+ [![Build status](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/build.svg)](https://gitlab.com/gitlab-org/gitlab-ce/commits/master)
+ [![CE coverage report](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/coverage.svg?job=coverage)](https://gitlab-org.gitlab.io/gitlab-ce/coverage-ruby)
+ [![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.svg)](https://codeclimate.com/github/gitlabhq/gitlabhq)
+ [![Core Infrastructure Initiative Best Practices](https://bestpractices.coreinfrastructure.org/projects/42/badge)](https://bestpractices.coreinfrastructure.org/projects/42)
+
+ ## Canonical source
+
+ The canonical source of GitLab Community Edition is [hosted on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/).
+
+ ## Open source software to collaborate on code
+
+ To see how GitLab looks please see the [features page on our website](https://about.gitlab.com/features/).
+
+
+ - Manage Git repositories with fine grained access controls that keep your code secure
+
+ - Perform code reviews and enhance collaboration with merge requests
+
+ - Complete continuous integration (CI) and CD pipelines to builds, test, and deploy your applications
+
+ - Each project can also have an issue tracker, issue board, and a wiki
+
+ - Used by more than 100,000 organizations, GitLab is the most popular solution to manage Git repositories on-premises
+
+ - Completely free and open source (MIT Expat license)
+ GFM
+ )
+
+ verify(
+ 'InlineDiffFilter',
+
+ '{-Deleted text-}',
+ '{+Added text+}'
+ )
+
+ verify(
+ 'TaskListFilter',
+
+ '- [ ] Unchecked task',
+ '- [x] Checked task',
+ '1. [ ] Unchecked numbered task',
+ '1. [x] Checked numbered task'
+ )
+
+ verify(
+ 'ReferenceFilter',
+
+ # issue reference
+ @feat.issue.to_reference,
+ # full issue reference
+ @feat.issue.to_reference(full: true),
+ # issue URL
+ namespace_project_issue_url(@project.namespace, @project, @feat.issue),
+ # issue URL with note anchor
+ namespace_project_issue_url(@project.namespace, @project, @feat.issue, anchor: 'note_123'),
+ # issue link
+ "[Issue](#{namespace_project_issue_url(@project.namespace, @project, @feat.issue)})",
+ # issue link with note anchor
+ "[Issue](#{namespace_project_issue_url(@project.namespace, @project, @feat.issue, anchor: 'note_123')})",
+ )
+
+ verify(
+ 'AutolinkFilter',
+
+ 'https://example.com'
+ )
+
+ verify(
+ 'TableOfContentsFilter',
+
+ '[[_TOC_]]'
+ )
+
+ verify(
+ 'EmojiFilter',
+
+ ':thumbsup:'
+ )
+
+ verify(
+ 'ImageLinkFilter',
+
+ '![Image](https://example.com/image.png)'
+ )
+
+ verify(
+ 'VideoLinkFilter',
+
+ '![Video](https://example.com/video.mp4)'
+ )
+
+ verify(
+ 'MathFilter: math as converted from GFM to HTML',
+
+ '$`c = \pm\sqrt{a^2 + b^2}`$',
+
+ # math block
+ <<-GFM.strip_heredoc
+ ```math
+ c = \pm\sqrt{a^2 + b^2}
+ ```
+ GFM
+ )
+
+ aggregate_failures('MathFilter: math as transformed from HTML to KaTeX') do
+ gfm = '$`c = \pm\sqrt{a^2 + b^2}`$'
+
+ html = <<-HTML.strip_heredoc
+ <span class="katex">
+ <span class="katex-mathml">
+ <math>
+ <semantics>
+ <mrow>
+ <mi>c</mi>
+ <mo>=</mo>
+ <mo>±</mo>
+ <msqrt>
+ <mrow>
+ <msup>
+ <mi>a</mi>
+ <mn>2</mn>
+ </msup>
+ <mo>+</mo>
+ <msup>
+ <mi>b</mi>
+ <mn>2</mn>
+ </msup>
+ </mrow>
+ </msqrt>
+ </mrow>
+ <annotation encoding="application/x-tex">c = \\pm\\sqrt{a^2 + b^2}</annotation>
+ </semantics>
+ </math>
+ </span>
+ <span class="katex-html" aria-hidden="true">
+ <span class="strut" style="height: 0.913389em;"></span>
+ <span class="strut bottom" style="height: 1.04em; vertical-align: -0.126611em;"></span>
+ <span class="base textstyle uncramped">
+ <span class="mord mathit">c</span>
+ <span class="mrel">=</span>
+ <span class="mord">±</span>
+ <span class="sqrt mord"><span class="sqrt-sign" style="top: -0.073389em;">
+ <span class="style-wrap reset-textstyle textstyle uncramped">√</span>
+ </span>
+ <span class="vlist">
+ <span class="" style="top: 0em;">
+ <span class="fontsize-ensurer reset-size5 size5">
+ <span class="" style="font-size: 1em;">​</span>
+ </span>
+ <span class="mord textstyle cramped">
+ <span class="mord">
+ <span class="mord mathit">a</span>
+ <span class="msupsub">
+ <span class="vlist">
+ <span class="" style="top: -0.289em; margin-right: 0.05em;">
+ <span class="fontsize-ensurer reset-size5 size5">
+ <span class="" style="font-size: 0em;">​</span>
+ </span>
+ <span class="reset-textstyle scriptstyle cramped">
+ <span class="mord mathrm">2</span>
+ </span>
+ </span>
+ <span class="baseline-fix">
+ <span class="fontsize-ensurer reset-size5 size5">
+ <span class="" style="font-size: 0em;">​</span>
+ </span>
+ ​</span>
+ </span>
+ </span>
+ </span>
+ <span class="mbin">+</span>
+ <span class="mord">
+ <span class="mord mathit">b</span>
+ <span class="msupsub">
+ <span class="vlist">
+ <span class="" style="top: -0.289em; margin-right: 0.05em;">
+ <span class="fontsize-ensurer reset-size5 size5">
+ <span class="" style="font-size: 0em;">​</span>
+ </span>
+ <span class="reset-textstyle scriptstyle cramped">
+ <span class="mord mathrm">2</span>
+ </span>
+ </span>
+ <span class="baseline-fix">
+ <span class="fontsize-ensurer reset-size5 size5">
+ <span class="" style="font-size: 0em;">​</span>
+ </span>
+ ​</span>
+ </span>
+ </span>
+ </span>
+ </span>
+ </span>
+ <span class="" style="top: -0.833389em;">
+ <span class="fontsize-ensurer reset-size5 size5">
+ <span class="" style="font-size: 1em;">​</span>
+ </span>
+ <span class="reset-textstyle textstyle uncramped sqrt-line"></span>
+ </span>
+ <span class="baseline-fix">
+ <span class="fontsize-ensurer reset-size5 size5">
+ <span class="" style="font-size: 1em;">​</span>
+ </span>
+ ​</span>
+ </span>
+ </span>
+ </span>
+ </span>
+ </span>
+ HTML
+
+ output_gfm = html_to_gfm(html)
+ expect(output_gfm.strip).to eq(gfm.strip)
+ end
+
+ verify(
+ 'SanitizationFilter',
+
+ <<-GFM.strip_heredoc
+ <sub>sub</sub>
+
+ <dl>
+ <dt>dt</dt>
+ <dd>dd</dd>
+ </dl>
+
+ <kbd>kbd</kbd>
+
+ <q>q</q>
+
+ <samp>samp</samp>
+
+ <var>var</var>
+
+ <ruby>ruby</ruby>
+
+ <rt>rt</rt>
+
+ <rp>rp</rp>
+
+ <abbr>abbr</abbr>
+ GFM
+ )
+
+ verify(
+ 'SanitizationFilter',
+
+ <<-GFM.strip_heredoc,
+ ```
+ Plain text
+ ```
+ GFM
+
+ <<-GFM.strip_heredoc,
+ ```ruby
+ def foo
+ bar
+ end
+ ```
+ GFM
+
+ <<-GFM.strip_heredoc
+ Foo
+
+ This is an example of GFM
+
+ ```js
+ Code goes here
+ ```
+ GFM
+ )
+
+ verify(
+ 'MarkdownFilter',
+
+ "Line with two spaces at the end \nto insert a linebreak",
+
+ '`code`',
+ '`` code with ` ticks ``',
+
+ '> Quote',
+
+ # multiline quote
+ <<-GFM.strip_heredoc,
+ > Multiline
+ > Quote
+ >
+ > With multiple paragraphs
+ GFM
+
+ '![Image](https://example.com/image.png)',
+
+ '# Heading with no anchor link',
+
+ '[Link](https://example.com)',
+
+ '- List item',
+
+ # multiline list item
+ <<-GFM.strip_heredoc,
+ - Multiline
+ List item
+ GFM
+
+ # nested lists
+ <<-GFM.strip_heredoc,
+ - Nested
+
+
+ - Lists
+ GFM
+
+ # list with blockquote
+ <<-GFM.strip_heredoc,
+ - List
+
+ > Blockquote
+ GFM
+
+ '1. Numbered list item',
+
+ # multiline numbered list item
+ <<-GFM.strip_heredoc,
+ 1. Multiline
+ Numbered list item
+ GFM
+
+ # nested numbered list
+ <<-GFM.strip_heredoc,
+ 1. Nested
+
+
+ 1. Numbered lists
+ GFM
+
+ '# Heading',
+ '## Heading',
+ '### Heading',
+ '#### Heading',
+ '##### Heading',
+ '###### Heading',
+
+ '**Bold**',
+
+ '_Italics_',
+
+ '~~Strikethrough~~',
+
+ '2^2',
+
+ '-----',
+
+ # table
+ <<-GFM.strip_heredoc,
+ | Centered | Right | Left |
+ |:--------:|------:|------|
+ | Foo | Bar | **Baz** |
+ | Foo | Bar | **Baz** |
+ GFM
+
+ # table with empty heading
+ <<-GFM.strip_heredoc,
+ | | x | y |
+ |---|---|---|
+ | a | 1 | 0 |
+ | b | 0 | 1 |
+ GFM
+ )
+ end
+
+ alias_method :gfm_to_html, :markdown
+
+ def html_to_gfm(html)
+ js = <<-JS.strip_heredoc
+ (function(html) {
+ var node = document.createElement('div');
+ node.innerHTML = html;
+ return window.gl.CopyAsGFM.nodeToGFM(node);
+ })("#{escape_javascript(html)}")
+ JS
+ page.evaluate_script(js)
+ end
+
+ def verify(label, *gfms)
+ aggregate_failures(label) do
+ gfms.each do |gfm|
+ html = gfm_to_html(gfm)
+ output_gfm = html_to_gfm(html)
+ expect(output_gfm.strip).to eq(gfm.strip)
+ end
+ end
+ end
+
+ # Fake a `current_user` helper
+ def current_user
+ @feat.user
+ end
+end
diff --git a/spec/features/dashboard/shortcuts_spec.rb b/spec/features/dashboard/shortcuts_spec.rb
new file mode 100644
index 00000000000..d9be4e5dbdd
--- /dev/null
+++ b/spec/features/dashboard/shortcuts_spec.rb
@@ -0,0 +1,29 @@
+require 'spec_helper'
+
+feature 'Dashboard shortcuts', feature: true, js: true do
+ before do
+ login_as :user
+ visit dashboard_projects_path
+ end
+
+ scenario 'Navigate to tabs' do
+ find('body').native.send_key('g')
+ find('body').native.send_key('p')
+
+ ensure_active_main_tab('Projects')
+
+ find('body').native.send_key('g')
+ find('body').native.send_key('i')
+
+ ensure_active_main_tab('Issues')
+
+ find('body').native.send_key('g')
+ find('body').native.send_key('m')
+
+ ensure_active_main_tab('Merge Requests')
+ end
+
+ def ensure_active_main_tab(content)
+ expect(find('.nav-sidebar li.active')).to have_content(content)
+ end
+end
diff --git a/spec/features/environment_spec.rb b/spec/features/environment_spec.rb
index 56f6cd2e095..511c95b758f 100644
--- a/spec/features/environment_spec.rb
+++ b/spec/features/environment_spec.rb
@@ -19,6 +19,10 @@ feature 'Environment', :feature do
visit_environment(environment)
end
+ scenario 'shows environment name' do
+ expect(page).to have_content(environment.name)
+ end
+
context 'without deployments' do
scenario 'does show no deployments' do
expect(page).to have_content('You don\'t have any deployments right now.')
diff --git a/spec/features/environments_spec.rb b/spec/features/environments_spec.rb
index 34ff3a33c19..010186d77fa 100644
--- a/spec/features/environments_spec.rb
+++ b/spec/features/environments_spec.rb
@@ -220,7 +220,7 @@ feature 'Environments page', :feature, :js do
end
scenario 'does create a new pipeline' do
- expect(page).to have_content('Production')
+ expect(page).to have_content('production')
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 8a155c3bfc5..93763f092fb 100644
--- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
@@ -43,14 +43,6 @@ describe 'Dropdown assignee', js: true, feature: true do
expect(page).to have_css(js_dropdown_assignee, visible: true)
end
- it 'shows assigned to me link' do
- filtered_search.set('assignee:')
-
- page.within js_dropdown_assignee do
- expect(page).to have_content('Assigned to me')
- end
- end
-
it 'closes when the search bar is unfocused' do
find('body').click()
@@ -129,14 +121,6 @@ describe 'Dropdown assignee', js: true, feature: true do
filtered_search.set('assignee:')
end
- it 'filters by current user' do
- page.within js_dropdown_assignee do
- click_button 'Assigned to me'
- end
-
- expect(filtered_search.value).to eq("assignee:#{user.to_reference} ")
- end
-
it 'fills in the assignee username when the assignee has not been filtered' do
click_assignee(user_jacob.name)
@@ -185,4 +169,22 @@ describe 'Dropdown assignee', js: true, feature: true do
expect(page).to have_css(js_dropdown_assignee, visible: true)
end
end
+
+ describe 'caching requests' do
+ it 'caches requests after the first load' do
+ filtered_search.set('assignee')
+ send_keys_to_filtered_search(':')
+ initial_size = dropdown_assignee_size
+
+ expect(initial_size).to be > 0
+
+ new_user = create(:user)
+ project.team << [new_user, :master]
+ find('.filtered-search-input-container .clear-search').click
+ filtered_search.set('assignee')
+ send_keys_to_filtered_search(':')
+
+ expect(dropdown_assignee_size).to eq(initial_size)
+ end
+ end
end
diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb
index a5d5d9d4c5e..59e302f0e2d 100644
--- a/spec/features/issues/filtered_search/dropdown_author_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb
@@ -157,4 +157,22 @@ describe 'Dropdown author', js: true, feature: true do
expect(page).to have_css(js_dropdown_author, visible: true)
end
end
+
+ describe 'caching requests' do
+ it 'caches requests after the first load' do
+ filtered_search.set('author')
+ send_keys_to_filtered_search(':')
+ initial_size = dropdown_author_size
+
+ expect(initial_size).to be > 0
+
+ new_user = create(:user)
+ project.team << [new_user, :master]
+ find('.filtered-search-input-container .clear-search').click
+ filtered_search.set('author')
+ send_keys_to_filtered_search(':')
+
+ expect(dropdown_author_size).to eq(initial_size)
+ end
+ end
end
diff --git a/spec/features/issues/filtered_search/dropdown_label_spec.rb b/spec/features/issues/filtered_search/dropdown_label_spec.rb
index bea00160f96..5079eb8dd00 100644
--- a/spec/features/issues/filtered_search/dropdown_label_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_label_spec.rb
@@ -40,6 +40,16 @@ describe 'Dropdown label', js: true, feature: true do
visit namespace_project_issues_path(project.namespace, project)
end
+ describe 'keyboard navigation' do
+ it 'selects label' do
+ send_keys_to_filtered_search('label:')
+
+ filtered_search.native.send_keys(:down, :down, :enter)
+
+ expect(filtered_search.value).to eq("label:~#{special_label.name} ")
+ end
+ end
+
describe 'behavior' do
it 'opens when the search bar has label:' do
filtered_search.set('label:')
@@ -239,4 +249,21 @@ describe 'Dropdown label', js: true, feature: true do
expect(page).to have_css(js_dropdown_label, visible: true)
end
end
+
+ describe 'caching requests' do
+ it 'caches requests after the first load' do
+ filtered_search.set('label')
+ send_keys_to_filtered_search(':')
+ initial_size = dropdown_label_size
+
+ expect(initial_size).to be > 0
+
+ create(:label, project: project)
+ find('.filtered-search-input-container .clear-search').click
+ filtered_search.set('label')
+ send_keys_to_filtered_search(':')
+
+ expect(dropdown_label_size).to eq(initial_size)
+ end
+ end
end
diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
index 134e58ad586..0ce16715b86 100644
--- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb
@@ -219,4 +219,21 @@ describe 'Dropdown milestone', js: true, feature: true do
expect(page).to have_css(js_dropdown_milestone, visible: true)
end
end
+
+ describe 'caching requests' do
+ it 'caches requests after the first load' do
+ filtered_search.set('milestone')
+ send_keys_to_filtered_search(':')
+ initial_size = dropdown_milestone_size
+
+ expect(initial_size).to be > 0
+
+ create(:milestone, project: project)
+ find('.filtered-search-input-container .clear-search').click
+ filtered_search.set('milestone')
+ send_keys_to_filtered_search(':')
+
+ expect(dropdown_milestone_size).to eq(initial_size)
+ end
+ end
end
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index f48a0193545..3f70a6aa75f 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -773,7 +773,7 @@ describe 'Filter issues', js: true, feature: true do
describe 'RSS feeds' do
it 'updates atom feed link for project issues' do
visit namespace_project_issues_path(project.namespace, project, milestone_title: milestone.title, assignee_id: user.id)
- link = find('.nav-controls a', text: 'Subscribe')
+ link = find_link('Subscribe')
params = CGI.parse(URI.parse(link[:href]).query)
auto_discovery_link = find('link[type="application/atom+xml"]', visible: false)
auto_discovery_params = CGI.parse(URI.parse(auto_discovery_link[:href]).query)
diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb
index 56b1d354eb0..90eb60eb337 100644
--- a/spec/features/issues/filtered_search/search_bar_spec.rb
+++ b/spec/features/issues/filtered_search/search_bar_spec.rb
@@ -20,6 +20,22 @@ describe 'Search bar', js: true, feature: true do
left_style.to_s.gsub('left: ', '').to_f
end
+ describe 'keyboard navigation' do
+ it 'makes item active' do
+ filtered_search.native.send_keys(:down)
+
+ page.within '#js-dropdown-hint' do
+ expect(page).to have_selector('.dropdown-active')
+ end
+ end
+
+ it 'selects item' do
+ filtered_search.native.send_keys(:down, :down, :enter)
+
+ expect(filtered_search.value).to eq('author:')
+ end
+ end
+
describe 'clear search button' do
it 'clears text' do
search_text = 'search_text'
diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb
index 8771cc8e157..741ca95f1ca 100644
--- a/spec/features/issues/form_spec.rb
+++ b/spec/features/issues/form_spec.rb
@@ -68,6 +68,22 @@ describe 'New/edit issue', feature: true, js: true do
end
end
end
+
+ it 'correctly updates the dropdown toggle when removing a label' do
+ click_button 'Labels'
+
+ page.within '.dropdown-menu-labels' do
+ click_link label.title
+ end
+
+ expect(find('.js-label-select')).to have_content(label.title)
+
+ page.within '.dropdown-menu-labels' do
+ click_link label.title
+ end
+
+ expect(find('.js-label-select')).to have_content('Labels')
+ end
end
context 'edit issue' do
diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb
index 31156fcf994..93139dc9e94 100644
--- a/spec/features/issues/gfm_autocomplete_spec.rb
+++ b/spec/features/issues/gfm_autocomplete_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
feature 'GFM autocomplete', feature: true, js: true do
include WaitForAjax
- let(:user) { create(:user, username: 'someone.special') }
+ let(:user) { create(:user, name: '💃speciąl someone💃', username: 'someone.special') }
let(:project) { create(:project) }
let(:label) { create(:label, project: project, title: 'special+') }
let(:issue) { create(:issue, project: project) }
@@ -59,6 +59,19 @@ feature 'GFM autocomplete', feature: true, js: true do
expect(find('#at-view-64')).to have_selector('.cur:first-of-type')
end
+ it 'includes items for assignee dropdowns with non-ASCII characters in name' do
+ page.within '.timeline-content-form' do
+ find('#note_note').native.send_keys('')
+ find('#note_note').native.send_keys("@#{user.name[0...8]}")
+ end
+
+ expect(page).to have_selector('.atwho-container')
+
+ wait_for_ajax
+
+ expect(find('#at-view-64')).to have_content(user.name)
+ end
+
it 'selects the first item for non-assignee dropdowns if a query is entered' do
page.within '.timeline-content-form' do
find('#note_note').native.send_keys('')
diff --git a/spec/features/issues/group_label_sidebar_spec.rb b/spec/features/issues/group_label_sidebar_spec.rb
new file mode 100644
index 00000000000..fc8515cfe9b
--- /dev/null
+++ b/spec/features/issues/group_label_sidebar_spec.rb
@@ -0,0 +1,21 @@
+require 'rails_helper'
+
+describe 'Group label on issue', :feature do
+ it 'renders link to the project issues page' do
+ group = create(:group)
+ project = create(:empty_project, :public, namespace: group)
+ feature = create(:group_label, group: group, title: 'feature')
+ issue = create(:labeled_issue, project: project, labels: [feature])
+ label_link = namespace_project_issues_path(
+ project.namespace,
+ project,
+ label_name: [feature.name]
+ )
+
+ visit namespace_project_issue_path(project.namespace, project, issue)
+
+ link = find('.issuable-show-labels a')
+
+ expect(link[:href]).to eq(label_link)
+ end
+end
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index bc068b5e7e0..1eb981942ea 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -2,6 +2,7 @@ require 'rails_helper'
feature 'Issue Sidebar', feature: true do
include WaitForAjax
+ include MobileHelpers
let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project) }
@@ -59,6 +60,23 @@ feature 'Issue Sidebar', feature: true do
end
end
+ context 'sidebar', js: true do
+ it 'changes size when the screen size is smaller' do
+ sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed'
+ # Resize the window
+ resize_screen_sm
+ # Make sure the sidebar is collapsed
+ expect(page).to have_css(sidebar_selector)
+ # Once is collapsed let's open the sidebard and reload
+ open_issue_sidebar
+ refresh
+ expect(page).to have_css(sidebar_selector)
+ # Restore the window size as it was including the sidebar
+ restore_window_size
+ open_issue_sidebar
+ end
+ end
+
context 'creating a new label', js: true do
it 'shows option to crate a new label is present' do
page.within('.block.labels') do
@@ -109,4 +127,11 @@ feature 'Issue Sidebar', feature: true do
def visit_issue(project, issue)
visit namespace_project_issue_path(project.namespace, project, issue)
end
+
+ def open_issue_sidebar
+ page.within('aside.right-sidebar.right-sidebar-collapsed') do
+ find('.js-sidebar-toggle').click
+ sleep 1
+ end
+ end
end
diff --git a/spec/features/issues/new_branch_button_spec.rb b/spec/features/issues/new_branch_button_spec.rb
index a4d3053d10c..c0ab42c6822 100644
--- a/spec/features/issues/new_branch_button_spec.rb
+++ b/spec/features/issues/new_branch_button_spec.rb
@@ -1,6 +1,6 @@
require 'rails_helper'
-feature 'Start new branch from an issue', feature: true do
+feature 'Start new branch from an issue', feature: true, js: true do
let!(:project) { create(:project) }
let!(:issue) { create(:issue, project: project) }
let!(:user) { create(:user)}
@@ -11,7 +11,7 @@ feature 'Start new branch from an issue', feature: true do
login_as(user)
end
- it 'shows the new branch button', js: true do
+ it 'shows the new branch button' do
visit namespace_project_issue_path(project.namespace, project, issue)
expect(page).to have_css('#new-branch .available')
@@ -34,16 +34,26 @@ feature 'Start new branch from an issue', feature: true do
visit namespace_project_issue_path(project.namespace, project, issue)
end
- it "hides the new branch button", js: true do
+ it "hides the new branch button" do
expect(page).to have_css('#new-branch .unavailable')
expect(page).not_to have_css('#new-branch .available')
expect(page).to have_content /1 Related Merge Request/
end
end
+
+ context 'when issue is confidential' do
+ it 'hides the new branch button' do
+ issue = create(:issue, :confidential, project: project)
+
+ visit namespace_project_issue_path(project.namespace, project, issue)
+
+ expect(page).not_to have_css('#new-branch')
+ end
+ end
end
- context "for visiters" do
- it 'shows no buttons', js: true do
+ context 'for visitors' do
+ it 'shows no buttons' do
visit namespace_project_issue_path(project.namespace, project, issue)
expect(page).not_to have_css('#new-branch')
diff --git a/spec/features/login_spec.rb b/spec/features/login_spec.rb
index 76bcfbe523a..ab7d89306db 100644
--- a/spec/features/login_spec.rb
+++ b/spec/features/login_spec.rb
@@ -25,6 +25,11 @@ feature 'Login', feature: true do
expect(current_path).to eq root_path
end
+
+ it 'does not show flash messages when login page' do
+ visit root_path
+ expect(page).not_to have_content('You need to sign in or sign up before continuing.')
+ end
end
describe 'with two-factor authentication' do
diff --git a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb
index 7e2907cd26f..d2f5c4afc93 100644
--- a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb
+++ b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb
@@ -50,7 +50,7 @@ feature 'Only allow merge requests to be merged if the build succeeds', feature:
visit_merge_request(merge_request)
expect(page).not_to have_button 'Accept Merge Request'
- expect(page).to have_content('Please retry the build or push a new commit to fix the failure.')
+ expect(page).to have_content('Please retry the job or push a new commit to fix the failure.')
end
end
@@ -61,7 +61,7 @@ feature 'Only allow merge requests to be merged if the build succeeds', feature:
visit_merge_request(merge_request)
expect(page).not_to have_button 'Accept Merge Request'
- expect(page).to have_content('Please retry the build or push a new commit to fix the failure.')
+ expect(page).to have_content('Please retry the job or push a new commit to fix the failure.')
end
end
diff --git a/spec/features/merge_requests/toggler_behavior_spec.rb b/spec/features/merge_requests/toggler_behavior_spec.rb
new file mode 100644
index 00000000000..a2cf9b18bf2
--- /dev/null
+++ b/spec/features/merge_requests/toggler_behavior_spec.rb
@@ -0,0 +1,28 @@
+require 'spec_helper'
+
+feature 'toggler_behavior', js: true, feature: true do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:merge_request) { create(:merge_request, source_project: project, author: user) }
+ let(:note) { create(:diff_note_on_merge_request, noteable: merge_request, project: project) }
+ let(:fragment_id) { "#note_#{note.id}" }
+
+ before do
+ login_as :admin
+ project = merge_request.source_project
+ page.current_window.resize_to(1000, 300)
+ visit "#{namespace_project_merge_request_path(project.namespace, project, merge_request)}#{fragment_id}"
+ end
+
+ describe 'scroll position' do
+ it 'should be scrolled down to fragment' do
+ page_height = page.current_window.size[1]
+ page_scroll_y = page.evaluate_script("window.scrollY")
+ fragment_position_top = page.evaluate_script("$('#{fragment_id}').offset().top")
+ expect(find('.js-toggle-content').visible?).to eq true
+ expect(find(fragment_id).visible?).to eq true
+ expect(fragment_position_top).to be >= page_scroll_y
+ expect(fragment_position_top).to be < (page_scroll_y + page_height)
+ end
+ end
+end
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 b13674b4db9..2f3c3e45ae6 100644
--- a/spec/features/merge_requests/user_uses_slash_commands_spec.rb
+++ b/spec/features/merge_requests/user_uses_slash_commands_spec.rb
@@ -11,7 +11,7 @@ feature 'Merge Requests > User uses slash commands', feature: true, js: true do
it_behaves_like 'issuable record that supports slash commands in its description and notes', :merge_request do
let(:issuable) { create(:merge_request, source_project: project) }
- let(:new_url_opts) { { merge_request: { source_branch: 'feature' } } }
+ let(:new_url_opts) { { merge_request: { source_branch: 'feature', target_branch: 'master' } } }
end
describe 'merge-request-only commands' do
@@ -120,5 +120,81 @@ feature 'Merge Requests > User uses slash commands', feature: true, js: true do
expect(page).not_to have_content '/due 2016-08-28'
end
end
+
+ describe '/target_branch command in merge request' do
+ let(:another_project) { create(:project, :public) }
+ let(:new_url_opts) { { merge_request: { source_branch: 'feature' } } }
+
+ before do
+ logout
+ another_project.team << [user, :master]
+ login_with(user)
+ end
+
+ it 'changes target_branch in new merge_request' do
+ visit new_namespace_project_merge_request_path(another_project.namespace, another_project, new_url_opts)
+ click_button "Compare branches and continue"
+
+ fill_in "merge_request_title", with: 'My brand new feature'
+ fill_in "merge_request_description", with: "le feature \n/target_branch fix\nFeature description:"
+ click_button "Submit merge request"
+
+ merge_request = another_project.merge_requests.first
+ expect(merge_request.description).to eq "le feature \nFeature description:"
+ expect(merge_request.target_branch).to eq 'fix'
+ end
+
+ it 'does not change target branch when merge request is edited' do
+ new_merge_request = create(:merge_request, source_project: another_project)
+
+ visit edit_namespace_project_merge_request_path(another_project.namespace, another_project, new_merge_request)
+ fill_in "merge_request_description", with: "Want to update target branch\n/target_branch fix\n"
+ click_button "Save changes"
+
+ new_merge_request = another_project.merge_requests.first
+ expect(new_merge_request.description).to include('/target_branch')
+ expect(new_merge_request.target_branch).not_to eq('fix')
+ end
+ end
+
+ describe '/target_branch command from note' do
+ context 'when the current user can change target branch' do
+ it 'changes target branch from a note' do
+ write_note("message start \n/target_branch merge-test\n message end.")
+
+ expect(page).not_to have_content('/target_branch')
+ expect(page).to have_content('message start')
+ expect(page).to have_content('message end.')
+
+ expect(merge_request.reload.target_branch).to eq 'merge-test'
+ end
+
+ it 'does not fail when target branch does not exists' do
+ write_note('/target_branch totally_not_existing_branch')
+
+ expect(page).not_to have_content('/target_branch')
+
+ expect(merge_request.target_branch).to eq 'feature'
+ end
+ end
+
+ context 'when current user can not change target branch' do
+ let(:guest) { create(:user) }
+ before do
+ project.team << [guest, :guest]
+ logout
+ login_with(guest)
+ visit namespace_project_merge_request_path(project.namespace, project, merge_request)
+ end
+
+ it 'does not change target branch' do
+ write_note('/target_branch merge-test')
+
+ expect(page).not_to have_content '/target_branch merge-test'
+
+ expect(merge_request.target_branch).to eq 'feature'
+ end
+ end
+ end
end
end
diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb
new file mode 100644
index 00000000000..7d1805f5001
--- /dev/null
+++ b/spec/features/merge_requests/widget_spec.rb
@@ -0,0 +1,34 @@
+require 'rails_helper'
+
+describe 'Merge request', :feature, :js do
+ include WaitForAjax
+
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+
+ before do
+ project.team << [user, :master]
+ login_as(user)
+
+ visit new_namespace_project_merge_request_path(
+ project.namespace,
+ project,
+ merge_request: {
+ source_project_id: project.id,
+ target_project_id: project.id,
+ source_branch: 'feature',
+ target_branch: 'master'
+ }
+ )
+ end
+
+ it 'shows widget status after creating new merge request' do
+ click_button 'Submit merge request'
+
+ expect(find('.mr-state-widget')).to have_content('Checking ability to merge automatically')
+
+ wait_for_ajax
+
+ expect(page).to have_selector('.accept_merge_request')
+ end
+end
diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb
index b785b2f7704..fab2d532e06 100644
--- a/spec/features/notes_on_merge_requests_spec.rb
+++ b/spec/features/notes_on_merge_requests_spec.rb
@@ -89,7 +89,7 @@ describe 'Comments', feature: true do
end
end
- it 'should reset the edit note form textarea with the original content of the note if cancelled' do
+ it 'resets the edit note form textarea with the original content of the note if cancelled' do
within('.current-note-edit-form') do
fill_in 'note[note]', with: 'Some new content'
find('.btn-cancel').click
@@ -198,7 +198,7 @@ describe 'Comments', feature: true do
end
describe 'the note form' do
- it "shouldn't add a second form for same row" do
+ it "does not add a second form for same row" do
click_diff_line
is_expected.
@@ -206,7 +206,7 @@ describe 'Comments', feature: true do
count: 1)
end
- it 'should be removed when canceled' do
+ it 'is removed when canceled' do
is_expected.to have_css('.js-temp-notes-holder')
page.within("form[data-line-code='#{line_code}']") do
diff --git a/spec/features/projects/builds_spec.rb b/spec/features/projects/builds_spec.rb
index 11d27feab0b..f7e0115643e 100644
--- a/spec/features/projects/builds_spec.rb
+++ b/spec/features/projects/builds_spec.rb
@@ -27,7 +27,7 @@ feature 'Builds', :feature do
visit namespace_project_builds_path(project.namespace, project, scope: :pending)
end
- it "shows Pending tab builds" do
+ it "shows Pending tab jobs" do
expect(page).to have_link 'Cancel running'
expect(page).to have_selector('.nav-links li.active', text: 'Pending')
expect(page).to have_content build.short_sha
@@ -42,7 +42,7 @@ feature 'Builds', :feature do
visit namespace_project_builds_path(project.namespace, project, scope: :running)
end
- it "shows Running tab builds" do
+ it "shows Running tab jobs" do
expect(page).to have_selector('.nav-links li.active', text: 'Running')
expect(page).to have_link 'Cancel running'
expect(page).to have_content build.short_sha
@@ -57,20 +57,20 @@ feature 'Builds', :feature do
visit namespace_project_builds_path(project.namespace, project, scope: :finished)
end
- it "shows Finished tab builds" do
+ it "shows Finished tab jobs" do
expect(page).to have_selector('.nav-links li.active', text: 'Finished')
- expect(page).to have_content 'No builds to show'
+ expect(page).to have_content 'No jobs to show'
expect(page).to have_link 'Cancel running'
end
end
- context "All builds" do
+ context "All jobs" do
before do
project.builds.running_or_pending.each(&:success)
visit namespace_project_builds_path(project.namespace, project)
end
- it "shows All tab builds" do
+ it "shows All tab jobs" do
expect(page).to have_selector('.nav-links li.active', text: 'All')
expect(page).to have_content build.short_sha
expect(page).to have_content build.ref
@@ -98,7 +98,7 @@ feature 'Builds', :feature do
end
describe "GET /:project/builds/:id" do
- context "Build from project" do
+ context "Job from project" do
before do
visit namespace_project_build_path(project.namespace, project, build)
end
@@ -111,7 +111,7 @@ feature 'Builds', :feature do
end
end
- context "Build from other project" do
+ context "Job from other project" do
before do
visit namespace_project_build_path(project.namespace, project, build2)
end
@@ -149,7 +149,7 @@ feature 'Builds', :feature do
context 'when expire date is defined' do
let(:expire_at) { Time.now + 7.days }
- context 'when user has ability to update build' do
+ context 'when user has ability to update job' do
it 'keeps artifacts when keep button is clicked' do
expect(page).to have_content 'The artifacts will be removed'
@@ -160,7 +160,7 @@ feature 'Builds', :feature do
end
end
- context 'when user does not have ability to update build' do
+ context 'when user does not have ability to update job' do
let(:user_access_level) { :guest }
it 'does not have keep button' do
@@ -197,8 +197,8 @@ feature 'Builds', :feature do
visit namespace_project_build_path(project.namespace, project, build)
end
- context 'when build has an initial trace' do
- it 'loads build trace' do
+ context 'when job has an initial trace' do
+ it 'loads job trace' do
expect(page).to have_content 'BUILD TRACE'
build.append_trace(' and more trace', 11)
@@ -242,32 +242,32 @@ feature 'Builds', :feature do
end
end
- context 'when build starts environment' do
+ context 'when job starts environment' do
let(:environment) { create(:environment, project: project) }
let(:pipeline) { create(:ci_pipeline, project: project) }
- context 'build is successfull and has deployment' do
+ context 'job is successfull and has deployment' do
let(:deployment) { create(:deployment) }
let(:build) { create(:ci_build, :success, environment: environment.name, deployments: [deployment], pipeline: pipeline) }
- it 'shows a link for the build' do
+ it 'shows a link for the job' do
visit namespace_project_build_path(project.namespace, project, build)
expect(page).to have_link environment.name
end
end
- context 'build is complete and not successfull' do
+ context 'job is complete and not successfull' do
let(:build) { create(:ci_build, :failed, environment: environment.name, pipeline: pipeline) }
- it 'shows a link for the build' do
+ it 'shows a link for the job' do
visit namespace_project_build_path(project.namespace, project, build)
expect(page).to have_link environment.name
end
end
- context 'build creates a new deployment' do
+ context 'job creates a new deployment' do
let!(:deployment) { create(:deployment, environment: environment, sha: project.commit.id) }
let(:build) { create(:ci_build, :success, environment: environment.name, pipeline: pipeline) }
@@ -281,7 +281,7 @@ feature 'Builds', :feature do
end
describe "POST /:project/builds/:id/cancel" do
- context "Build from project" do
+ context "Job from project" do
before do
build.run!
visit namespace_project_build_path(project.namespace, project, build)
@@ -295,7 +295,7 @@ feature 'Builds', :feature do
end
end
- context "Build from other project" do
+ context "Job from other project" do
before do
build.run!
visit namespace_project_build_path(project.namespace, project, build)
@@ -307,13 +307,13 @@ feature 'Builds', :feature do
end
describe "POST /:project/builds/:id/retry" do
- context "Build from project" do
+ context "Job from project" do
before do
build.run!
visit namespace_project_build_path(project.namespace, project, build)
click_link 'Cancel'
page.within('.build-header') do
- click_link 'Retry build'
+ click_link 'Retry job'
end
end
diff --git a/spec/features/projects/files/editing_a_file_spec.rb b/spec/features/projects/files/editing_a_file_spec.rb
index fe047e00409..36a80d7575d 100644
--- a/spec/features/projects/files/editing_a_file_spec.rb
+++ b/spec/features/projects/files/editing_a_file_spec.rb
@@ -7,7 +7,7 @@ feature 'User wants to edit a file', feature: true do
let(:user) { create(:user) }
let(:commit_params) do
{
- source_branch: project.default_branch,
+ start_branch: project.default_branch,
target_branch: project.default_branch,
commit_message: "Committing First Update",
file_path: ".gitignore",
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 a521ce50f35..64094af29c0 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
@@ -6,7 +6,8 @@ feature 'project owner creates a license file', feature: true, js: true do
let(:project_master) { create(:user) }
let(:project) { create(:project) }
background do
- project.repository.remove_file(project_master, 'LICENSE', 'Remove LICENSE', 'master')
+ project.repository.remove_file(project_master, 'LICENSE',
+ message: 'Remove LICENSE', branch_name: 'master')
project.team << [project_master, :master]
login_as(project_master)
visit namespace_project_path(project.namespace, project)
diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb
index 52d08982c7a..16dddb2a86b 100644
--- a/spec/features/projects/import_export/export_file_spec.rb
+++ b/spec/features/projects/import_export/export_file_spec.rb
@@ -74,6 +74,9 @@ feature 'Import/Export - project export integration test', feature: true, js: tr
Otherwise, please add the exception to +safe_list+ in CURRENT_SPEC using #{sensitive_word} as the key and the
correspondent hash or model as the value.
+ Also, if the attribute is a generated unique token, please add it to RelationFactory::TOKEN_RESET_MODELS if it needs to be
+ reset (to prevent duplicate column problems while importing to the same instance).
+
IMPORT_EXPORT_CONFIG: #{Gitlab::ImportExport.config_file}
CURRENT_SPEC: #{__FILE__}
MSG
diff --git a/spec/features/projects/import_export/test_project_export.tar.gz b/spec/features/projects/import_export/test_project_export.tar.gz
index 7655c2b351f..20cdfbae24f 100644
--- a/spec/features/projects/import_export/test_project_export.tar.gz
+++ b/spec/features/projects/import_export/test_project_export.tar.gz
Binary files differ
diff --git a/spec/features/projects/issuable_templates_spec.rb b/spec/features/projects/issuable_templates_spec.rb
index 6dae5c64b30..e90a033b8c4 100644
--- a/spec/features/projects/issuable_templates_spec.rb
+++ b/spec/features/projects/issuable_templates_spec.rb
@@ -18,8 +18,20 @@ feature 'issuable templates', feature: true, js: true do
let(:description_addition) { ' appending to description' }
background do
- project.repository.commit_file(user, '.gitlab/issue_templates/bug.md', template_content, 'added issue template', 'master', false)
- project.repository.commit_file(user, '.gitlab/issue_templates/test.md', longtemplate_content, 'added issue template', 'master', false)
+ project.repository.commit_file(
+ user,
+ '.gitlab/issue_templates/bug.md',
+ template_content,
+ message: 'added issue template',
+ branch_name: 'master',
+ update: false)
+ project.repository.commit_file(
+ user,
+ '.gitlab/issue_templates/test.md',
+ longtemplate_content,
+ message: 'added issue template',
+ branch_name: 'master',
+ update: false)
visit edit_namespace_project_issue_path project.namespace, project, issue
fill_in :'issue[title]', with: 'test issue title'
end
@@ -67,7 +79,13 @@ feature 'issuable templates', feature: true, js: true do
let(:issue) { create(:issue, author: user, assignee: user, project: project) }
background do
- project.repository.commit_file(user, '.gitlab/issue_templates/bug.md', template_content, 'added issue template', 'master', false)
+ project.repository.commit_file(
+ user,
+ '.gitlab/issue_templates/bug.md',
+ template_content,
+ message: 'added issue template',
+ branch_name: 'master',
+ update: false)
visit edit_namespace_project_issue_path project.namespace, project, issue
fill_in :'issue[title]', with: 'test issue title'
fill_in :'issue[description]', with: prior_description
@@ -86,7 +104,13 @@ feature 'issuable templates', feature: true, js: true do
let(:merge_request) { create(:merge_request, :with_diffs, source_project: project) }
background do
- project.repository.commit_file(user, '.gitlab/merge_request_templates/feature-proposal.md', template_content, 'added merge request template', 'master', false)
+ project.repository.commit_file(
+ user,
+ '.gitlab/merge_request_templates/feature-proposal.md',
+ template_content,
+ message: 'added merge request template',
+ branch_name: 'master',
+ update: false)
visit edit_namespace_project_merge_request_path project.namespace, project, merge_request
fill_in :'merge_request[title]', with: 'test merge request title'
end
@@ -111,7 +135,13 @@ feature 'issuable templates', feature: true, js: true do
fork_project.team << [fork_user, :master]
create(:forked_project_link, forked_to_project: fork_project, forked_from_project: project)
login_as fork_user
- project.repository.commit_file(fork_user, '.gitlab/merge_request_templates/feature-proposal.md', template_content, 'added merge request template', 'master', false)
+ project.repository.commit_file(
+ fork_user,
+ '.gitlab/merge_request_templates/feature-proposal.md',
+ template_content,
+ message: 'added merge request template',
+ branch_name: 'master',
+ update: false)
visit edit_namespace_project_merge_request_path project.namespace, project, merge_request
fill_in :'merge_request[title]', with: 'test merge request title'
end
diff --git a/spec/features/projects/labels/update_prioritization_spec.rb b/spec/features/projects/labels/update_prioritization_spec.rb
index c9fa8315e79..97ce9cdfd87 100644
--- a/spec/features/projects/labels/update_prioritization_spec.rb
+++ b/spec/features/projects/labels/update_prioritization_spec.rb
@@ -20,7 +20,7 @@ feature 'Prioritize labels', feature: true do
scenario 'user can prioritize a group label', js: true do
visit namespace_project_labels_path(project.namespace, project)
- expect(page).to have_content('No prioritized labels yet')
+ expect(page).to have_content('Star labels to start sorting by priority')
page.within('.other-labels') do
all('.js-toggle-priority')[1].click
@@ -29,7 +29,7 @@ feature 'Prioritize labels', feature: true do
end
page.within('.prioritized-labels') do
- expect(page).not_to have_content('No prioritized labels yet')
+ expect(page).not_to have_content('Star labels to start sorting by priority')
expect(page).to have_content('feature')
end
end
@@ -55,7 +55,7 @@ feature 'Prioritize labels', feature: true do
scenario 'user can prioritize a project label', js: true do
visit namespace_project_labels_path(project.namespace, project)
- expect(page).to have_content('No prioritized labels yet')
+ expect(page).to have_content('Star labels to start sorting by priority')
page.within('.other-labels') do
first('.js-toggle-priority').click
@@ -64,7 +64,7 @@ feature 'Prioritize labels', feature: true do
end
page.within('.prioritized-labels') do
- expect(page).not_to have_content('No prioritized labels yet')
+ expect(page).not_to have_content('Star labels to start sorting by priority')
expect(page).to have_content('bug')
end
end
diff --git a/spec/features/projects/merge_request_button_spec.rb b/spec/features/projects/merge_request_button_spec.rb
new file mode 100644
index 00000000000..b6728960fb8
--- /dev/null
+++ b/spec/features/projects/merge_request_button_spec.rb
@@ -0,0 +1,108 @@
+require 'spec_helper'
+
+feature 'Merge Request button', feature: true do
+ shared_examples 'Merge Request button only shown when allowed' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :public) }
+ let(:forked_project) { create(:project, :public, forked_from_project: project) }
+
+ context 'not logged in' do
+ it 'does not show Create Merge Request button' do
+ visit url
+
+ within("#content-body") do
+ expect(page).not_to have_link(label)
+ end
+ end
+ end
+
+ context 'logged in as developer' do
+ before do
+ login_as(user)
+ project.team << [user, :developer]
+ end
+
+ it 'shows Create Merge Request button' do
+ href = new_namespace_project_merge_request_path(project.namespace,
+ project,
+ merge_request: { source_branch: 'feature',
+ target_branch: 'master' })
+
+ visit url
+
+ within("#content-body") do
+ expect(page).to have_link(label, href: href)
+ end
+ end
+
+ context 'merge requests are disabled' do
+ before do
+ project.project_feature.update!(merge_requests_access_level: ProjectFeature::DISABLED)
+ end
+
+ it 'does not show Create Merge Request button' do
+ visit url
+
+ within("#content-body") do
+ expect(page).not_to have_link(label)
+ end
+ end
+ end
+ end
+
+ context 'logged in as non-member' do
+ before do
+ login_as(user)
+ end
+
+ it 'does not show Create Merge Request button' do
+ visit url
+
+ within("#content-body") do
+ expect(page).not_to have_link(label)
+ end
+ end
+
+ context 'on own fork of project' do
+ let(:user) { forked_project.owner }
+
+ it 'shows Create Merge Request button' do
+ href = new_namespace_project_merge_request_path(forked_project.namespace,
+ forked_project,
+ merge_request: { source_branch: 'feature',
+ target_branch: 'master' })
+
+ visit fork_url
+
+ within("#content-body") do
+ expect(page).to have_link(label, href: href)
+ end
+ end
+ end
+ end
+ end
+
+ 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) }
+ end
+ end
+
+ context 'on compare page' do
+ it_behaves_like 'Merge Request button only shown when allowed' do
+ let(:label) { 'Create Merge Request' }
+ let(:url) { namespace_project_compare_path(project.namespace, project, from: 'master', to: 'feature') }
+ let(:fork_url) { namespace_project_compare_path(forked_project.namespace, forked_project, from: 'master', to: 'feature') }
+ end
+ end
+
+ context 'on commits page' do
+ it_behaves_like 'Merge Request button only shown when allowed' do
+ let(:label) { 'Create Merge Request' }
+ let(:url) { namespace_project_commits_path(project.namespace, project, 'feature') }
+ let(:fork_url) { namespace_project_commits_path(forked_project.namespace, forked_project, 'feature') }
+ end
+ end
+end
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index abfc46601fb..b56e562b2b6 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -1,11 +1,13 @@
require "spec_helper"
feature "New project", feature: true do
- context "Visibility level selector" do
- let(:user) { create(:admin) }
+ let(:user) { create(:admin) }
- before { login_as(user) }
+ before do
+ login_as(user)
+ end
+ context "Visibility level selector" do
Gitlab::VisibilityLevel.options.each do |key, level|
it "sets selector to #{key}" do
stub_application_setting(default_project_visibility: level)
@@ -16,4 +18,16 @@ feature "New project", feature: true do
end
end
end
+
+ context 'Import project options' do
+ before do
+ visit new_project_path
+ end
+
+ it 'does not autocomplete sensitive git repo URL' do
+ autocomplete = find('#project_import_url')['autocomplete']
+
+ expect(autocomplete).to eq('off')
+ end
+ end
end
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index e673ece37c3..0b5ccc8c515 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -66,8 +66,8 @@ describe 'Pipeline', :feature, :js do
context 'when pipeline has running builds' do
it 'shows a running icon and a cancel action for the running build' do
page.within('#ci-badge-deploy') do
- expect(page).to have_selector('.ci-status-icon-running')
- expect(page).to have_selector('.ci-action-icon-container .fa-ban')
+ expect(page).to have_selector('.js-ci-status-icon-running')
+ expect(page).to have_selector('.js-icon-action-cancel')
expect(page).to have_content('deploy')
end
end
@@ -82,63 +82,63 @@ describe 'Pipeline', :feature, :js do
context 'when pipeline has successful builds' do
it 'shows the success icon and a retry action for the successful build' do
page.within('#ci-badge-build') do
- expect(page).to have_selector('.ci-status-icon-success')
+ expect(page).to have_selector('.js-ci-status-icon-success')
expect(page).to have_content('build')
end
page.within('#ci-badge-build .ci-action-icon-container') do
- expect(page).to have_selector('.ci-action-icon-container .fa-refresh')
+ expect(page).to have_selector('.js-icon-action-retry')
end
end
- it 'should be possible to retry the success build' do
+ it 'should be possible to retry the success job' do
find('#ci-badge-build .ci-action-icon-container').trigger('click')
- expect(page).not_to have_content('Retry build')
+ expect(page).not_to have_content('Retry job')
end
end
context 'when pipeline has failed builds' do
it 'shows the failed icon and a retry action for the failed build' do
page.within('#ci-badge-test') do
- expect(page).to have_selector('.ci-status-icon-failed')
+ expect(page).to have_selector('.js-ci-status-icon-failed')
expect(page).to have_content('test')
end
page.within('#ci-badge-test .ci-action-icon-container') do
- expect(page).to have_selector('.ci-action-icon-container .fa-refresh')
+ expect(page).to have_selector('.js-icon-action-retry')
end
end
it 'should be possible to retry the failed build' do
find('#ci-badge-test .ci-action-icon-container').trigger('click')
- expect(page).not_to have_content('Retry build')
+ expect(page).not_to have_content('Retry job')
end
end
- context 'when pipeline has manual builds' do
+ context 'when pipeline has manual jobs' do
it 'shows the skipped icon and a play action for the manual build' do
page.within('#ci-badge-manual-build') do
- expect(page).to have_selector('.ci-status-icon-manual')
+ expect(page).to have_selector('.js-ci-status-icon-manual')
expect(page).to have_content('manual')
end
page.within('#ci-badge-manual-build .ci-action-icon-container') do
- expect(page).to have_selector('.ci-action-icon-container .fa-play')
+ expect(page).to have_selector('.js-icon-action-play')
end
end
- it 'should be possible to play the manual build' do
+ it 'should be possible to play the manual job' do
find('#ci-badge-manual-build .ci-action-icon-container').trigger('click')
- expect(page).not_to have_content('Play build')
+ expect(page).not_to have_content('Play job')
end
end
- context 'when pipeline has external build' do
+ context 'when pipeline has external job' do
it 'shows the success icon and the generic comit status build' do
- expect(page).to have_selector('.ci-status-icon-success')
+ expect(page).to have_selector('.js-ci-status-icon-success')
expect(page).to have_content('jenkins')
expect(page).to have_link('jenkins', href: 'http://gitlab.com/status')
end
@@ -146,12 +146,12 @@ describe 'Pipeline', :feature, :js do
end
context 'page tabs' do
- it 'shows Pipeline and Builds tabs with link' do
+ it 'shows Pipeline and Jobs tabs with link' do
expect(page).to have_link('Pipeline')
- expect(page).to have_link('Builds')
+ expect(page).to have_link('Jobs')
end
- it 'shows counter in Builds tab' do
+ it 'shows counter in Jobs tab' do
expect(page.find('.js-builds-counter').text).to eq(pipeline.statuses.count.to_s)
end
@@ -160,7 +160,7 @@ describe 'Pipeline', :feature, :js do
end
end
- context 'retrying builds' do
+ context 'retrying jobs' do
it { expect(page).not_to have_content('retried') }
context 'when retrying' do
@@ -170,7 +170,7 @@ describe 'Pipeline', :feature, :js do
end
end
- context 'canceling builds' do
+ context 'canceling jobs' do
it { expect(page).not_to have_selector('.ci-canceled') }
context 'when canceling' do
@@ -191,7 +191,7 @@ describe 'Pipeline', :feature, :js do
visit builds_namespace_project_pipeline_path(project.namespace, project, pipeline)
end
- it 'shows a list of builds' do
+ it 'shows a list of jobs' do
expect(page).to have_content('Test')
expect(page).to have_content(build_passed.id)
expect(page).to have_content('Deploy')
@@ -203,26 +203,26 @@ describe 'Pipeline', :feature, :js do
expect(page).to have_link('Play')
end
- it 'shows Builds tab pane as active' do
+ it 'shows jobs tab pane as active' do
expect(page).to have_css('#js-tab-builds.active')
end
context 'page tabs' do
- it 'shows Pipeline and Builds tabs with link' do
+ it 'shows Pipeline and Jobs tabs with link' do
expect(page).to have_link('Pipeline')
- expect(page).to have_link('Builds')
+ expect(page).to have_link('Jobs')
end
- it 'shows counter in Builds tab' do
+ it 'shows counter in Jobs tab' do
expect(page.find('.js-builds-counter').text).to eq(pipeline.statuses.count.to_s)
end
- it 'shows Builds tab as active' do
+ it 'shows Jobs tab as active' do
expect(page).to have_css('li.js-builds-tab-link.active')
end
end
- context 'retrying builds' do
+ context 'retrying jobs' do
it { expect(page).not_to have_content('retried') }
context 'when retrying' do
@@ -233,7 +233,7 @@ describe 'Pipeline', :feature, :js do
end
end
- context 'canceling builds' do
+ context 'canceling jobs' do
it { expect(page).not_to have_selector('.ci-canceled') }
context 'when canceling' do
@@ -244,7 +244,7 @@ describe 'Pipeline', :feature, :js do
end
end
- context 'playing manual build' do
+ context 'playing manual job' do
before do
within '.pipeline-holder' do
click_link('Play')
diff --git a/spec/features/projects/project_settings_spec.rb b/spec/features/projects/project_settings_spec.rb
index 55d5d082c6e..5d0314d5c09 100644
--- a/spec/features/projects/project_settings_spec.rb
+++ b/spec/features/projects/project_settings_spec.rb
@@ -37,7 +37,7 @@ describe 'Edit Project Settings', feature: true do
it 'shows errors for invalid project path/name' do
visit edit_namespace_project_path(project.namespace, project)
- fill_in 'Project name', with: 'foo&bar'
+ fill_in 'project_name', with: 'foo&bar'
fill_in 'Path', with: 'foo&bar'
click_button 'Rename project'
@@ -53,7 +53,7 @@ describe 'Edit Project Settings', feature: true do
it 'shows error for invalid project name' do
visit edit_namespace_project_path(project.namespace, project)
- fill_in 'Project name', with: '🚀 foo bar ☁️'
+ fill_in 'project_name', with: '🚀 foo bar ☁️'
click_button 'Rename project'
diff --git a/spec/features/projects/ref_switcher_spec.rb b/spec/features/projects/ref_switcher_spec.rb
index 472491188c9..38fe2d92885 100644
--- a/spec/features/projects/ref_switcher_spec.rb
+++ b/spec/features/projects/ref_switcher_spec.rb
@@ -17,14 +17,15 @@ feature 'Ref switcher', feature: true, js: true do
page.within '.project-refs-form' do
input = find('input[type="search"]')
- input.set 'expand'
+ input.set 'binary'
+ wait_for_ajax
input.native.send_keys :down
input.native.send_keys :down
input.native.send_keys :enter
end
- expect(page).to have_title 'expand-collapse-files'
+ expect(page).to have_title 'binary-encoding'
end
it "user selects ref with special characters" do
diff --git a/spec/features/projects/services/mattermost_slash_command_spec.rb b/spec/features/projects/services/mattermost_slash_command_spec.rb
index 86a07b2c679..042a1ccab51 100644
--- a/spec/features/projects/services/mattermost_slash_command_spec.rb
+++ b/spec/features/projects/services/mattermost_slash_command_spec.rb
@@ -99,6 +99,15 @@ feature 'Setup Mattermost slash commands', feature: true do
expect(select_element.all('option').count).to eq(3)
end
+ it 'shows an error alert with the error message if there is an error requesting teams' do
+ allow_any_instance_of(MattermostSlashCommandsService).to receive(:list_teams) { [[], 'test mattermost error message'] }
+
+ click_link 'Add to Mattermost'
+
+ expect(page).to have_selector('.alert')
+ expect(page).to have_content('test mattermost error message')
+ end
+
def stub_teams(count: 0)
teams = create_teams(count)
diff --git a/spec/features/projects/settings/merge_requests_settings_spec.rb b/spec/features/projects/settings/merge_requests_settings_spec.rb
index 4bfaa499272..034b75c2e51 100644
--- a/spec/features/projects/settings/merge_requests_settings_spec.rb
+++ b/spec/features/projects/settings/merge_requests_settings_spec.rb
@@ -11,41 +11,41 @@ feature 'Project settings > Merge Requests', feature: true, js: true do
login_as(user)
end
- context 'when Merge Request and Builds are initially enabled' do
+ context 'when Merge Request and Pipelines are initially enabled' do
before do
project.project_feature.update_attribute('merge_requests_access_level', ProjectFeature::ENABLED)
end
- context 'when Builds are initially enabled' do
+ context 'when Pipelines are initially enabled' do
before do
project.project_feature.update_attribute('builds_access_level', ProjectFeature::ENABLED)
visit edit_project_path(project)
end
scenario 'shows the Merge Requests settings' do
- expect(page).to have_content('Only allow merge requests to be merged if the build succeeds')
+ expect(page).to have_content('Only allow merge requests to be merged if the pipeline succeeds')
expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved')
select 'Disabled', from: "project_project_feature_attributes_merge_requests_access_level"
- expect(page).not_to have_content('Only allow merge requests to be merged if the build succeeds')
+ expect(page).not_to have_content('Only allow merge requests to be merged if the pipeline succeeds')
expect(page).not_to have_content('Only allow merge requests to be merged if all discussions are resolved')
end
end
- context 'when Builds are initially disabled' do
+ context 'when Pipelines are initially disabled' do
before do
project.project_feature.update_attribute('builds_access_level', ProjectFeature::DISABLED)
visit edit_project_path(project)
end
scenario 'shows the Merge Requests settings that do not depend on Builds feature' do
- expect(page).not_to have_content('Only allow merge requests to be merged if the build succeeds')
+ expect(page).not_to have_content('Only allow merge requests to be merged if the pipeline succeeds')
expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved')
select 'Everyone with access', from: "project_project_feature_attributes_builds_access_level"
- expect(page).to have_content('Only allow merge requests to be merged if the build succeeds')
+ expect(page).to have_content('Only allow merge requests to be merged if the pipeline succeeds')
expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved')
end
end
@@ -58,12 +58,12 @@ feature 'Project settings > Merge Requests', feature: true, js: true do
end
scenario 'does not show the Merge Requests settings' do
- expect(page).not_to have_content('Only allow merge requests to be merged if the build succeeds')
+ expect(page).not_to have_content('Only allow merge requests to be merged if the pipeline succeeds')
expect(page).not_to have_content('Only allow merge requests to be merged if all discussions are resolved')
select 'Everyone with access', from: "project_project_feature_attributes_merge_requests_access_level"
- expect(page).to have_content('Only allow merge requests to be merged if the build succeeds')
+ expect(page).to have_content('Only allow merge requests to be merged if the pipeline succeeds')
expect(page).to have_content('Only allow merge requests to be merged if all discussions are resolved')
end
end
diff --git a/spec/features/task_lists_spec.rb b/spec/features/task_lists_spec.rb
index abb27c90e0a..a5d14aa19f1 100644
--- a/spec/features/task_lists_spec.rb
+++ b/spec/features/task_lists_spec.rb
@@ -36,6 +36,19 @@ feature 'Task Lists', feature: true do
MARKDOWN
end
+ let(:nested_tasks_markdown) do
+ <<-EOT.strip_heredoc
+ - [ ] Task a
+ - [x] Task a.1
+ - [ ] Task a.2
+ - [ ] Task b
+
+ 1. [ ] Task 1
+ 1. [ ] Task 1.1
+ 1. [x] Task 1.2
+ EOT
+ end
+
before do
Warden.test_mode!
@@ -123,6 +136,35 @@ feature 'Task Lists', feature: true do
expect(page).to have_content("1 of 1 task completed")
end
end
+
+ describe 'nested tasks', js: true do
+ let(:issue) { create(:issue, description: nested_tasks_markdown, author: user, project: project) }
+
+ before { visit_issue(project, issue) }
+
+ it 'renders' do
+ expect(page).to have_selector('ul.task-list', count: 2)
+ expect(page).to have_selector('li.task-list-item', count: 7)
+ expect(page).to have_selector('ul input[checked]', count: 1)
+ expect(page).to have_selector('ol input[checked]', count: 1)
+ end
+
+ it 'solves tasks' do
+ expect(page).to have_content("2 of 7 tasks completed")
+
+ page.find('li.task-list-item', text: 'Task b').find('input').click
+ page.find('li.task-list-item ul li.task-list-item', text: 'Task a.2').find('input').click
+ page.find('li.task-list-item ol li.task-list-item', text: 'Task 1.1').find('input').click
+
+ expect(page).to have_content("5 of 7 tasks completed")
+
+ visit_issue(project, issue) # reload to see new system notes
+
+ expect(page).to have_content('marked the task Task b as complete')
+ expect(page).to have_content('marked the task Task a.2 as complete')
+ expect(page).to have_content('marked the task Task 1.1 as complete')
+ end
+ end
end
describe 'for Notes' do
@@ -236,7 +278,7 @@ feature 'Task Lists', feature: true do
expect(page).to have_content("2 of 6 tasks completed")
end
end
-
+
describe 'single incomplete task' do
let!(:merge) { create(:merge_request, :simple, description: singleIncompleteMarkdown, author: user, source_project: project) }
diff --git a/spec/features/todos/todos_spec.rb b/spec/features/todos/todos_spec.rb
index 3850e930b6d..1b352be9331 100644
--- a/spec/features/todos/todos_spec.rb
+++ b/spec/features/todos/todos_spec.rb
@@ -171,7 +171,7 @@ describe 'Dashboard Todos', feature: true do
it 'links to the pipelines for the merge request' do
href = pipelines_namespace_project_merge_request_path(project.namespace, project, todo.target)
- expect(page).to have_link "merge request #{todo.target.to_reference}", href
+ expect(page).to have_link "merge request #{todo.target.to_reference(full: true)}", href
end
end
end