summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock18
-rw-r--r--features/steps/dashboard/dashboard.rb83
-rw-r--r--features/steps/dashboard/todos.rb191
-rw-r--r--features/steps/profile/notifications.rb2
-rw-r--r--features/steps/project/merge_requests.rb12
-rw-r--r--features/steps/search.rb8
-rw-r--r--features/steps/shared/diff_note.rb6
-rw-r--r--features/support/capybara.rb26
-rw-r--r--spec/features/boards/sidebar_spec.rb4
-rw-r--r--spec/features/dashboard/active_tab_spec.rb2
-rw-r--r--spec/features/dashboard/group_spec.rb2
-rw-r--r--spec/features/dashboard/groups_list_spec.rb6
-rw-r--r--spec/features/dashboard/issues_spec.rb2
-rw-r--r--spec/features/dashboard/merge_requests_spec.rb2
-rw-r--r--spec/features/explore/new_menu_spec.rb10
-rw-r--r--spec/features/issues/filtered_search/recent_searches_spec.rb4
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb2
-rw-r--r--spec/features/issues_spec.rb2
-rw-r--r--spec/features/merge_requests/conflicts_spec.rb2
-rw-r--r--spec/features/merge_requests/diff_notes_avatars_spec.rb2
-rw-r--r--spec/features/merge_requests/diff_notes_resolve_spec.rb2
-rw-r--r--spec/features/merge_requests/mini_pipeline_graph_spec.rb2
-rw-r--r--spec/features/merge_requests/user_posts_diff_notes_spec.rb4
-rw-r--r--spec/features/merge_requests/versions_spec.rb4
-rw-r--r--spec/features/profiles/preferences_spec.rb2
-rw-r--r--spec/features/projects/branches_spec.rb4
-rw-r--r--spec/features/projects/group_links_spec.rb2
-rw-r--r--spec/features/projects/jobs_spec.rb2
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb12
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb12
-rw-r--r--spec/features/projects/services/jira_service_spec.rb2
-rw-r--r--spec/features/projects/wiki/markdown_preview_spec.rb6
-rw-r--r--spec/features/protected_branches_spec.rb2
-rw-r--r--spec/features/search_spec.rb8
-rw-r--r--spec/features/todos/todos_spec.rb355
-rw-r--r--spec/features/user_callout_spec.rb2
-rw-r--r--spec/support/capybara.rb27
-rw-r--r--spec/support/features/discussion_comments_shared_example.rb4
-rw-r--r--spec/support/protected_tags/access_control_ce_shared_examples.rb2
-rw-r--r--spec/support/quick_actions_helpers.rb2
-rw-r--r--spec/support/shared_examples/features/protected_branches_access_control_ce.rb2
-rw-r--r--spec/support/time_tracking_shared_examples.rb2
44 files changed, 739 insertions, 111 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index adde3400107..5d4def307c9 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,4 +1,4 @@
-image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.3-golang-1.8-git-2.7-phantomjs-2.1-node-7.1-postgresql-9.6"
+image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.3-golang-1.8-git-2.7-chrome-59.0-node-7.1-postgresql-9.6"
.default-cache: &default-cache
key: "ruby-233-with-yarn"
diff --git a/Gemfile b/Gemfile
index afea07ee6ff..012cc8679af 100644
--- a/Gemfile
+++ b/Gemfile
@@ -333,7 +333,7 @@ group :development, :test do
gem 'capybara', '~> 2.6.2'
gem 'capybara-screenshot', '~> 1.0.0'
- gem 'poltergeist', '~> 1.9.0'
+ gem 'selenium-webdriver', '~> 2.53'
gem 'spring', '~> 2.0.0'
gem 'spring-commands-rspec', '~> 1.0.4'
diff --git a/Gemfile.lock b/Gemfile.lock
index 05a70704513..61d8b23d9fc 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -113,12 +113,13 @@ GEM
mime-types (>= 1.16)
cause (0.1)
charlock_holmes (0.7.3)
+ childprocess (0.7.0)
+ ffi (~> 1.0, >= 1.0.11)
chronic (0.10.2)
chronic_duration (0.10.6)
numerizer (~> 0.1.1)
chunky_png (1.3.5)
citrus (3.0.2)
- cliver (0.3.2)
coderay (1.1.1)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
@@ -583,11 +584,6 @@ GEM
pg (0.18.4)
po_to_json (1.0.1)
json (>= 1.6.0)
- poltergeist (1.9.0)
- capybara (~> 2.1)
- cliver (~> 0.3.1)
- multi_json (~> 1.0)
- websocket-driver (>= 0.2.0)
posix-spawn (0.3.11)
powerpack (0.1.1)
premailer (1.10.4)
@@ -774,6 +770,10 @@ GEM
activesupport (>= 3.1)
select2-rails (3.5.9.3)
thor (~> 0.14)
+ selenium-webdriver (2.53.4)
+ childprocess (~> 0.5)
+ rubyzip (~> 1.0)
+ websocket (~> 1.0)
sentry-raven (2.5.3)
faraday (>= 0.7.6, < 1.0)
settingslogic (2.0.9)
@@ -895,9 +895,7 @@ GEM
hashdiff
webpack-rails (0.9.10)
railties (>= 3.2.0)
- websocket-driver (0.6.3)
- websocket-extensions (>= 0.1.0)
- websocket-extensions (0.1.2)
+ websocket (1.2.4)
wikicloth (0.8.1)
builder
expression_parser
@@ -1048,7 +1046,6 @@ DEPENDENCIES
peek-redis (~> 1.2.0)
peek-sidekiq (~> 1.0.3)
pg (~> 0.18.2)
- poltergeist (~> 1.9.0)
premailer-rails (~> 1.9.7)
prometheus-client-mmap (~> 0.7.0.beta11)
pry-byebug (~> 3.4.1)
@@ -1090,6 +1087,7 @@ DEPENDENCIES
scss_lint (~> 0.54.0)
seed-fu (~> 2.3.5)
select2-rails (~> 3.5.9)
+ selenium-webdriver (~> 2.53)
sentry-raven (~> 2.5.3)
settingslogic (~> 2.0.9)
sham_rack (~> 1.3.6)
diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb
new file mode 100644
index 00000000000..e221a550882
--- /dev/null
+++ b/features/steps/dashboard/dashboard.rb
@@ -0,0 +1,83 @@
+class Spinach::Features::Dashboard < Spinach::FeatureSteps
+ include SharedAuthentication
+ include SharedPaths
+ include SharedProject
+ include SharedIssuable
+
+ step 'I should see "New Project" link' do
+ expect(page).to have_link "New project"
+ end
+
+ step 'I should see "Shop" project link' do
+ expect(page).to have_link "Shop"
+ end
+
+ step 'I should see "Shop" project CI status' do
+ expect(page).to have_link "Commit: skipped"
+ end
+
+ step 'I should see last push widget' do
+ expect(page).to have_content "You pushed to fix"
+ expect(page).to have_link "Create merge request"
+ end
+
+ step 'I click "Create merge request" link' do
+ find_link("Create merge request", visible: false).click
+ end
+
+ step 'I see prefilled new Merge Request page' do
+ expect(page).to have_selector('.merge-request-form')
+ expect(current_path).to eq new_namespace_project_merge_request_path(@project.namespace, @project)
+ expect(find("#merge_request_target_project_id").value).to eq @project.id.to_s
+ expect(find("input#merge_request_source_branch").value).to eq "fix"
+ expect(find("input#merge_request_target_branch").value).to eq "master"
+ end
+
+ step 'I have group with projects' do
+ @group = create(:group)
+ @project = create(:empty_project, namespace: @group)
+ @event = create(:closed_issue_event, project: @project)
+
+ @project.team << [current_user, :master]
+ end
+
+ step 'I should see projects list' do
+ @user.authorized_projects.all.each do |project|
+ expect(page).to have_link project.name_with_namespace
+ end
+ end
+
+ step 'I should see groups list' do
+ Group.all.each do |group|
+ expect(page).to have_link group.name
+ end
+ end
+
+ step 'group has a projects that does not belongs to me' do
+ @forbidden_project1 = create(:empty_project, group: @group)
+ @forbidden_project2 = create(:empty_project, group: @group)
+ end
+
+ step 'I should see 1 project at group list' do
+ expect(find('span.last_activity/span')).to have_content('1')
+ end
+
+ step 'I filter the list by label "feature"' do
+ page.within ".labels-filter" do
+ find('.dropdown').click
+ click_link "feature"
+ end
+ end
+
+ step 'I should see "Bugfix1" in issues list' do
+ page.within "ul.content-list" do
+ expect(page).to have_content "Bugfix1"
+ end
+ end
+
+ step 'project "Shop" has issue "Bugfix1" with label "feature"' do
+ project = Project.find_by(name: "Shop")
+ issue = create(:issue, title: "Bugfix1", project: project, assignees: [current_user])
+ issue.labels << project.labels.find_by(title: 'feature')
+ end
+end
diff --git a/features/steps/dashboard/todos.rb b/features/steps/dashboard/todos.rb
new file mode 100644
index 00000000000..0b4a69b2a91
--- /dev/null
+++ b/features/steps/dashboard/todos.rb
@@ -0,0 +1,191 @@
+class Spinach::Features::DashboardTodos < Spinach::FeatureSteps
+ include SharedAuthentication
+ include SharedPaths
+ include SharedProject
+ include SharedUser
+ include WaitForRequests
+
+ step '"John Doe" is a developer of project "Shop"' do
+ project.team << [john_doe, :developer]
+ end
+
+ step 'I am a developer of project "Enterprise"' do
+ enterprise.team << [current_user, :developer]
+ end
+
+ step '"Mary Jane" is a developer of project "Shop"' do
+ project.team << [john_doe, :developer]
+ end
+
+ step 'I have todos' do
+ create(:todo, user: current_user, project: project, author: mary_jane, target: issue, action: Todo::MENTIONED)
+ create(:todo, user: current_user, project: project, author: john_doe, target: issue, action: Todo::ASSIGNED)
+ note = create(:note, author: john_doe, noteable: issue, note: "#{current_user.to_reference} Wdyt?", project: project)
+ create(:todo, user: current_user, project: project, author: john_doe, target: issue, action: Todo::MENTIONED, note: note)
+ create(:todo, user: current_user, project: project, author: john_doe, target: merge_request, action: Todo::ASSIGNED)
+ end
+
+ step 'I should see todos assigned to me' do
+ merge_request_reference = merge_request.to_reference(full: true)
+ issue_reference = issue.to_reference(full: true)
+
+ page.within('.todos-count') { expect(page).to have_content '4' }
+ expect(page).to have_content 'To do 4'
+ expect(page).to have_content 'Done 0'
+
+ expect(page).to have_link project.name_with_namespace
+ should_see_todo(1, "John Doe assigned you merge request #{merge_request_reference}", merge_request.title)
+ should_see_todo(2, "John Doe mentioned you on issue #{issue_reference}", "#{current_user.to_reference} Wdyt?")
+ should_see_todo(3, "John Doe assigned you issue #{issue_reference}", issue.title)
+ should_see_todo(4, "Mary Jane mentioned you on issue #{issue_reference}", issue.title)
+ end
+
+ step 'I mark the todo as done' do
+ page.within('.todo:nth-child(1)') do
+ click_link 'Done'
+ end
+
+ page.within('.todos-count') { expect(page).to have_content '3' }
+ expect(page).to have_content 'To do 3'
+ expect(page).to have_content 'Done 1'
+ should_see_todo(1, "John Doe assigned you merge request #{merge_request.to_reference(full: true)}", merge_request.title, state: :done_reversible)
+ end
+
+ step 'I mark all todos as done' do
+ merge_request_reference = merge_request.to_reference(full: true)
+ issue_reference = issue.to_reference(full: true)
+
+ find('.js-todos-mark-all').click
+
+ page.within('.todos-count') { expect(page).to have_content '0' }
+ expect(page).to have_content 'To do 0'
+ expect(page).to have_content 'Done 4'
+ expect(page).to have_content "You're all done!"
+ expect('.prepend-top-default').not_to have_link project.name_with_namespace
+ should_not_see_todo "John Doe assigned you merge request #{merge_request_reference}"
+ should_not_see_todo "John Doe mentioned you on issue #{issue_reference}"
+ should_not_see_todo "John Doe assigned you issue #{issue_reference}"
+ should_not_see_todo "Mary Jane mentioned you on issue #{issue_reference}"
+ end
+
+ step 'I should see the todo marked as done' do
+ find('.todos-done a').click
+
+ expect(page).to have_link project.name_with_namespace
+ should_see_todo(1, "John Doe assigned you merge request #{merge_request.to_reference(full: true)}", merge_request.title, state: :done_irreversible)
+ end
+
+ step 'I should see all todos marked as done' do
+ merge_request_reference = merge_request.to_reference(full: true)
+ issue_reference = issue.to_reference(full: true)
+
+ find('.todos-done a').click
+
+ expect(page).to have_link project.name_with_namespace
+ should_see_todo(1, "John Doe assigned you merge request #{merge_request_reference}", merge_request.title, state: :done_irreversible)
+ should_see_todo(2, "John Doe mentioned you on issue #{issue_reference}", "#{current_user.to_reference} Wdyt?", state: :done_irreversible)
+ should_see_todo(3, "John Doe assigned you issue #{issue_reference}", issue.title, state: :done_irreversible)
+ should_see_todo(4, "Mary Jane mentioned you on issue #{issue_reference}", issue.title, state: :done_irreversible)
+ end
+
+ step 'I filter by "Enterprise"' do
+ click_button 'Project'
+ page.within '.dropdown-menu-project' do
+ click_link enterprise.name_with_namespace
+ end
+ end
+
+ step 'I filter by "John Doe"' do
+ click_button 'Author'
+ page.within '.dropdown-menu-author' do
+ click_link john_doe.username
+ end
+ end
+
+ step 'I filter by "Issue"' do
+ click_button 'Type'
+ page.within '.dropdown-menu-type' do
+ click_link 'Issue'
+ end
+ end
+
+ step 'I filter by "Mentioned"' do
+ click_button 'Action'
+ page.within '.dropdown-menu-action' do
+ click_link 'Mentioned'
+ end
+ end
+
+ step 'I should not see todos' do
+ expect(page).to have_content "You're all done!"
+ end
+
+ step 'I should not see todos related to "Mary Jane" in the list' do
+ should_not_see_todo "Mary Jane mentioned you on issue #{issue.to_reference(full: true)}"
+ end
+
+ step 'I should not see todos related to "Merge Requests" in the list' do
+ should_not_see_todo "John Doe assigned you merge request #{merge_request.to_reference(full: true)}"
+ end
+
+ step 'I should not see todos related to "Assignments" in the list' do
+ should_not_see_todo "John Doe assigned you merge request #{merge_request.to_reference(full: true)}"
+ should_not_see_todo "John Doe assigned you issue #{issue.to_reference(full: true)}"
+ end
+
+ step 'I click on the todo' do
+ find('.todo:nth-child(1)').click
+ end
+
+ step 'I should be directed to the corresponding page' do
+ page.should have_css('.identifier', text: 'Merge request !1')
+ # Merge request page loads and issues a number of Ajax requests
+ wait_for_requests
+ end
+
+ def should_see_todo(position, title, body, state: :pending)
+ page.within(".todo:nth-child(#{position})") do
+ expect(page).to have_content title
+ expect(page).to have_content body
+
+ if state == :pending
+ expect(page).to have_link 'Done'
+ elsif state == :done_reversible
+ expect(page).to have_link 'Undo'
+ elsif state == :done_irreversible
+ expect(page).not_to have_link 'Undo'
+ expect(page).not_to have_link 'Done'
+ else
+ raise 'Invalid state given, valid states: :pending, :done_reversible, :done_irreversible'
+ end
+ end
+ end
+
+ def should_not_see_todo(title)
+ expect(page).not_to have_visible_content title
+ end
+
+ def have_visible_content(text)
+ have_css('*', text: text, visible: true)
+ end
+
+ def john_doe
+ @john_doe ||= user_exists("John Doe", { username: "john_doe" })
+ end
+
+ def mary_jane
+ @mary_jane ||= user_exists("Mary Jane", { username: "mary_jane" })
+ end
+
+ def enterprise
+ @enterprise ||= Project.find_by(name: 'Enterprise')
+ end
+
+ def issue
+ @issue ||= create(:issue, assignees: [current_user], project: project)
+ end
+
+ def merge_request
+ @merge_request ||= create(:merge_request, assignee: current_user, source_project: project)
+ end
+end
diff --git a/features/steps/profile/notifications.rb b/features/steps/profile/notifications.rb
index 7e339443b75..f8eb0f01de8 100644
--- a/features/steps/profile/notifications.rb
+++ b/features/steps/profile/notifications.rb
@@ -11,7 +11,7 @@ class Spinach::Features::ProfileNotifications < Spinach::FeatureSteps
end
step 'I select Mention setting from dropdown' do
- first(:link, "On mention").trigger('click')
+ first(:link, "On mention").click
end
step 'I should see Notification saved message' do
diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb
index 810cd75591b..d6c1c73ae83 100644
--- a/features/steps/project/merge_requests.rb
+++ b/features/steps/project/merge_requests.rb
@@ -34,7 +34,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
end
step 'I click link "Merged"' do
- find('#state-merged').trigger('click')
+ find('#state-merged').click
end
step 'I click link "Closed"' do
@@ -336,7 +336,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
step 'I click on the Discussion tab' do
page.within '.merge-request-tabs' do
- find('.notes-tab').trigger('click')
+ find('.notes-tab').click
end
# Waits for load
@@ -420,7 +420,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
end
step 'I click link "Reopen"' do
- first(:css, '.reopen-mr-link').trigger('click')
+ first(:css, '.reopen-mr-link').click
end
step 'I should see reopened merge request "Bug NS-04"' do
@@ -432,13 +432,13 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
step 'I click link "Hide inline discussion" of the third file' do
page.within '.files>div:nth-child(3)' do
- find('.js-toggle-diff-comments').trigger('click')
+ find('.js-toggle-diff-comments').click
end
end
step 'I click link "Show inline discussion" of the third file' do
page.within '.files>div:nth-child(3)' do
- find('.js-toggle-diff-comments').trigger('click')
+ find('.js-toggle-diff-comments').click
end
end
@@ -510,7 +510,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
end
step 'I click Side-by-side Diff tab' do
- find('a', text: 'Side-by-side').trigger('click')
+ find('a', text: 'Side-by-side').click
# Waits for load
expect(page).to have_css('.parallel')
diff --git a/features/steps/search.rb b/features/steps/search.rb
index 16c4a5ab2e4..2f1b8cc0156 100644
--- a/features/steps/search.rb
+++ b/features/steps/search.rb
@@ -10,12 +10,12 @@ class Spinach::Features::Search < Spinach::FeatureSteps
step 'I search for "Foo"' do
fill_in "dashboard_search", with: "Foo"
- find('.btn-search').trigger('click')
+ find('.btn-search').click
end
step 'I search for "rspec"' do
fill_in "dashboard_search", with: "rspec"
- find('.btn-search').trigger('click')
+ find('.btn-search').click
end
step 'I search for "rspec" on project page' do
@@ -25,7 +25,7 @@ class Spinach::Features::Search < Spinach::FeatureSteps
step 'I search for "Wiki content"' do
fill_in "dashboard_search", with: "content"
- find('.btn-search').trigger('click')
+ find('.btn-search').click
end
step 'I click "Issues" link' do
@@ -35,7 +35,7 @@ class Spinach::Features::Search < Spinach::FeatureSteps
end
step 'I click project "Shop" link' do
- find('.js-search-project-dropdown').trigger('click')
+ find('.js-search-project-dropdown').click
page.within '.project-filter' do
click_link project.name_with_namespace
end
diff --git a/features/steps/shared/diff_note.rb b/features/steps/shared/diff_note.rb
index 2c59ec5bb06..312187cbd0f 100644
--- a/features/steps/shared/diff_note.rb
+++ b/features/steps/shared/diff_note.rb
@@ -215,7 +215,7 @@ module SharedDiffNote
end
step 'I click side-by-side diff button' do
- find('#parallel-diff-btn').trigger('click')
+ find('#parallel-diff-btn').click
end
step 'I see side-by-side diff button' do
@@ -228,11 +228,11 @@ module SharedDiffNote
def click_diff_line(code)
find(".line_holder[id='#{code}'] td:nth-of-type(1)").trigger 'mouseover'
- find(".line_holder[id='#{code}'] button").trigger 'click'
+ find(".line_holder[id='#{code}'] button").click
end
def click_parallel_diff_line(code, line_type)
find(".line_holder.parallel .diff-line-num[id='#{code}']").trigger 'mouseover'
- find(".line_holder.parallel button[data-line-code='#{code}']").trigger 'click'
+ find(".line_holder.parallel button[data-line-code='#{code}']").click
end
end
diff --git a/features/support/capybara.rb b/features/support/capybara.rb
index f4691647d4b..595577804bd 100644
--- a/features/support/capybara.rb
+++ b/features/support/capybara.rb
@@ -1,22 +1,18 @@
-require 'capybara/poltergeist'
require 'capybara-screenshot/spinach'
# Give CI some extra time
timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 60 : 30
-Capybara.javascript_driver = :poltergeist
-Capybara.register_driver :poltergeist do |app|
- Capybara::Poltergeist::Driver.new(
- app,
- js_errors: true,
- timeout: timeout,
- window_size: [1366, 768],
- url_whitelist: %w[localhost 127.0.0.1],
- url_blacklist: %w[.mp4 .png .gif .avi .bmp .jpg .jpeg],
- phantomjs_options: [
- '--load-images=yes'
- ]
+Capybara.javascript_driver = :chrome
+Capybara.register_driver :chrome do |app|
+ capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
+ 'chromeOptions' => {
+ 'args' => %w[headless no-sandbox disable-gpu]
+ }
)
+
+ Capybara::Selenium::Driver
+ .new(app, browser: :chrome, desired_capabilities: capabilities)
end
Capybara.default_max_wait_time = timeout
@@ -24,6 +20,10 @@ Capybara.ignore_hidden_elements = false
# Keep only the screenshots generated from the last failing test suite
Capybara::Screenshot.prune_strategy = :keep_last_run
+# From https://github.com/mattheworiordan/capybara-screenshot/issues/84#issuecomment-41219326
+Capybara::Screenshot.register_driver(:chrome) do |driver, path|
+ driver.browser.save_screenshot(path)
+end
Spinach.hooks.before_run do
TestEnv.eager_load_driver_server
diff --git a/spec/features/boards/sidebar_spec.rb b/spec/features/boards/sidebar_spec.rb
index 3f58fe1c32c..9b3fb48046a 100644
--- a/spec/features/boards/sidebar_spec.rb
+++ b/spec/features/boards/sidebar_spec.rb
@@ -51,7 +51,7 @@ describe 'Issue Boards', js: true do
expect(page).to have_selector('.issue-boards-sidebar')
- find('.gutter-toggle').trigger('click')
+ find('.gutter-toggle').click
expect(page).not_to have_selector('.issue-boards-sidebar')
end
@@ -171,7 +171,7 @@ describe 'Issue Boards', js: true do
end
page.within(find('.board:nth-child(2)')) do
- find('.card:nth-child(2)').trigger('click')
+ find('.card:nth-child(2)').click
end
page.within('.assignee') do
diff --git a/spec/features/dashboard/active_tab_spec.rb b/spec/features/dashboard/active_tab_spec.rb
index 067e4337e6a..ee2554cbd48 100644
--- a/spec/features/dashboard/active_tab_spec.rb
+++ b/spec/features/dashboard/active_tab_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe 'Dashboard Active Tab', js: true do
shared_examples 'page has active tab' do |title|
it "#{title} tab" do
- find('.global-dropdown-toggle').trigger('click')
+ find('.global-dropdown-toggle').click
expect(page).to have_selector('.global-dropdown-menu li.active', count: 1)
expect(find('.global-dropdown-menu li.active')).to have_content(title)
end
diff --git a/spec/features/dashboard/group_spec.rb b/spec/features/dashboard/group_spec.rb
index 60a16830cdc..1c4699c3818 100644
--- a/spec/features/dashboard/group_spec.rb
+++ b/spec/features/dashboard/group_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe 'Dashboard Group' do
it 'creates new group', js: true do
visit dashboard_groups_path
- find('.btn-new').trigger('click')
+ find('.btn-new').click
new_path = 'Samurai'
new_description = 'Tokugawa Shogunate'
diff --git a/spec/features/dashboard/groups_list_spec.rb b/spec/features/dashboard/groups_list_spec.rb
index 533df7a325c..bb4f3d9ecb4 100644
--- a/spec/features/dashboard/groups_list_spec.rb
+++ b/spec/features/dashboard/groups_list_spec.rb
@@ -74,14 +74,14 @@ feature 'Dashboard Groups page', :js do
expect(page).not_to have_selector("#group-#{group.id} .fa-caret-right")
# Collapse
- find("#group-#{group.id}").trigger('click')
+ find("#group-#{group.id}").click
expect(page).not_to have_selector("#group-#{group.id} .fa-caret-down")
expect(page).to have_selector("#group-#{group.id} .fa-caret-right", count: 1)
expect(page).not_to have_selector("#group-#{group.id} #group-#{subgroup.id}")
# Expand
- find("#group-#{group.id}").trigger('click')
+ find("#group-#{group.id}").click
expect(page).to have_selector("#group-#{group.id} .fa-caret-down", count: 1)
expect(page).not_to have_selector("#group-#{group.id} .fa-caret-right")
@@ -115,7 +115,7 @@ feature 'Dashboard Groups page', :js do
expect(page).not_to have_selector("#group-#{group.id}")
# Go to next page
- find(".gl-pagination .page:not(.active) a").trigger('click')
+ find(".gl-pagination .page:not(.active) a").click
wait_for_requests
diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb
index 82adde6258f..a11499ba191 100644
--- a/spec/features/dashboard/issues_spec.rb
+++ b/spec/features/dashboard/issues_spec.rb
@@ -71,7 +71,7 @@ RSpec.describe 'Dashboard Issues' do
describe 'new issue dropdown' do
it 'shows projects only with issues feature enabled', js: true do
- find('.new-project-item-select-button').trigger('click')
+ find('.new-project-item-select-button').click
page.within('.select2-results') do
expect(page).to have_content(project.name_with_namespace)
diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb
index 42d6fadc0c1..a406cd89ead 100644
--- a/spec/features/dashboard/merge_requests_spec.rb
+++ b/spec/features/dashboard/merge_requests_spec.rb
@@ -24,7 +24,7 @@ feature 'Dashboard Merge Requests' do
end
it 'shows projects only with merge requests feature enabled', js: true do
- find('.new-project-item-select-button').trigger('click')
+ find('.new-project-item-select-button').click
page.within('.select2-results') do
expect(page).to have_content(project.name_with_namespace)
diff --git a/spec/features/explore/new_menu_spec.rb b/spec/features/explore/new_menu_spec.rb
index b1ccf80c28e..a4c4d336807 100644
--- a/spec/features/explore/new_menu_spec.rb
+++ b/spec/features/explore/new_menu_spec.rb
@@ -65,9 +65,9 @@ feature 'Top Plus Menu', :js do
visit project_path(project)
page.within '.header-content' do
- find('.header-new-dropdown-toggle').trigger('click')
+ find('.header-new-dropdown-toggle').click
expect(page).to have_selector('.header-new.dropdown.open', count: 1)
- find('.header-new-project-snippet a').trigger('click')
+ find('.header-new-project-snippet a').click
end
expect(page).to have_content('New Snippet')
@@ -87,9 +87,9 @@ feature 'Top Plus Menu', :js do
visit group_path(group)
page.within '.header-content' do
- find('.header-new-dropdown-toggle').trigger('click')
+ find('.header-new-dropdown-toggle').click
expect(page).to have_selector('.header-new.dropdown.open', count: 1)
- find('.header-new-group-project a').trigger('click')
+ find('.header-new-group-project a').click
end
expect(page).to have_content('Project path')
@@ -161,7 +161,7 @@ feature 'Top Plus Menu', :js do
def click_topmenuitem(item_name)
page.within '.header-content' do
- find('.header-new-dropdown-toggle').trigger('click')
+ find('.header-new-dropdown-toggle').click
expect(page).to have_selector('.header-new.dropdown.open', count: 1)
click_link item_name
end
diff --git a/spec/features/issues/filtered_search/recent_searches_spec.rb b/spec/features/issues/filtered_search/recent_searches_spec.rb
index 5842bb22beb..51c0be69abc 100644
--- a/spec/features/issues/filtered_search/recent_searches_spec.rb
+++ b/spec/features/issues/filtered_search/recent_searches_spec.rb
@@ -80,7 +80,7 @@ describe 'Recent searches', js: true do
set_recent_searches(project_1_local_storage_key, '["foo", "bar"]')
visit project_issues_path(project_1)
- all('.filtered-search-history-dropdown-item', visible: false)[0].trigger('click')
+ all('.filtered-search-history-dropdown-item', visible: false)[0].click
wait_for_filtered_search('foo')
expect(find('.filtered-search').value.strip).to eq('foo')
@@ -94,7 +94,7 @@ describe 'Recent searches', js: true do
expect(items_before.count).to eq(1)
- find('.filtered-search-history-clear-button', visible: false).trigger('click')
+ find('.filtered-search-history-clear-button', visible: false).click
items_after = all('.filtered-search-history-dropdown-item', visible: false)
expect(items_after.count).to eq(0)
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index 28f93cfd971..50aa5fbb790 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -170,7 +170,7 @@ feature 'Issue Sidebar' do
end
def open_issue_sidebar
- find('aside.right-sidebar.right-sidebar-collapsed .js-sidebar-toggle').trigger('click')
+ find('aside.right-sidebar.right-sidebar-collapsed .js-sidebar-toggle').click
find('aside.right-sidebar.right-sidebar-expanded')
end
end
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index 722237481ea..4f4bf189280 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -379,7 +379,7 @@ describe 'Issues' do
it 'changes incoming email address token', js: true do
find('.issue-email-modal-btn').click
previous_token = find('input#issue_email').value
- find('.incoming-email-token-reset').trigger('click')
+ find('.incoming-email-token-reset').click
wait_for_requests
diff --git a/spec/features/merge_requests/conflicts_spec.rb b/spec/features/merge_requests/conflicts_spec.rb
index 2c560632a1b..19a38afb410 100644
--- a/spec/features/merge_requests/conflicts_spec.rb
+++ b/spec/features/merge_requests/conflicts_spec.rb
@@ -23,7 +23,7 @@ feature 'Merge request conflict resolution', js: true do
within find('.files-wrapper .diff-file', text: 'files/ruby/regex.rb') do
all('button', text: 'Use ours').each do |button|
- button.trigger('click')
+ button.click
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 2d9419d6124..737045413bf 100644
--- a/spec/features/merge_requests/diff_notes_avatars_spec.rb
+++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb
@@ -150,7 +150,7 @@ feature 'Diff note avatars', js: true do
page.within '.js-discussion-note-form' do
find('.js-note-text').native.send_keys('Test')
- find('.js-comment-button').trigger 'click'
+ find('.js-comment-button').click
wait_for_requests
end
diff --git a/spec/features/merge_requests/diff_notes_resolve_spec.rb b/spec/features/merge_requests/diff_notes_resolve_spec.rb
index ac7f75bd308..5019ed43496 100644
--- a/spec/features/merge_requests/diff_notes_resolve_spec.rb
+++ b/spec/features/merge_requests/diff_notes_resolve_spec.rb
@@ -275,7 +275,7 @@ feature 'Diff notes resolve', js: true do
end
page.within '.line-resolve-all-container' do
- page.find('.discussion-next-btn').trigger('click')
+ page.find('.discussion-next-btn').click
end
expect(page.evaluate_script("$('body').scrollTop()")).to be > 0
diff --git a/spec/features/merge_requests/mini_pipeline_graph_spec.rb b/spec/features/merge_requests/mini_pipeline_graph_spec.rb
index b1215f9ba63..24abebb3995 100644
--- a/spec/features/merge_requests/mini_pipeline_graph_spec.rb
+++ b/spec/features/merge_requests/mini_pipeline_graph_spec.rb
@@ -90,7 +90,7 @@ feature 'Mini Pipeline Graph', :js do
end
it 'should close when toggle is clicked again' do
- toggle.trigger('click')
+ toggle.click
expect(toggle.find(:xpath, '..')).not_to have_selector('.mini-pipeline-graph-dropdown-menu')
end
diff --git a/spec/features/merge_requests/user_posts_diff_notes_spec.rb b/spec/features/merge_requests/user_posts_diff_notes_spec.rb
index 1cfd78663e5..24372244bd7 100644
--- a/spec/features/merge_requests/user_posts_diff_notes_spec.rb
+++ b/spec/features/merge_requests/user_posts_diff_notes_spec.rb
@@ -221,7 +221,7 @@ feature 'Merge requests > User posts diff notes', :js do
def should_allow_dismissing_a_comment(line_holder, diff_side = nil)
write_comment_on_line(line_holder, diff_side)
- find('.js-close-discussion-note-form').trigger('click')
+ find('.js-close-discussion-note-form').click
assert_comment_dismissal(line_holder)
end
@@ -259,7 +259,7 @@ feature 'Merge requests > User posts diff notes', :js do
expect(line[:num]).to have_css comment_button_class
- line[:num].find(comment_button_class).trigger 'click'
+ line[:num].find(comment_button_class).click
end
def write_comment_on_line(line_holder, diff_side)
diff --git a/spec/features/merge_requests/versions_spec.rb b/spec/features/merge_requests/versions_spec.rb
index 8e231fbc281..6669522dd7a 100644
--- a/spec/features/merge_requests/versions_spec.rb
+++ b/spec/features/merge_requests/versions_spec.rb
@@ -68,7 +68,7 @@ feature 'Merge Request versions', js: true do
page.within(diff_file_selector) do
find(".line_holder[id='#{line_code}'] td:nth-of-type(1)").trigger 'mouseover'
- find(".line_holder[id='#{line_code}'] button").trigger 'click'
+ find(".line_holder[id='#{line_code}'] button").click
page.within("form[data-line-code='#{line_code}']") do
fill_in "note[note]", with: "Typo, please fix"
@@ -138,7 +138,7 @@ feature 'Merge Request versions', js: true do
page.within(diff_file_selector) do
find(".line_holder[id='#{line_code}'] td:nth-of-type(1)").trigger 'mouseover'
- find(".line_holder[id='#{line_code}'] button").trigger 'click'
+ find(".line_holder[id='#{line_code}'] button").click
page.within("form[data-line-code='#{line_code}']") do
fill_in "note[note]", with: "Typo, please fix"
diff --git a/spec/features/profiles/preferences_spec.rb b/spec/features/profiles/preferences_spec.rb
index 9123aa9d155..3b57ff47d33 100644
--- a/spec/features/profiles/preferences_spec.rb
+++ b/spec/features/profiles/preferences_spec.rb
@@ -44,7 +44,7 @@ describe 'Profile > Preferences' do
expect(page.current_path).to eq starred_dashboard_projects_path
end
- find('.shortcuts-activity').trigger('click')
+ find('.shortcuts-activity').click
expect(page).not_to have_content("You don't have starred projects yet")
expect(page.current_path).to eq dashboard_projects_path
diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb
index ad4527a0b74..b7ceac79c40 100644
--- a/spec/features/projects/branches_spec.rb
+++ b/spec/features/projects/branches_spec.rb
@@ -93,7 +93,7 @@ describe 'Branches' do
expect(page).to have_content('fix')
expect(find('.all-branches')).to have_selector('li', count: 1)
- find('.js-branch-fix .btn-remove').trigger(:click)
+ find('.js-branch-fix .btn-remove').click
expect(page).not_to have_content('fix')
expect(find('.all-branches')).to have_selector('li', count: 0)
@@ -155,7 +155,7 @@ describe 'Branches' do
expect(page).to have_content('fix')
expect(find('.all-branches')).to have_selector('li', count: 1)
- page.find('[data-target="#modal-delete-branch"]').trigger(:click)
+ page.find('[data-target="#modal-delete-branch"]').click
expect(page).to have_css('.js-delete-branch[disabled]')
fill_in 'delete_branch_input', with: 'fix'
diff --git a/spec/features/projects/group_links_spec.rb b/spec/features/projects/group_links_spec.rb
index 698baad97ff..30800aae468 100644
--- a/spec/features/projects/group_links_spec.rb
+++ b/spec/features/projects/group_links_spec.rb
@@ -21,7 +21,7 @@ feature 'Project group links', :js do
select2 group.id, from: '#link_group_id'
fill_in 'expires_at_groups', with: (Time.current + 4.5.days).strftime('%Y-%m-%d')
page.find('body').click
- find('.btn-create').trigger('click')
+ find('.btn-create').click
end
it 'shows the expiration time with a warning class' do
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index 037ac00d39f..3fa32e2d10b 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -374,7 +374,7 @@ feature 'Jobs' do
job.run!
visit project_job_path(project, job)
find('.js-cancel-job').click()
- find('.js-retry-button').trigger('click')
+ find('.js-retry-button').click
end
it 'shows the right status and buttons', :js do
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index 0b626749275..45b1d482c8a 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -73,7 +73,7 @@ describe 'Pipeline', :js do
end
it 'should be possible to cancel the running build' do
- find('#ci-badge-deploy .ci-action-icon-container').trigger('click')
+ find('#ci-badge-deploy .ci-action-icon-container').click
expect(page).not_to have_content('Cancel running')
end
@@ -92,7 +92,7 @@ describe 'Pipeline', :js do
end
it 'should be possible to retry the success job' do
- find('#ci-badge-build .ci-action-icon-container').trigger('click')
+ find('#ci-badge-build .ci-action-icon-container').click
expect(page).not_to have_content('Retry job')
end
@@ -111,7 +111,7 @@ describe 'Pipeline', :js do
end
it 'should be possible to retry the failed build' do
- find('#ci-badge-test .ci-action-icon-container').trigger('click')
+ find('#ci-badge-test .ci-action-icon-container').click
expect(page).not_to have_content('Retry job')
end
@@ -130,7 +130,7 @@ describe 'Pipeline', :js do
end
it 'should be possible to play the manual job' do
- find('#ci-badge-manual-build .ci-action-icon-container').trigger('click')
+ find('#ci-badge-manual-build .ci-action-icon-container').click
expect(page).not_to have_content('Play job')
end
@@ -165,7 +165,7 @@ describe 'Pipeline', :js do
context 'when retrying' do
before do
- find('.js-retry-button').trigger('click')
+ find('.js-retry-button').click
end
it { expect(page).not_to have_content('Retry') }
@@ -231,7 +231,7 @@ describe 'Pipeline', :js do
context 'when retrying' do
before do
- find('.js-retry-button').trigger('click')
+ find('.js-retry-button').click
end
it { expect(page).not_to have_content('Retry') }
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 59dff22eca3..f05d8685cfb 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -222,7 +222,7 @@ describe 'Pipelines', :js do
context 'when canceling' do
before do
- find('.js-pipelines-cancel-button').trigger('click')
+ find('.js-pipelines-cancel-button').click
end
it 'indicates that pipeline was canceled' do
@@ -335,14 +335,14 @@ describe 'Pipelines', :js do
context 'when clicking a stage badge' do
it 'should open a dropdown' do
- find('.js-builds-dropdown-button').trigger('click')
+ find('.js-builds-dropdown-button').click
expect(page).to have_link build.name
end
it 'should be possible to cancel pending build' do
- find('.js-builds-dropdown-button').trigger('click')
- find('a.js-ci-action-icon').trigger('click')
+ find('.js-builds-dropdown-button').click
+ find('a.js-ci-action-icon').click
expect(page).to have_content('canceled')
expect(build.reload).to be_canceled
@@ -351,11 +351,11 @@ describe 'Pipelines', :js do
context 'dropdown jobs list' do
it 'should keep the dropdown open when the user ctr/cmd + clicks in the job name' do
- find('.js-builds-dropdown-button').trigger('click')
+ find('.js-builds-dropdown-button').click
execute_script('var e = $.Event("keydown", { keyCode: 64 }); $("body").trigger(e);')
- find('.mini-pipeline-graph-dropdown-item').trigger('click')
+ find('.mini-pipeline-graph-dropdown-item').click
expect(page).to have_selector('.js-ci-action-icon')
end
diff --git a/spec/features/projects/services/jira_service_spec.rb b/spec/features/projects/services/jira_service_spec.rb
index ecaa69c49dd..645713d0805 100644
--- a/spec/features/projects/services/jira_service_spec.rb
+++ b/spec/features/projects/services/jira_service_spec.rb
@@ -65,7 +65,7 @@ feature 'Setup Jira service', :js do
expect(find('.flash-container-page')).to have_content 'Test failed. message'
expect(find('.flash-container-page')).to have_content 'Save anyway'
- find('.flash-alert .flash-action').trigger('click')
+ find('.flash-alert .flash-action').click
wait_for_requests
expect(page).to have_content('JIRA activated.')
diff --git a/spec/features/projects/wiki/markdown_preview_spec.rb b/spec/features/projects/wiki/markdown_preview_spec.rb
index dbe98a38197..327bda28dd6 100644
--- a/spec/features/projects/wiki/markdown_preview_spec.rb
+++ b/spec/features/projects/wiki/markdown_preview_spec.rb
@@ -19,13 +19,13 @@ feature 'Projects > Wiki > User previews markdown changes', js: true do
sign_in(user)
visit project_path(project)
- find('.shortcuts-wiki').trigger('click')
+ find('.shortcuts-wiki').click
end
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
- find('.add-new-wiki').trigger('click')
+ find('.add-new-wiki').click
page.within '#modal-new-wiki' do
fill_in :new_wiki_path, with: 'a/b/c/d'
click_button 'Create page'
@@ -92,7 +92,7 @@ feature 'Projects > Wiki > User previews markdown changes', js: true do
context "while editing a wiki page" do
def create_wiki_page(path)
- find('.add-new-wiki').trigger('click')
+ find('.add-new-wiki').click
page.within '#modal-new-wiki' do
fill_in :new_wiki_path, with: path
diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb
index 3677bf38724..03e43fce384 100644
--- a/spec/features/protected_branches_spec.rb
+++ b/spec/features/protected_branches_spec.rb
@@ -9,7 +9,7 @@ feature 'Protected Branches', js: true do
end
def set_protected_branch_name(branch_name)
- find(".js-protected-branch-select").trigger('click')
+ find(".js-protected-branch-select").click
find(".dropdown-input-field").set(branch_name)
click_on("Create wildcard #{branch_name}")
end
diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb
index b29f19f1562..20dcb640c9c 100644
--- a/spec/features/search_spec.rb
+++ b/spec/features/search_spec.rb
@@ -27,7 +27,7 @@ describe "Search" do
end
it 'shows group name after filtering' do
- find('.js-search-group-dropdown').trigger('click')
+ find('.js-search-group-dropdown').click
wait_for_requests
page.within '.search-holder' do
@@ -38,7 +38,7 @@ describe "Search" do
end
it 'filters by group projects after filtering by group' do
- find('.js-search-group-dropdown').trigger('click')
+ find('.js-search-group-dropdown').click
wait_for_requests
page.within '.search-holder' do
@@ -48,7 +48,7 @@ describe "Search" do
expect(find('.js-search-group-dropdown')).to have_content(group.name)
page.within('.project-filter') do
- find('.js-search-project-dropdown').trigger('click')
+ find('.js-search-project-dropdown').click
wait_for_requests
expect(page).to have_link(group_project.name_with_namespace)
@@ -57,7 +57,7 @@ describe "Search" do
it 'shows project name after filtering' do
page.within('.project-filter') do
- find('.js-search-project-dropdown').trigger('click')
+ find('.js-search-project-dropdown').click
wait_for_requests
click_link project.name_with_namespace
diff --git a/spec/features/todos/todos_spec.rb b/spec/features/todos/todos_spec.rb
new file mode 100644
index 00000000000..320777e97bf
--- /dev/null
+++ b/spec/features/todos/todos_spec.rb
@@ -0,0 +1,355 @@
+require 'spec_helper'
+
+describe 'Dashboard Todos', feature: true do
+ let(:user) { create(:user) }
+ let(:author) { create(:user) }
+ let(:project) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ let(:issue) { create(:issue, due_date: Date.today) }
+
+ describe 'GET /dashboard/todos' do
+ context 'User does not have todos' do
+ before do
+ gitlab_sign_in(user)
+ visit dashboard_todos_path
+ end
+ it 'shows "All done" message' do
+ expect(page).to have_content "Todos let you see what you should do next."
+ end
+ end
+
+ context 'User has a todo', js: true do
+ before do
+ create(:todo, :mentioned, user: user, project: project, target: issue, author: author)
+ gitlab_sign_in(user)
+ visit dashboard_todos_path
+ end
+
+ it 'has todo present' do
+ expect(page).to have_selector('.todos-list .todo', count: 1)
+ end
+
+ it 'shows due date as today' do
+ within first('.todo') do
+ expect(page).to have_content 'Due today'
+ end
+ end
+
+ shared_examples 'deleting the todo' do
+ before do
+ within first('.todo') do
+ click_link 'Done'
+ end
+ end
+
+ it 'is marked as done-reversible in the list' do
+ expect(page).to have_selector('.todos-list .todo.todo-pending.done-reversible')
+ end
+
+ it 'shows Undo button' do
+ expect(page).to have_selector('.js-undo-todo', visible: true)
+ expect(page).to have_selector('.js-done-todo', visible: false)
+ end
+
+ it 'updates todo count' do
+ expect(page).to have_content 'To do 0'
+ expect(page).to have_content 'Done 1'
+ end
+
+ it 'has not "All done" message' do
+ expect(page).not_to have_selector('.todos-all-done')
+ end
+ end
+
+ shared_examples 'deleting and restoring the todo' do
+ before do
+ within first('.todo') do
+ click_link 'Done'
+ wait_for_requests
+ click_link 'Undo'
+ end
+ end
+
+ it 'is marked back as pending in the list' do
+ expect(page).not_to have_selector('.todos-list .todo.todo-pending.done-reversible')
+ expect(page).to have_selector('.todos-list .todo.todo-pending')
+ end
+
+ it 'shows Done button' do
+ expect(page).to have_selector('.js-undo-todo', visible: false)
+ expect(page).to have_selector('.js-done-todo', visible: true)
+ end
+
+ it 'updates todo count' do
+ expect(page).to have_content 'To do 1'
+ expect(page).to have_content 'Done 0'
+ end
+ end
+
+ it_behaves_like 'deleting the todo'
+ it_behaves_like 'deleting and restoring the todo'
+
+ context 'todo is stale on the page' do
+ before do
+ todos = TodosFinder.new(user, state: :pending).execute
+ TodoService.new.mark_todos_as_done(todos, user)
+ end
+
+ it_behaves_like 'deleting the todo'
+ it_behaves_like 'deleting and restoring the todo'
+ end
+ end
+
+ context 'User created todos for themself' do
+ before do
+ gitlab_sign_in(user)
+ end
+
+ context 'issue assigned todo' do
+ before do
+ create(:todo, :assigned, user: user, project: project, target: issue, author: user)
+ visit dashboard_todos_path
+ end
+
+ it 'shows issue assigned to yourself message' do
+ page.within('.js-todos-all') do
+ expect(page).to have_content("You assigned issue #{issue.to_reference(full: true)} to yourself")
+ end
+ end
+ end
+
+ context 'marked todo' do
+ before do
+ create(:todo, :marked, user: user, project: project, target: issue, author: user)
+ visit dashboard_todos_path
+ end
+
+ it 'shows you added a todo message' do
+ page.within('.js-todos-all') do
+ expect(page).to have_content("You added a todo for issue #{issue.to_reference(full: true)}")
+ expect(page).not_to have_content('to yourself')
+ end
+ end
+ end
+
+ context 'mentioned todo' do
+ before do
+ create(:todo, :mentioned, user: user, project: project, target: issue, author: user)
+ visit dashboard_todos_path
+ end
+
+ it 'shows you mentioned yourself message' do
+ page.within('.js-todos-all') do
+ expect(page).to have_content("You mentioned yourself on issue #{issue.to_reference(full: true)}")
+ expect(page).not_to have_content('to yourself')
+ end
+ end
+ end
+
+ context 'directly_addressed todo' do
+ before do
+ create(:todo, :directly_addressed, user: user, project: project, target: issue, author: user)
+ visit dashboard_todos_path
+ end
+
+ it 'shows you directly addressed yourself message' do
+ page.within('.js-todos-all') do
+ expect(page).to have_content("You directly addressed yourself on issue #{issue.to_reference(full: true)}")
+ expect(page).not_to have_content('to yourself')
+ end
+ end
+ end
+
+ context 'approval todo' do
+ let(:merge_request) { create(:merge_request) }
+
+ before do
+ create(:todo, :approval_required, user: user, project: project, target: merge_request, author: user)
+ visit dashboard_todos_path
+ end
+
+ it 'shows you set yourself as an approver message' do
+ page.within('.js-todos-all') do
+ expect(page).to have_content("You set yourself as an approver for merge request #{merge_request.to_reference(full: true)}")
+ expect(page).not_to have_content('to yourself')
+ end
+ end
+ end
+ end
+
+ context 'User has done todos', js: true do
+ before do
+ create(:todo, :mentioned, :done, user: user, project: project, target: issue, author: author)
+ gitlab_sign_in(user)
+ visit dashboard_todos_path(state: :done)
+ end
+
+ it 'has the done todo present' do
+ expect(page).to have_selector('.todos-list .todo.todo-done', count: 1)
+ end
+
+ describe 'restoring the todo' do
+ before do
+ within first('.todo') do
+ click_link 'Add todo'
+ end
+ end
+
+ it 'is removed from the list' do
+ expect(page).not_to have_selector('.todos-list .todo.todo-done')
+ end
+
+ it 'updates todo count' do
+ expect(page).to have_content 'To do 1'
+ expect(page).to have_content 'Done 0'
+ end
+ end
+ end
+
+ context 'User has Todos with labels spanning multiple projects' do
+ before do
+ label1 = create(:label, project: project)
+ note1 = create(:note_on_issue, note: "Hello #{label1.to_reference(format: :name)}", noteable_id: issue.id, noteable_type: 'Issue', project: issue.project)
+ create(:todo, :mentioned, project: project, target: issue, user: user, note_id: note1.id)
+
+ project2 = create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ label2 = create(:label, project: project2)
+ issue2 = create(:issue, project: project2)
+ note2 = create(:note_on_issue, note: "Test #{label2.to_reference(format: :name)}", noteable_id: issue2.id, noteable_type: 'Issue', project: project2)
+ create(:todo, :mentioned, project: project2, target: issue2, user: user, note_id: note2.id)
+
+ gitlab_sign_in(user)
+ visit dashboard_todos_path
+ end
+
+ it 'shows page with two Todos' do
+ expect(page).to have_selector('.todos-list .todo', count: 2)
+ end
+ end
+
+ context 'User has multiple pages of Todos' do
+ before do
+ allow(Todo).to receive(:default_per_page).and_return(1)
+
+ # Create just enough records to cause us to paginate
+ create_list(:todo, 2, :mentioned, user: user, project: project, target: issue, author: author)
+
+ gitlab_sign_in(user)
+ end
+
+ it 'is paginated' do
+ visit dashboard_todos_path
+
+ expect(page).to have_selector('.gl-pagination')
+ end
+
+ it 'is has the right number of pages' do
+ visit dashboard_todos_path
+
+ expect(page).to have_selector('.gl-pagination .page', count: 2)
+ end
+
+ describe 'mark all as done', js: true do
+ before do
+ visit dashboard_todos_path
+ find('.js-todos-mark-all').click
+ end
+
+ it 'shows "All done" message!' do
+ expect(page).to have_content 'To do 0'
+ expect(page).to have_content "You're all done!"
+ expect(page).not_to have_selector('.gl-pagination')
+ end
+
+ it 'shows "Undo mark all as done" button' do
+ expect(page).to have_selector('.js-todos-mark-all', visible: false)
+ expect(page).to have_selector('.js-todos-undo-all', visible: true)
+ end
+ end
+
+ describe 'undo mark all as done', js: true do
+ before do
+ visit dashboard_todos_path
+ end
+
+ it 'shows the restored todo list' do
+ mark_all_and_undo
+
+ expect(page).to have_selector('.todos-list .todo', count: 1)
+ expect(page).to have_selector('.gl-pagination')
+ expect(page).not_to have_content "You're all done!"
+ end
+
+ it 'updates todo count' do
+ mark_all_and_undo
+
+ expect(page).to have_content 'To do 2'
+ expect(page).to have_content 'Done 0'
+ end
+
+ it 'shows "Mark all as done" button' do
+ mark_all_and_undo
+
+ expect(page).to have_selector('.js-todos-mark-all', visible: true)
+ expect(page).to have_selector('.js-todos-undo-all', visible: false)
+ end
+
+ context 'User has deleted a todo' do
+ before do
+ within first('.todo') do
+ click_link 'Done'
+ end
+ end
+
+ it 'shows the restored todo list with the deleted todo' do
+ mark_all_and_undo
+
+ expect(page).to have_selector('.todos-list .todo.todo-pending', count: 1)
+ end
+ end
+
+ def mark_all_and_undo
+ find('.js-todos-mark-all').click
+ wait_for_requests
+ find('.js-todos-undo-all').click
+ wait_for_requests
+ end
+ end
+ end
+
+ context 'User has a Todo in a project pending deletion' do
+ before do
+ deleted_project = create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC, pending_delete: true)
+ create(:todo, :mentioned, user: user, project: deleted_project, target: issue, author: author)
+ create(:todo, :mentioned, user: user, project: deleted_project, target: issue, author: author, state: :done)
+ gitlab_sign_in(user)
+ visit dashboard_todos_path
+ end
+
+ it 'shows "All done" message' do
+ within('.todos-count') { expect(page).to have_content '0' }
+ expect(page).to have_content 'To do 0'
+ expect(page).to have_content 'Done 0'
+ expect(page).to have_selector('.todos-all-done', count: 1)
+ end
+ end
+
+ context 'User has a Build Failed todo' do
+ let!(:todo) { create(:todo, :build_failed, user: user, project: project, author: author) }
+
+ before do
+ gitlab_sign_in user
+ visit dashboard_todos_path
+ end
+
+ it 'shows the todo' do
+ expect(page).to have_content 'The build failed for merge request'
+ end
+
+ it 'links to the pipelines for the merge request' do
+ href = pipelines_namespace_project_merge_request_path(project.namespace, project, todo.target)
+
+ expect(page).to have_link "merge request #{todo.target.to_reference(full: true)}", href
+ end
+ end
+ end
+end
diff --git a/spec/features/user_callout_spec.rb b/spec/features/user_callout_spec.rb
index 93768aa46df..fa35fd7ebab 100644
--- a/spec/features/user_callout_spec.rb
+++ b/spec/features/user_callout_spec.rb
@@ -20,7 +20,7 @@ describe 'User Callouts', js: true do
visit dashboard_projects_path
within('.user-callout') do
- find('.close').trigger('click')
+ find('.close').click
end
visit dashboard_projects_path
diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb
index c45c4a4310d..53a90cdb26f 100644
--- a/spec/support/capybara.rb
+++ b/spec/support/capybara.rb
@@ -1,25 +1,22 @@
# rubocop:disable Style/GlobalVars
require 'capybara/rails'
require 'capybara/rspec'
-require 'capybara/poltergeist'
require 'capybara-screenshot/rspec'
+require 'selenium-webdriver'
# Give CI some extra time
timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 60 : 30
-Capybara.javascript_driver = :poltergeist
-Capybara.register_driver :poltergeist do |app|
- Capybara::Poltergeist::Driver.new(
- app,
- js_errors: true,
- timeout: timeout,
- window_size: [1366, 768],
- url_whitelist: %w[localhost 127.0.0.1],
- url_blacklist: %w[.mp4 .png .gif .avi .bmp .jpg .jpeg],
- phantomjs_options: [
- '--load-images=yes'
- ]
+Capybara.javascript_driver = :chrome
+Capybara.register_driver :chrome do |app|
+ capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
+ 'chromeOptions' => {
+ 'args' => %w[headless no-sandbox disable-gpu]
+ }
)
+
+ Capybara::Selenium::Driver
+ .new(app, browser: :chrome, desired_capabilities: capabilities)
end
Capybara.default_max_wait_time = timeout
@@ -27,6 +24,10 @@ Capybara.ignore_hidden_elements = true
# Keep only the screenshots generated from the last failing test suite
Capybara::Screenshot.prune_strategy = :keep_last_run
+# From https://github.com/mattheworiordan/capybara-screenshot/issues/84#issuecomment-41219326
+Capybara::Screenshot.register_driver(:chrome) do |driver, path|
+ driver.browser.save_screenshot(path)
+end
RSpec.configure do |config|
config.before(:context, :js) do
diff --git a/spec/support/features/discussion_comments_shared_example.rb b/spec/support/features/discussion_comments_shared_example.rb
index bb4542b1683..da1074e5932 100644
--- a/spec/support/features/discussion_comments_shared_example.rb
+++ b/spec/support/features/discussion_comments_shared_example.rb
@@ -74,12 +74,12 @@ shared_examples 'discussion comments' do |resource_name|
end
it 'clicking the ul padding or divider should not change the text' do
- find(menu_selector).trigger 'click'
+ find(menu_selector).click
expect(page).to have_selector menu_selector
expect(find(dropdown_selector)).to have_content 'Comment'
- find("#{menu_selector} .divider").trigger 'click'
+ find("#{menu_selector} .divider").click
expect(page).to have_selector menu_selector
expect(find(dropdown_selector)).to have_content 'Comment'
diff --git a/spec/support/protected_tags/access_control_ce_shared_examples.rb b/spec/support/protected_tags/access_control_ce_shared_examples.rb
index 421a51fc336..2770cdcbefc 100644
--- a/spec/support/protected_tags/access_control_ce_shared_examples.rb
+++ b/spec/support/protected_tags/access_control_ce_shared_examples.rb
@@ -9,7 +9,7 @@ RSpec.shared_examples "protected tags > access control > CE" do
allowed_to_create_button = find(".js-allowed-to-create")
unless allowed_to_create_button.text == access_type_name
- allowed_to_create_button.trigger('click')
+ allowed_to_create_button.click
find('.create_access_levels-container .dropdown-menu li', match: :first)
within('.create_access_levels-container .dropdown-menu') { click_on access_type_name }
end
diff --git a/spec/support/quick_actions_helpers.rb b/spec/support/quick_actions_helpers.rb
index d2aaae7518f..361190aa352 100644
--- a/spec/support/quick_actions_helpers.rb
+++ b/spec/support/quick_actions_helpers.rb
@@ -3,7 +3,7 @@ module QuickActionsHelpers
Sidekiq::Testing.fake! do
page.within('.js-main-target-form') do
fill_in 'note[note]', with: text
- find('.js-comment-submit-button').trigger('click')
+ find('.js-comment-submit-button').click
end
end
end
diff --git a/spec/support/shared_examples/features/protected_branches_access_control_ce.rb b/spec/support/shared_examples/features/protected_branches_access_control_ce.rb
index d5bc12f3bc5..72bb0f2e9b9 100644
--- a/spec/support/shared_examples/features/protected_branches_access_control_ce.rb
+++ b/spec/support/shared_examples/features/protected_branches_access_control_ce.rb
@@ -9,7 +9,7 @@ shared_examples "protected branches > access control > CE" do
allowed_to_push_button = find(".js-allowed-to-push")
unless allowed_to_push_button.text == access_type_name
- allowed_to_push_button.trigger('click')
+ allowed_to_push_button.click
within(".dropdown.open .dropdown-menu") { click_on access_type_name }
end
end
diff --git a/spec/support/time_tracking_shared_examples.rb b/spec/support/time_tracking_shared_examples.rb
index 0fa74f911f6..909d4e2ee8d 100644
--- a/spec/support/time_tracking_shared_examples.rb
+++ b/spec/support/time_tracking_shared_examples.rb
@@ -80,6 +80,6 @@ end
def submit_time(quick_action)
fill_in 'note[note]', with: quick_action
- find('.js-comment-submit-button').trigger('click')
+ find('.js-comment-submit-button').click
wait_for_requests
end