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