Commit 5d4f377b authored by Stan Hu's avatar Stan Hu

Merge branch 'sh-headless-chrome-support' into 'master'

Replace PhantomJS with Headless Chrome for GitLab Integration Tests

Closes #30876

See merge request gitlab-org/gitlab-ce!12244
parents ae470ae2 cc00b289
image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.5-golang-1.8-git-2.13-phantomjs-2.1-node-8.x-yarn-1.0-postgresql-9.6" image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.5-golang-1.8-git-2.13-chrome-62.0-node-8.x-yarn-1.2-postgresql-9.6"
.default-cache: &default-cache .default-cache: &default-cache
key: "ruby-235-with-yarn" key: "ruby-235-with-yarn"
...@@ -23,7 +23,6 @@ variables: ...@@ -23,7 +23,6 @@ variables:
SIMPLECOV: "true" SIMPLECOV: "true"
GIT_DEPTH: "20" GIT_DEPTH: "20"
GIT_SUBMODULE_STRATEGY: "none" GIT_SUBMODULE_STRATEGY: "none"
PHANTOMJS_VERSION: "2.1.1"
GET_SOURCES_ATTEMPTS: "3" GET_SOURCES_ATTEMPTS: "3"
KNAPSACK_RSPEC_SUITE_REPORT_PATH: knapsack/${CI_PROJECT_NAME}/rspec_report-master.json KNAPSACK_RSPEC_SUITE_REPORT_PATH: knapsack/${CI_PROJECT_NAME}/rspec_report-master.json
KNAPSACK_SPINACH_SUITE_REPORT_PATH: knapsack/${CI_PROJECT_NAME}/spinach_report-master.json KNAPSACK_SPINACH_SUITE_REPORT_PATH: knapsack/${CI_PROJECT_NAME}/spinach_report-master.json
...@@ -551,7 +550,6 @@ karma: ...@@ -551,7 +550,6 @@ karma:
<<: *dedicated-runner <<: *dedicated-runner
<<: *except-docs <<: *except-docs
<<: *pull-cache <<: *pull-cache
image: "dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.5-golang-1.8-git-2.13-chrome-61.0-node-8.x-yarn-1.0-postgresql-9.6"
stage: test stage: test
variables: variables:
BABEL_ENV: "coverage" BABEL_ENV: "coverage"
......
...@@ -324,9 +324,9 @@ group :development, :test do ...@@ -324,9 +324,9 @@ group :development, :test do
# Generate Fake data # Generate Fake data
gem 'ffaker', '~> 2.4' gem 'ffaker', '~> 2.4'
gem 'capybara', '~> 2.15.0' gem 'capybara', '~> 2.15'
gem 'capybara-screenshot', '~> 1.0.0' gem 'capybara-screenshot', '~> 1.0.0'
gem 'poltergeist', '~> 1.9.0' gem 'selenium-webdriver', '~> 3.5'
gem 'spring', '~> 2.0.0' gem 'spring', '~> 2.0.0'
gem 'spring-commands-rspec', '~> 1.0.4' gem 'spring-commands-rspec', '~> 1.0.4'
......
...@@ -113,12 +113,13 @@ GEM ...@@ -113,12 +113,13 @@ GEM
mime-types (>= 1.16) mime-types (>= 1.16)
cause (0.1) cause (0.1)
charlock_holmes (0.7.5) charlock_holmes (0.7.5)
childprocess (0.7.0)
ffi (~> 1.0, >= 1.0.11)
chronic (0.10.2) chronic (0.10.2)
chronic_duration (0.10.6) chronic_duration (0.10.6)
numerizer (~> 0.1.1) numerizer (~> 0.1.1)
chunky_png (1.3.5) chunky_png (1.3.5)
citrus (3.0.2) citrus (3.0.2)
cliver (0.3.2)
coderay (1.1.1) coderay (1.1.1)
coercible (1.0.0) coercible (1.0.0)
descendants_tracker (~> 0.0.1) descendants_tracker (~> 0.0.1)
...@@ -604,11 +605,6 @@ GEM ...@@ -604,11 +605,6 @@ GEM
pg (0.18.4) pg (0.18.4)
po_to_json (1.0.1) po_to_json (1.0.1)
json (>= 1.6.0) 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.13) posix-spawn (0.3.13)
powerpack (0.1.1) powerpack (0.1.1)
premailer (1.10.4) premailer (1.10.4)
...@@ -818,6 +814,9 @@ GEM ...@@ -818,6 +814,9 @@ GEM
activesupport (>= 3.1) activesupport (>= 3.1)
select2-rails (3.5.9.3) select2-rails (3.5.9.3)
thor (~> 0.14) thor (~> 0.14)
selenium-webdriver (3.5.0)
childprocess (~> 0.5)
rubyzip (~> 1.0)
sentry-raven (2.5.3) sentry-raven (2.5.3)
faraday (>= 0.7.6, < 1.0) faraday (>= 0.7.6, < 1.0)
settingslogic (2.0.9) settingslogic (2.0.9)
...@@ -949,9 +948,6 @@ GEM ...@@ -949,9 +948,6 @@ GEM
hashdiff hashdiff
webpack-rails (0.9.10) webpack-rails (0.9.10)
railties (>= 3.2.0) railties (>= 3.2.0)
websocket-driver (0.6.3)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2)
wikicloth (0.8.1) wikicloth (0.8.1)
builder builder
expression_parser expression_parser
...@@ -988,7 +984,7 @@ DEPENDENCIES ...@@ -988,7 +984,7 @@ DEPENDENCIES
browser (~> 2.2) browser (~> 2.2)
bullet (~> 5.5.0) bullet (~> 5.5.0)
bundler-audit (~> 0.5.0) bundler-audit (~> 0.5.0)
capybara (~> 2.15.0) capybara (~> 2.15)
capybara-screenshot (~> 1.0.0) capybara-screenshot (~> 1.0.0)
carrierwave (~> 1.2) carrierwave (~> 1.2)
charlock_holmes (~> 0.7.5) charlock_holmes (~> 0.7.5)
...@@ -1104,7 +1100,6 @@ DEPENDENCIES ...@@ -1104,7 +1100,6 @@ DEPENDENCIES
peek-redis (~> 1.2.0) peek-redis (~> 1.2.0)
peek-sidekiq (~> 1.0.3) peek-sidekiq (~> 1.0.3)
pg (~> 0.18.2) pg (~> 0.18.2)
poltergeist (~> 1.9.0)
premailer-rails (~> 1.9.7) premailer-rails (~> 1.9.7)
prometheus-client-mmap (~> 0.7.0.beta18) prometheus-client-mmap (~> 0.7.0.beta18)
pry-byebug (~> 3.4.1) pry-byebug (~> 3.4.1)
...@@ -1150,6 +1145,7 @@ DEPENDENCIES ...@@ -1150,6 +1145,7 @@ DEPENDENCIES
scss_lint (~> 0.54.0) scss_lint (~> 0.54.0)
seed-fu (~> 2.3.5) seed-fu (~> 2.3.5)
select2-rails (~> 3.5.9) select2-rails (~> 3.5.9)
selenium-webdriver (~> 3.5)
sentry-raven (~> 2.5.3) sentry-raven (~> 2.5.3)
settingslogic (~> 2.0.9) settingslogic (~> 2.0.9)
sham_rack (~> 1.3.6) sham_rack (~> 1.3.6)
......
...@@ -79,8 +79,6 @@ const Filter = { ...@@ -79,8 +79,6 @@ const Filter = {
this.hook.trigger.addEventListener('keydown.dl', this.eventWrapper.debounceKeydown); this.hook.trigger.addEventListener('keydown.dl', this.eventWrapper.debounceKeydown);
this.hook.trigger.addEventListener('mousedown.dl', this.eventWrapper.debounceKeydown); this.hook.trigger.addEventListener('mousedown.dl', this.eventWrapper.debounceKeydown);
this.debounceKeydown({ detail: { hook: this.hook } });
}, },
destroy: function destroy() { destroy: function destroy() {
......
import 'core-js/es6/map'; import 'core-js/es6/map';
import 'core-js/es6/set'; import 'core-js/es6/set';
import simulateDrag from './simulate_drag'; import simulateDrag from './simulate_drag';
import simulateInput from './simulate_input';
// Export to global space for rspec to use // Export to global space for rspec to use
window.simulateDrag = simulateDrag; window.simulateDrag = simulateDrag;
window.simulateInput = simulateInput;
function triggerEvents(input) {
input.dispatchEvent(new Event('keydown'));
input.dispatchEvent(new Event('keypress'));
input.dispatchEvent(new Event('input'));
input.dispatchEvent(new Event('keyup'));
}
export default function simulateInput(target, text) {
const input = document.querySelector(target);
if (!input || !input.matches('textarea, input')) {
return false;
}
if (text.length > 0) {
Array.prototype.forEach.call(text, (char) => {
input.value += char;
triggerEvents(input);
});
} else {
triggerEvents(input);
}
return true;
}
...@@ -484,10 +484,7 @@ ...@@ -484,10 +484,7 @@
height: calc(100vh - #{$header-height}); height: calc(100vh - #{$header-height});
@media (min-width: $screen-sm-min) { @media (min-width: $screen-sm-min) {
height: 475px; // Needed for PhantomJS
// scss-lint:disable DuplicateProperty
height: calc(100vh - 180px); height: calc(100vh - 180px);
// scss-lint:enable DuplicateProperty
} }
} }
......
...@@ -268,12 +268,6 @@ ...@@ -268,12 +268,6 @@
.filtered-search-box-input-container { .filtered-search-box-input-container {
flex: 1; flex: 1;
position: relative; position: relative;
// Fix PhantomJS not supporting `flex: 1;` properly.
// This is important because it can change the expected `e.target` when clicking things in tests.
// See https://gitlab.com/gitlab-org/gitlab-ce/blob/b54acba8b732688c59fe2f38510c469dc86ee499/spec/features/issues/filtered_search/visual_tokens_spec.rb#L61
// - With `width: 100%`: `e.target` = `.tokens-container`, https://i.imgur.com/jGq7wbx.png
// - Without `width: 100%`: `e.target` = `.filtered-search`, https://i.imgur.com/cNI2CyT.png
width: 100%;
min-width: 0; min-width: 0;
} }
......
...@@ -86,10 +86,7 @@ ...@@ -86,10 +86,7 @@
} }
@media (min-width: $screen-md-min) { @media (min-width: $screen-md-min) {
height: 475px; // Needed for PhantomJS
// scss-lint:disable DuplicateProperty
height: calc(100vh - 160px); height: calc(100vh - 160px);
// scss-lint:enable DuplicateProperty
min-height: 475px; min-height: 475px;
} }
} }
......
...@@ -485,8 +485,6 @@ ul.notes { ...@@ -485,8 +485,6 @@ ul.notes {
flex-shrink: 0; flex-shrink: 0;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
// For PhantomJS that does not support flex
float: right;
margin-left: 10px; margin-left: 10px;
color: $gray-darkest; color: $gray-darkest;
...@@ -497,7 +495,6 @@ ul.notes { ...@@ -497,7 +495,6 @@ ul.notes {
} }
.more-actions { .more-actions {
float: right; // phantomjs fallback
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
......
...@@ -4,11 +4,6 @@ ...@@ -4,11 +4,6 @@
-ms-transition: none !important; -ms-transition: none !important;
-webkit-transition: none !important; -webkit-transition: none !important;
transition: none !important; transition: none !important;
-o-transform: none !important;
-moz-transform: none !important;
-ms-transform: none !important;
-webkit-transform: none !important;
transform: none !important;
-webkit-animation: none !important; -webkit-animation: none !important;
-moz-animation: none !important; -moz-animation: none !important;
-o-animation: none !important; -o-animation: none !important;
......
Rails.application.configure do Rails.application.configure do
# Make sure the middleware is inserted first in middleware chain # Make sure the middleware is inserted first in middleware chain
config.middleware.insert_before('ActionDispatch::Static', 'Gitlab::Testing::RequestBlockerMiddleware') config.middleware.insert_before('ActionDispatch::Static', 'Gitlab::Testing::RequestBlockerMiddleware')
config.middleware.insert_before('ActionDispatch::Static', 'Gitlab::Testing::RequestInspectorMiddleware')
# Settings specified here will take precedence over those in config/application.rb # Settings specified here will take precedence over those in config/application.rb
......
...@@ -11,7 +11,7 @@ class Spinach::Features::ProfileNotifications < Spinach::FeatureSteps ...@@ -11,7 +11,7 @@ class Spinach::Features::ProfileNotifications < Spinach::FeatureSteps
end end
step 'I select Mention setting from dropdown' do step 'I select Mention setting from dropdown' do
first(:link, "On mention").trigger('click') first(:link, "On mention").click
end end
step 'I should see Notification saved message' do step 'I should see Notification saved message' do
......
...@@ -40,6 +40,7 @@ class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps ...@@ -40,6 +40,7 @@ class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps
step 'I submit new branch form with invalid name' do step 'I submit new branch form with invalid name' do
fill_in 'branch_name', with: '1.0 stable' fill_in 'branch_name', with: '1.0 stable'
page.find("body").click # defocus the branch_name input
select_branch('master') select_branch('master')
click_button 'Create branch' click_button 'Create branch'
end end
...@@ -70,17 +71,16 @@ class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps ...@@ -70,17 +71,16 @@ class Spinach::Features::ProjectCommitsBranches < Spinach::FeatureSteps
step "I click branch 'improve/awesome' delete link" do step "I click branch 'improve/awesome' delete link" do
page.within '.js-branch-improve\/awesome' do page.within '.js-branch-improve\/awesome' do
find('.btn-remove').click accept_alert { find('.btn-remove').click }
sleep 0.05
end end
end end
step "I should not see branch 'improve/awesome'" do step "I should not see branch 'improve/awesome'" do
expect(page.all(visible: true)).not_to have_content 'improve/awesome' expect(page).to have_css('.js-branch-improve\\/awesome', visible: :hidden)
end end
def select_branch(branch_name) def select_branch(branch_name)
click_button 'master' find('.git-revision-dropdown-toggle').click
page.within '#new-branch-form .dropdown-menu' do page.within '#new-branch-form .dropdown-menu' do
click_link branch_name click_link branch_name
......
...@@ -16,7 +16,7 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps ...@@ -16,7 +16,7 @@ class Spinach::Features::ProjectIssuesLabels < Spinach::FeatureSteps
step 'I delete all labels' do step 'I delete all labels' do
page.within '.labels' do page.within '.labels' do
page.all('.remove-row').each do page.all('.remove-row').each do
first('.remove-row').click accept_confirm { first('.remove-row').click }
end end
end end
end end
......
...@@ -3,6 +3,7 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps ...@@ -3,6 +3,7 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps
include SharedProject include SharedProject
include SharedPaths include SharedPaths
include SharedMarkdown include SharedMarkdown
include CapybaraHelpers
step 'I should see milestone "v2.2"' do step 'I should see milestone "v2.2"' do
milestone = @project.milestones.find_by(title: "v2.2") milestone = @project.milestones.find_by(title: "v2.2")
...@@ -65,7 +66,7 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps ...@@ -65,7 +66,7 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps
end end
step 'I click link to remove milestone' do step 'I click link to remove milestone' do
click_link 'Delete' confirm_modal_if_present { click_link 'Delete' }
end end
step 'I should see no milestones' do step 'I should see no milestones' do
......
...@@ -215,7 +215,7 @@ module SharedDiffNote ...@@ -215,7 +215,7 @@ module SharedDiffNote
end end
step 'I click side-by-side diff button' do step 'I click side-by-side diff button' do
find('#parallel-diff-btn').trigger('click') find('#parallel-diff-btn').click
end end
step 'I see side-by-side diff button' do step 'I see side-by-side diff button' do
...@@ -227,12 +227,11 @@ module SharedDiffNote ...@@ -227,12 +227,11 @@ module SharedDiffNote
end end
def click_diff_line(code) def click_diff_line(code)
find(".line_holder[id='#{code}'] td:nth-of-type(1)").trigger 'mouseover' find(".line_holder[id='#{code}'] button").click
find(".line_holder[id='#{code}'] button").trigger 'click'
end end
def click_parallel_diff_line(code, line_type) def click_parallel_diff_line(code, line_type)
find(".line_holder.parallel td[id='#{code}']").find(:xpath, 'preceding-sibling::*[1][self::td]').trigger 'mouseover' find(".line_holder.parallel td[id='#{code}']").find(:xpath, 'preceding-sibling::*[1][self::td]').hover
find(".line_holder.parallel button[data-line-code='#{code}']").trigger 'click' find(".line_holder.parallel button[data-line-code='#{code}']").click
end end
end end
...@@ -14,7 +14,7 @@ module SharedNote ...@@ -14,7 +14,7 @@ module SharedNote
find('.more-actions').click find('.more-actions').click
find('.more-actions .dropdown-menu li', match: :first) find('.more-actions .dropdown-menu li', match: :first)
find(".js-note-delete").click accept_confirm { find(".js-note-delete").click }
end end
end end
......
require 'capybara/poltergeist'
require 'capybara-screenshot/spinach' require 'capybara-screenshot/spinach'
# Give CI some extra time # Give CI some extra time
timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 60 : 30 timeout = (ENV['CI'] || ENV['CI_SERVER']) ? 60 : 30
Capybara.javascript_driver = :poltergeist Capybara.javascript_driver = :chrome
Capybara.register_driver :poltergeist do |app| Capybara.register_driver :chrome do |app|
Capybara::Poltergeist::Driver.new( extra_args = []
app, extra_args << 'headless' unless ENV['CHROME_HEADLESS'] =~ /^(false|no|0)$/i
js_errors: true,
timeout: timeout, capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
window_size: [1366, 768], chromeOptions: {
url_whitelist: %w[localhost 127.0.0.1], 'args' => %w[no-sandbox disable-gpu --window-size=1240,1400] + extra_args
url_blacklist: %w[.mp4 .png .gif .avi .bmp .jpg .jpeg], }
phantomjs_options: [
'--load-images=yes'
]
) )
Capybara::Selenium::Driver
.new(app, browser: :chrome, desired_capabilities: capabilities)
end end
Capybara.default_max_wait_time = timeout Capybara.default_max_wait_time = timeout
...@@ -24,6 +23,10 @@ Capybara.ignore_hidden_elements = false ...@@ -24,6 +23,10 @@ Capybara.ignore_hidden_elements = false
# Keep only the screenshots generated from the last failing test suite # Keep only the screenshots generated from the last failing test suite
Capybara::Screenshot.prune_strategy = :keep_last_run 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 Spinach.hooks.before_run do
TestEnv.eager_load_driver_server TestEnv.eager_load_driver_server
......
module CapybaraHelpers
def confirm_modal_if_present
if Capybara.current_driver == Capybara.javascript_driver
accept_confirm { yield }
return
end
yield
end
end
...@@ -7,6 +7,7 @@ module Gitlab ...@@ -7,6 +7,7 @@ module Gitlab
class RequestBlockerMiddleware class RequestBlockerMiddleware
@@num_active_requests = Concurrent::AtomicFixnum.new(0) @@num_active_requests = Concurrent::AtomicFixnum.new(0)
@@block_requests = Concurrent::AtomicBoolean.new(false) @@block_requests = Concurrent::AtomicBoolean.new(false)
@@slow_requests = Concurrent::AtomicBoolean.new(false)
# Returns the number of requests the server is currently processing. # Returns the number of requests the server is currently processing.
def self.num_active_requests def self.num_active_requests
...@@ -19,9 +20,15 @@ module Gitlab ...@@ -19,9 +20,15 @@ module Gitlab
@@block_requests.value = true @@block_requests.value = true
end end
# Slows down incoming requests (useful for race conditions).
def self.slow_requests!
@@slow_requests.value = true
end
# Allows the server to accept requests again. # Allows the server to accept requests again.
def self.allow_requests! def self.allow_requests!
@@block_requests.value = false @@block_requests.value = false
@@slow_requests.value = false
end end
def initialize(app) def initialize(app)
...@@ -33,6 +40,7 @@ module Gitlab ...@@ -33,6 +40,7 @@ module Gitlab
if block_requests? if block_requests?
block_request(env) block_request(env)
else else
sleep 0.2 if slow_requests?
@app.call(env) @app.call(env)
end end
ensure ensure
...@@ -45,6 +53,10 @@ module Gitlab ...@@ -45,6 +53,10 @@ module Gitlab
@@block_requests.true? @@block_requests.true?
end end
def slow_requests?
@@slow_requests.true?
end
def block_request(env) def block_request(env)
[503, {}, []] [503, {}, []]
end end
......
# rubocop:disable Style/ClassVars
module Gitlab
module Testing
class RequestInspectorMiddleware
@@log_requests = Concurrent::AtomicBoolean.new(false)
@@logged_requests = Concurrent::Array.new
@@inject_headers = Concurrent::Hash.new
# Resets the current request log and starts logging requests
def self.log_requests!(headers = {})
@@inject_headers.replace(headers)
@@logged_requests.replace([])
@@log_requests.value = true
end
# Stops logging requests
def self.stop_logging!
@@log_requests.value = false
end
def self.requests
@@logged_requests
end
def initialize(app)
@app = app
end
def call(env)
return @app.call(env) unless @@log_requests.true?
url = env['REQUEST_URI']
env.merge! http_headers_env(@@inject_headers) if @@inject_headers.any?
request_headers = env_http_headers(env)
status, headers, body = @app.call(env)
request = OpenStruct.new(
url: url,
status_code: status,
request_headers: request_headers,
response_headers: headers
)
log_request request
[status, headers, body]
end
private
def env_http_headers(env)
Hash[*env.select { |k, v| k.start_with? 'HTTP_' }
.collect { |k, v| [k.sub(/^HTTP_/, ''), v] }
.collect { |k, v| [k.split('_').collect(&:capitalize).join('-'), v] }
.sort
.flatten]
end
def http_headers_env(headers)
Hash[*headers
.collect { |k, v| [k.split('-').collect(&:upcase).join('_'), v] }
.collect { |k, v| [k.prepend('HTTP_'), v] }
.flatten]
end
def log_request(response)
@@logged_requests.push(response)
end
end
end
end
...@@ -7,7 +7,7 @@ feature 'Admin disables 2FA for a user' do ...@@ -7,7 +7,7 @@ feature 'Admin disables 2FA for a user' do
edit_user(user) edit_user(user)
page.within('.two-factor-status') do page.within('.two-factor-status') do
click_link 'Disable' accept_confirm { click_link 'Disable' }
end end
page.within('.two-factor-status') do page.within('.two-factor-status') do
......
...@@ -152,7 +152,7 @@ feature 'Admin Groups' do ...@@ -152,7 +152,7 @@ feature 'Admin Groups' do
expect(page).to have_content('Developer') expect(page).to have_content('Developer')
end end
find(:css, 'li', text: current_user.name).find(:css, 'a.btn-remove').click accept_confirm { find(:css, 'li', text: current_user.name).find(:css, 'a.btn-remove').click }
visit group_group_members_path(group) visit group_group_members_path(group)
......
...@@ -62,14 +62,14 @@ describe 'Admin::Hooks', :js do ...@@ -62,14 +62,14 @@ describe 'Admin::Hooks', :js do
it 'from hooks list page' do it 'from hooks list page' do
visit admin_hooks_path visit admin_hooks_path
expect { click_link 'Remove' }.to change(SystemHook, :count).by(-1) expect { accept_confirm { find(:link, 'Remove').send_keys(:return) } }.to change(SystemHook, :count).by(-1)
end end
it 'from hook edit page' do it 'from hook edit page' do
visit admin_hooks_path visit admin_hooks_path
click_link 'Edit' click_link 'Edit'
expect { click_link 'Remove' }.to change(SystemHook, :count).by(-1) expect { accept_confirm { find(:link, 'Remove').send_keys(:return) } }.to change(SystemHook, :count).by(-1)
end end
end end
end end
......
...@@ -33,7 +33,7 @@ RSpec.describe 'admin issues labels' do ...@@ -33,7 +33,7 @@ RSpec.describe 'admin issues labels' do
it 'deletes all labels', :js do it 'deletes all labels', :js do
page.within '.labels' do page.within '.labels' do
page.all('.btn-remove').each do |remove| page.all('.btn-remove').each do |remove|
remove.click accept_confirm { remove.click }
wait_for_requests wait_for_requests
end end
end end
......
...@@ -73,7 +73,7 @@ feature 'Admin updates settings' do ...@@ -73,7 +73,7 @@ feature 'Admin updates settings' do
context 'sign-in restrictions', :js do context 'sign-in restrictions', :js do
it 'de-activates oauth sign-in source' do it 'de-activates oauth sign-in source' do
find('.btn', text: 'GitLab.com').click find('input#application_setting_enabled_oauth_sign_in_sources_[value=gitlab]').send_keys(:return)
expect(find('.btn', text: 'GitLab.com')).not_to have_css('.active') expect(find('.btn', text: 'GitLab.com')).not_to have_css('.active')
end end
......
...@@ -24,7 +24,7 @@ describe 'Admin > Users > Impersonation Tokens', :js do ...@@ -24,7 +24,7 @@ describe 'Admin > Users > Impersonation Tokens', :js do
fill_in "Name", with: name fill_in "Name", with: name
# Set date to 1st of next month # Set date to 1st of next month
find_field("Expires at").trigger('focus') find_field("Expires at").click
find(".pika-next").click find(".pika-next").click
click_on "1" click_on "1"
...@@ -60,7 +60,7 @@ describe 'Admin > Users > Impersonation Tokens', :js do ...@@ -60,7 +60,7 @@ describe 'Admin > Users > Impersonation Tokens', :js do
it "allows revocation of an active impersonation token" do it "allows revocation of an active impersonation token" do
visit admin_user_impersonation_tokens_path(user_id: user.username) visit admin_user_impersonation_tokens_path(user_id: user.username)
click_on "Revoke" accept_confirm { click_on "Revoke" }
expect(page).to have_selector(".settings-message") expect(page).to have_selector(".settings-message")
expect(no_personal_access_tokens_message).to have_text("This user has no active Impersonation Tokens.") expect(no_personal_access_tokens_message).to have_text("This user has no active Impersonation Tokens.")
......
...@@ -290,7 +290,7 @@ describe "Admin::Users" do ...@@ -290,7 +290,7 @@ describe "Admin::Users" do
it 'allows group membership to be revoked', :js do it 'allows group membership to be revoked', :js do
page.within(first('.group_member')) do page.within(first('.group_member')) do
find('.btn-remove').click accept_confirm { find('.btn-remove').click }
end end
wait_for_requests wait_for_requests
...@@ -319,7 +319,7 @@ describe "Admin::Users" do ...@@ -319,7 +319,7 @@ describe "Admin::Users" do
expect(page).to have_content("Secondary email: #{secondary_email.email}") expect(page).to have_content("Secondary email: #{secondary_email.email}")
find("#remove_email_#{secondary_email.id}").click accept_confirm { find("#remove_email_#{secondary_email.id}").click }
expect(page).not_to have_content(secondary_email.email) expect(page).not_to have_content(secondary_email.email)
end end
......
...@@ -37,7 +37,7 @@ feature 'Admin uses repository checks' do ...@@ -37,7 +37,7 @@ feature 'Admin uses repository checks' do
expect(RepositoryCheck::ClearWorker).to receive(:perform_async) expect(RepositoryCheck::ClearWorker).to receive(:perform_async)
click_link 'Clear all repository checks' accept_confirm { find(:link, 'Clear all repository checks').send_keys(:return) }
expect(page).to have_content('Started asynchronous removal of all repository check states.') expect(page).to have_content('Started asynchronous removal of all repository check states.')
end end
......
...@@ -101,7 +101,7 @@ describe 'Issue Boards add issue modal', :js do ...@@ -101,7 +101,7 @@ describe 'Issue Boards add issue modal', :js do
click_button 'Cancel' click_button 'Cancel'
end end
first('.board-delete').click accept_confirm { first('.board-delete').click }
click_button('Add issues') click_button('Add issues')
......
...@@ -2,6 +2,7 @@ require 'rails_helper' ...@@ -2,6 +2,7 @@ require 'rails_helper'
describe 'Issue Boards', :js do describe 'Issue Boards', :js do
include DragTo include DragTo
include MobileHelpers
let(:group) { create(:group, :nested) } let(:group) { create(:group, :nested) }
let(:project) { create(:project, :public, namespace: group) } let(:project) { create(:project, :public, namespace: group) }
...@@ -13,7 +14,7 @@ describe 'Issue Boards', :js do ...@@ -13,7 +14,7 @@ describe 'Issue Boards', :js do
project.team << [user, :master] project.team << [user, :master]
project.team << [user2, :master] project.team << [user2, :master]
page.driver.set_cookie('sidebar_collapsed', 'true') set_cookie('sidebar_collapsed', 'true')
sign_in(user) sign_in(user)
end end
...@@ -135,7 +136,7 @@ describe 'Issue Boards', :js do ...@@ -135,7 +136,7 @@ describe 'Issue Boards', :js do
it 'allows user to delete board' do it 'allows user to delete board' do
page.within(find('.board:nth-child(2)')) do page.within(find('.board:nth-child(2)')) do
find('.board-delete').click accept_confirm { find('.board-delete').click }
end end
wait_for_requests wait_for_requests
...@@ -150,7 +151,7 @@ describe 'Issue Boards', :js do ...@@ -150,7 +151,7 @@ describe 'Issue Boards', :js do
find('.dropdown-menu-close').click find('.dropdown-menu-close').click
page.within(find('.board:nth-child(2)')) do page.within(find('.board:nth-child(2)')) do
find('.board-delete').click accept_confirm { find('.board-delete').click }
end end
wait_for_requests wait_for_requests
...@@ -379,7 +380,7 @@ describe 'Issue Boards', :js do ...@@ -379,7 +380,7 @@ describe 'Issue Boards', :js do
end end
it 'filters by milestone' do it 'filters by milestone' do
set_filter("milestone", "\"#{milestone.title}\"") set_filter("milestone", "\"#{milestone.title}")
click_filter_link(milestone.title) click_filter_link(milestone.title)
submit_filter submit_filter
...@@ -400,7 +401,7 @@ describe 'Issue Boards', :js do ...@@ -400,7 +401,7 @@ describe 'Issue Boards', :js do
end end
it 'filters by label with space after reload' do it 'filters by label with space after reload' do
set_filter("label", "\"#{accepting.title}\"") set_filter("label", "\"#{accepting.title}")
click_filter_link(accepting.title) click_filter_link(accepting.title)
submit_filter submit_filter
...@@ -521,7 +522,7 @@ describe 'Issue Boards', :js do ...@@ -521,7 +522,7 @@ describe 'Issue Boards', :js do
end end
it 'allows user to use keyboard shortcuts' do it 'allows user to use keyboard shortcuts' do
find('.boards-list').native.send_keys('i') find('body').native.send_keys('i')
expect(page).to have_content('New Issue') expect(page).to have_content('New Issue')
end end
end end
...@@ -563,6 +564,9 @@ describe 'Issue Boards', :js do ...@@ -563,6 +564,9 @@ describe 'Issue Boards', :js do
end end
def drag(selector: '.board-list', list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0) def drag(selector: '.board-list', list_from_index: 0, from_index: 0, to_index: 0, list_to_index: 0)
# ensure there is enough horizontal space for four boards
resize_window(2000, 800)
drag_to(selector: selector, drag_to(selector: selector,
scrollable: '#board-app', scrollable: '#board-app',
list_from_index: list_from_index, list_from_index: list_from_index,
......
...@@ -51,7 +51,7 @@ describe 'Issue Boards', :js do ...@@ -51,7 +51,7 @@ describe 'Issue Boards', :js do
expect(page).to have_selector('.issue-boards-sidebar') 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') expect(page).not_to have_selector('.issue-boards-sidebar')
end end
...@@ -171,7 +171,7 @@ describe 'Issue Boards', :js do ...@@ -171,7 +171,7 @@ describe 'Issue Boards', :js do
end end
page.within(find('.board:nth-child(2)')) do page.within(find('.board:nth-child(2)')) do
find('.card:nth-child(2)').trigger('click') find('.card:nth-child(2)').click
end end
page.within('.assignee') do page.within('.assignee') do
......
...@@ -63,8 +63,8 @@ feature 'Contributions Calendar', :js do ...@@ -63,8 +63,8 @@ feature 'Contributions Calendar', :js do
Event.create(note_comment_params) Event.create(note_comment_params)
end end
def selected_day_activities def selected_day_activities(visible: true)
find('.user-calendar-activities').text find('.user-calendar-activities', visible: visible).text
end end
before do before do
...@@ -112,7 +112,7 @@ feature 'Contributions Calendar', :js do ...@@ -112,7 +112,7 @@ feature 'Contributions Calendar', :js do
end end
it 'hides calendar day activities' do it 'hides calendar day activities' do
expect(selected_day_activities).to be_empty expect(selected_day_activities(visible: false)).to be_empty
end end
end end
end end
......
...@@ -47,7 +47,7 @@ describe "Container Registry", :js do ...@@ -47,7 +47,7 @@ describe "Container Registry", :js do
scenario 'user removes a specific tag from container repository' do scenario 'user removes a specific tag from container repository' do
visit_container_registry visit_container_registry
find('.js-toggle-repo').trigger('click') find('.js-toggle-repo').click
wait_for_requests wait_for_requests
expect_any_instance_of(ContainerRegistry::Tag) expect_any_instance_of(ContainerRegistry::Tag)
......
...@@ -13,7 +13,7 @@ RSpec.describe 'Dashboard Group' do ...@@ -13,7 +13,7 @@ RSpec.describe 'Dashboard Group' do
it 'creates new group', :js do it 'creates new group', :js do
visit dashboard_groups_path visit dashboard_groups_path
find('.btn-new').trigger('click') find('.btn-new').click
new_path = 'Samurai' new_path = 'Samurai'
new_description = 'Tokugawa Shogunate' new_description = 'Tokugawa Shogunate'
......
...@@ -138,7 +138,7 @@ feature 'Dashboard Groups page', :js do ...@@ -138,7 +138,7 @@ feature 'Dashboard Groups page', :js do
expect(page).not_to have_selector("#group-#{group.id}") expect(page).not_to have_selector("#group-#{group.id}")
# Go to next page # Go to next page
find(".gl-pagination .page:not(.active) a").trigger('click') find(".gl-pagination .page:not(.active) a").click
wait_for_requests wait_for_requests
......
...@@ -33,7 +33,7 @@ RSpec.describe 'Dashboard Issues' do ...@@ -33,7 +33,7 @@ RSpec.describe 'Dashboard Issues' do
end end
it 'shows issues when current user is author', :js do it 'shows issues when current user is author', :js do
find('#assignee_id', visible: false).set('') execute_script("document.querySelector('#assignee_id').value=''")
find('.js-author-search', match: :first).click find('.js-author-search', match: :first).click
expect(find('li[data-user-id="null"] a.is-active')).to be_visible expect(find('li[data-user-id="null"] a.is-active')).to be_visible
...@@ -71,7 +71,7 @@ RSpec.describe 'Dashboard Issues' do ...@@ -71,7 +71,7 @@ RSpec.describe 'Dashboard Issues' do
describe 'new issue dropdown' do describe 'new issue dropdown' do
it 'shows projects only with issues feature enabled', :js do it 'shows projects only with issues feature enabled', :js do
find('.new-project-item-select-button').trigger('click') find('.new-project-item-select-button').click
page.within('.select2-results') do page.within('.select2-results') do
expect(page).to have_content(project.name_with_namespace) expect(page).to have_content(project.name_with_namespace)
...@@ -80,7 +80,7 @@ RSpec.describe 'Dashboard Issues' do ...@@ -80,7 +80,7 @@ RSpec.describe 'Dashboard Issues' do
end end
it 'shows the new issue page', :js do it 'shows the new issue page', :js do
find('.new-project-item-select-button').trigger('click') find('.new-project-item-select-button').click
wait_for_requests wait_for_requests
...@@ -93,7 +93,7 @@ RSpec.describe 'Dashboard Issues' do ...@@ -93,7 +93,7 @@ RSpec.describe 'Dashboard Issues' do
find('#select2-drop-mask', visible: false) find('#select2-drop-mask', visible: false)
execute_script("$('#select2-drop-mask').remove();") execute_script("$('#select2-drop-mask').remove();")
find('.new-project-item-link').trigger('click') find('.new-project-item-link').click
expect(page).to have_current_path("#{project_path}/issues/new") expect(page).to have_current_path("#{project_path}/issues/new")
......
...@@ -25,7 +25,7 @@ feature 'Dashboard Merge Requests' do ...@@ -25,7 +25,7 @@ feature 'Dashboard Merge Requests' do
end end
it 'shows projects only with merge requests feature enabled', :js do it 'shows projects only with merge requests feature enabled', :js do
find('.new-project-item-select-button').trigger('click') find('.new-project-item-select-button').click
page.within('.select2-results') do page.within('.select2-results') do
expect(page).to have_content(project.name_with_namespace) expect(page).to have_content(project.name_with_namespace)
......
...@@ -252,7 +252,7 @@ feature 'Dashboard Todos' do ...@@ -252,7 +252,7 @@ feature 'Dashboard Todos' do
describe 'mark all as done', :js do describe 'mark all as done', :js do
before do before do
visit dashboard_todos_path visit dashboard_todos_path
find('.js-todos-mark-all').trigger('click') find('.js-todos-mark-all').click
end end
it 'shows "All done" message!' do it 'shows "All done" message!' do
...@@ -309,9 +309,9 @@ feature 'Dashboard Todos' do ...@@ -309,9 +309,9 @@ feature 'Dashboard Todos' do
end end
def mark_all_and_undo def mark_all_and_undo
find('.js-todos-mark-all').trigger('click') find('.js-todos-mark-all').click
wait_for_requests wait_for_requests
find('.js-todos-undo-all').trigger('click') find('.js-todos-undo-all').click
wait_for_requests wait_for_requests
end end
end end
......
require 'spec_helper' require 'spec_helper'
describe 'Discussion Comments Merge Request', :js do describe 'Discussion Comments Commit', :js do
include RepoHelpers include RepoHelpers
let(:user) { create(:user) } let(:user) { create(:user) }
......
require 'spec_helper' require 'spec_helper'
describe 'Discussion Comments Issue', :js do describe 'Discussion Comments Snippet', :js do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { create(:project) } let(:project) { create(:project) }
let(:snippet) { create(:project_snippet, :private, project: project, author: user) } let(:snippet) { create(:project_snippet, :private, project: project, author: user) }
......
...@@ -65,9 +65,9 @@ feature 'Top Plus Menu', :js do ...@@ -65,9 +65,9 @@ feature 'Top Plus Menu', :js do
visit project_path(project) visit project_path(project)
page.within '.header-content' do 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) 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 end
expect(page).to have_content('New Snippet') expect(page).to have_content('New Snippet')
...@@ -87,9 +87,9 @@ feature 'Top Plus Menu', :js do ...@@ -87,9 +87,9 @@ feature 'Top Plus Menu', :js do
visit group_path(group) visit group_path(group)
page.within '.header-content' do 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) 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 end
expect(page).to have_content('Project path') expect(page).to have_content('Project path')
...@@ -155,7 +155,7 @@ feature 'Top Plus Menu', :js do ...@@ -155,7 +155,7 @@ feature 'Top Plus Menu', :js do
def click_topmenuitem(item_name) def click_topmenuitem(item_name)
page.within '.header-content' do 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) expect(page).to have_selector('.header-new.dropdown.open', count: 1)
click_link item_name click_link item_name
end end
......
...@@ -65,7 +65,7 @@ feature 'Group' do ...@@ -65,7 +65,7 @@ feature 'Group' do
end end
it 'updates the team URL on graph path update', :js do it 'updates the team URL on graph path update', :js do
out_span = find('span[data-bind-out="create_chat_team"]') out_span = find('span[data-bind-out="create_chat_team"]', visible: false)
expect(out_span.text).to be_empty expect(out_span.text).to be_empty
......
...@@ -405,7 +405,7 @@ feature 'Issues > Labels bulk assignment' do ...@@ -405,7 +405,7 @@ feature 'Issues > Labels bulk assignment' do
end end
def update_issues def update_issues
find('.update-selected-issues').trigger('click') find('.update-selected-issues').click
wait_for_requests wait_for_requests
end end
......
...@@ -43,15 +43,16 @@ describe 'Dropdown assignee', :js do ...@@ -43,15 +43,16 @@ describe 'Dropdown assignee', :js do
end end
it 'should show loading indicator when opened' do it 'should show loading indicator when opened' do
filtered_search.set('assignee:') slow_requests do
filtered_search.set('assignee:')
expect(page).to have_css('#js-dropdown-assignee .filter-dropdown-loading', visible: true) expect(page).to have_css('#js-dropdown-assignee .filter-dropdown-loading', visible: true)
end
end end
it 'should hide loading indicator when loaded' do it 'should hide loading indicator when loaded' do
filtered_search.set('assignee:') filtered_search.set('assignee:')
expect(find(js_dropdown_assignee)).to have_css('.filter-dropdown-loading')
expect(find(js_dropdown_assignee)).not_to have_css('.filter-dropdown-loading') expect(find(js_dropdown_assignee)).not_to have_css('.filter-dropdown-loading')
end end
......
...@@ -51,9 +51,11 @@ describe 'Dropdown author', :js do ...@@ -51,9 +51,11 @@ describe 'Dropdown author', :js do
end end
it 'should show loading indicator when opened' do it 'should show loading indicator when opened' do
filtered_search.set('author:') slow_requests do
filtered_search.set('author:')
expect(page).to have_css('#js-dropdown-author .filter-dropdown-loading', visible: true) expect(page).to have_css('#js-dropdown-author .filter-dropdown-loading', visible: true)
end
end end
it 'should hide loading indicator when loaded' do it 'should hide loading indicator when loaded' do
......
...@@ -70,9 +70,11 @@ describe 'Dropdown emoji', :js do ...@@ -70,9 +70,11 @@ describe 'Dropdown emoji', :js do
end end
it 'should show loading indicator when opened' do it 'should show loading indicator when opened' do
filtered_search.set('my-reaction:') slow_requests do
filtered_search.set('my-reaction:')
expect(page).to have_css('#js-dropdown-my-reaction .filter-dropdown-loading', visible: true) expect(page).to have_css('#js-dropdown-my-reaction .filter-dropdown-loading', visible: true)
end
end end
it 'should hide loading indicator when loaded' do it 'should hide loading indicator when loaded' do
......
...@@ -66,9 +66,11 @@ describe 'Dropdown label', :js do ...@@ -66,9 +66,11 @@ describe 'Dropdown label', :js do
end end
it 'shows loading indicator when opened and hides it when loaded' do it 'shows loading indicator when opened and hides it when loaded' do
filtered_search.set('label:') slow_requests do
filtered_search.set('label:')
expect(find(js_dropdown_label)).to have_css('.filter-dropdown-loading') expect(page).to have_css("#{js_dropdown_label} .filter-dropdown-loading", visible: true)
end
expect(find(js_dropdown_label)).not_to have_css('.filter-dropdown-loading') expect(find(js_dropdown_label)).not_to have_css('.filter-dropdown-loading')
end end
......
...@@ -50,15 +50,16 @@ describe 'Dropdown milestone', :js do ...@@ -50,15 +50,16 @@ describe 'Dropdown milestone', :js do
end end
it 'should show loading indicator when opened' do it 'should show loading indicator when opened' do
filtered_search.set('milestone:') slow_requests do
filtered_search.set('milestone:')
expect(page).to have_css('#js-dropdown-milestone .filter-dropdown-loading', visible: true) expect(page).to have_css('#js-dropdown-milestone .filter-dropdown-loading', visible: true)
end
end end
it 'should hide loading indicator when loaded' do it 'should hide loading indicator when loaded' do
filtered_search.set('milestone:') filtered_search.set('milestone:')
expect(find(js_dropdown_milestone)).to have_css('.filter-dropdown-loading')
expect(find(js_dropdown_milestone)).not_to have_css('.filter-dropdown-loading') expect(find(js_dropdown_milestone)).not_to have_css('.filter-dropdown-loading')
end end
......
...@@ -139,7 +139,7 @@ describe 'Filter issues', :js do ...@@ -139,7 +139,7 @@ describe 'Filter issues', :js do
input_filtered_search('label:none') input_filtered_search('label:none')
expect_tokens([label_token('none', false)]) expect_tokens([label_token('none', false)])
expect_issues_list_count(8) expect_issues_list_count(4)
expect_filtered_search_input_empty expect_filtered_search_input_empty
end end
......
...@@ -76,7 +76,8 @@ describe 'Recent searches', :js do ...@@ -76,7 +76,8 @@ describe 'Recent searches', :js do
set_recent_searches(project_1_local_storage_key, '["foo", "bar"]') set_recent_searches(project_1_local_storage_key, '["foo", "bar"]')
visit project_issues_path(project_1) visit project_issues_path(project_1)
all('.filtered-search-history-dropdown-item', visible: false, count: 2)[0].trigger('click') find('.filtered-search-history-dropdown-toggle-button').click
all('.filtered-search-history-dropdown-item', count: 2)[0].click
wait_for_filtered_search('foo') wait_for_filtered_search('foo')
expect(find('.filtered-search').value.strip).to eq('foo') expect(find('.filtered-search').value.strip).to eq('foo')
...@@ -86,10 +87,11 @@ describe 'Recent searches', :js do ...@@ -86,10 +87,11 @@ describe 'Recent searches', :js do
set_recent_searches(project_1_local_storage_key, '["foo"]') set_recent_searches(project_1_local_storage_key, '["foo"]')
visit project_issues_path(project_1) visit project_issues_path(project_1)
all('.filtered-search-history-dropdown-item', visible: false, count: 1) find('.filtered-search-history-dropdown-toggle-button').click
all('.filtered-search-history-dropdown-item', count: 1)
find('.filtered-search-history-clear-button', visible: false).trigger('click') find('.filtered-search-history-clear-button').click
items_after = all('.filtered-search-history-dropdown-item', visible: false, count: 0) items_after = all('.filtered-search-history-dropdown-item', count: 0)
expect(items_after.count).to eq(0) expect(items_after.count).to eq(0)
end end
......
...@@ -2,7 +2,6 @@ require 'rails_helper' ...@@ -2,7 +2,6 @@ require 'rails_helper'
describe 'Visual tokens', :js do describe 'Visual tokens', :js do
include FilteredSearchHelpers include FilteredSearchHelpers
include WaitForRequests
let!(:project) { create(:project) } let!(:project) { create(:project) }
let!(:user) { create(:user, name: 'administrator', username: 'root') } let!(:user) { create(:user, name: 'administrator', username: 'root') }
...@@ -28,7 +27,7 @@ describe 'Visual tokens', :js do ...@@ -28,7 +27,7 @@ describe 'Visual tokens', :js do
sign_in(user) sign_in(user)
create(:issue, project: project) create(:issue, project: project)
page.driver.set_cookie('sidebar_collapsed', 'true') set_cookie('sidebar_collapsed', 'true')
visit project_issues_path(project) visit project_issues_path(project)
end end
......
...@@ -17,9 +17,9 @@ feature 'GFM autocomplete', :js do ...@@ -17,9 +17,9 @@ feature 'GFM autocomplete', :js do
it 'updates issue descripton with GFM reference' do it 'updates issue descripton with GFM reference' do
find('.issuable-edit').click find('.issuable-edit').click
find('#issue-description').native.send_keys("@#{user.name[0...3]}") simulate_input('#issue-description', "@#{user.name[0...3]}")
find('.atwho-view .cur').trigger('click') find('.atwho-view .cur').click
click_button 'Save changes' click_button 'Save changes'
...@@ -28,7 +28,6 @@ feature 'GFM autocomplete', :js do ...@@ -28,7 +28,6 @@ feature 'GFM autocomplete', :js do
it 'opens autocomplete menu when field starts with text' do it 'opens autocomplete menu when field starts with text' do
page.within '.timeline-content-form' do page.within '.timeline-content-form' do
find('#note-body').native.send_keys('')
find('#note-body').native.send_keys('@') find('#note-body').native.send_keys('@')
end end
...@@ -46,7 +45,6 @@ feature 'GFM autocomplete', :js do ...@@ -46,7 +45,6 @@ feature 'GFM autocomplete', :js do
it 'doesnt select the first item for non-assignee dropdowns' do it 'doesnt select the first item for non-assignee dropdowns' do
page.within '.timeline-content-form' do page.within '.timeline-content-form' do
find('#note-body').native.send_keys('')
find('#note-body').native.send_keys(':') find('#note-body').native.send_keys(':')
end end
...@@ -86,7 +84,6 @@ feature 'GFM autocomplete', :js do ...@@ -86,7 +84,6 @@ feature 'GFM autocomplete', :js do
it 'selects the first item for assignee dropdowns' do it 'selects the first item for assignee dropdowns' do
page.within '.timeline-content-form' do page.within '.timeline-content-form' do
find('#note-body').native.send_keys('')
find('#note-body').native.send_keys('@') find('#note-body').native.send_keys('@')
end end
...@@ -100,7 +97,7 @@ feature 'GFM autocomplete', :js do ...@@ -100,7 +97,7 @@ feature 'GFM autocomplete', :js do
it 'includes items for assignee dropdowns with non-ASCII characters in name' do it 'includes items for assignee dropdowns with non-ASCII characters in name' do
page.within '.timeline-content-form' do page.within '.timeline-content-form' do
find('#note-body').native.send_keys('') find('#note-body').native.send_keys('')
find('#note-body').native.send_keys("@#{user.name[0...8]}") simulate_input('#note-body', "@#{user.name[0...8]}")
end end
expect(page).to have_selector('.atwho-container') expect(page).to have_selector('.atwho-container')
...@@ -112,7 +109,6 @@ feature 'GFM autocomplete', :js do ...@@ -112,7 +109,6 @@ feature 'GFM autocomplete', :js do
it 'selects the first item for non-assignee dropdowns if a query is entered' do it 'selects the first item for non-assignee dropdowns if a query is entered' do
page.within '.timeline-content-form' do page.within '.timeline-content-form' do
find('#note-body').native.send_keys('')
find('#note-body').native.send_keys(':1') find('#note-body').native.send_keys(':1')
end end
...@@ -127,9 +123,8 @@ feature 'GFM autocomplete', :js do ...@@ -127,9 +123,8 @@ feature 'GFM autocomplete', :js do
it 'wraps the result in double quotes' do it 'wraps the result in double quotes' do
note = find('#note-body') note = find('#note-body')
page.within '.timeline-content-form' do page.within '.timeline-content-form' do
note.native.send_keys('') find('#note-body').native.send_keys('')
note.native.send_keys("~#{label.title[0]}") simulate_input('#note-body', "~#{label.title[0]}")
note.click
end end
label_item = find('.atwho-view li', text: label.title) label_item = find('.atwho-view li', text: label.title)
...@@ -152,16 +147,13 @@ feature 'GFM autocomplete', :js do ...@@ -152,16 +147,13 @@ feature 'GFM autocomplete', :js do
it "does not show dropdown when preceded with a special character" do it "does not show dropdown when preceded with a special character" do
note = find('#note-body') note = find('#note-body')
page.within '.timeline-content-form' do page.within '.timeline-content-form' do
note.native.send_keys('')
note.native.send_keys("@") note.native.send_keys("@")
note.click
end end
expect(page).to have_selector('.atwho-container') expect(page).to have_selector('.atwho-container')
page.within '.timeline-content-form' do page.within '.timeline-content-form' do
note.native.send_keys("@") note.native.send_keys("@")
note.click
end end
expect(page).to have_selector('.atwho-container', visible: false) expect(page).to have_selector('.atwho-container', visible: false)
...@@ -170,9 +162,7 @@ feature 'GFM autocomplete', :js do ...@@ -170,9 +162,7 @@ feature 'GFM autocomplete', :js do
it "does not throw an error if no labels exist" do it "does not throw an error if no labels exist" do
note = find('#note-body') note = find('#note-body')
page.within '.timeline-content-form' do page.within '.timeline-content-form' do
note.native.send_keys('')
note.native.send_keys('~') note.native.send_keys('~')
note.click
end end
expect(page).to have_selector('.atwho-container', visible: false) expect(page).to have_selector('.atwho-container', visible: false)
...@@ -181,9 +171,7 @@ feature 'GFM autocomplete', :js do ...@@ -181,9 +171,7 @@ feature 'GFM autocomplete', :js do
it 'doesn\'t wrap for assignee values' do it 'doesn\'t wrap for assignee values' do
note = find('#note-body') note = find('#note-body')
page.within '.timeline-content-form' do page.within '.timeline-content-form' do
note.native.send_keys('')
note.native.send_keys("@#{user.username[0]}") note.native.send_keys("@#{user.username[0]}")
note.click
end end
user_item = find('.atwho-view li', text: user.username) user_item = find('.atwho-view li', text: user.username)
...@@ -194,9 +182,7 @@ feature 'GFM autocomplete', :js do ...@@ -194,9 +182,7 @@ feature 'GFM autocomplete', :js do
it 'doesn\'t wrap for emoji values' do it 'doesn\'t wrap for emoji values' do
note = find('#note-body') note = find('#note-body')
page.within '.timeline-content-form' do page.within '.timeline-content-form' do
note.native.send_keys('') note.native.send_keys(":cartwheel_")
note.native.send_keys(":cartwheel")
note.click
end end
emoji_item = find('.atwho-view li', text: 'cartwheel_tone1') emoji_item = find('.atwho-view li', text: 'cartwheel_tone1')
...@@ -223,12 +209,11 @@ feature 'GFM autocomplete', :js do ...@@ -223,12 +209,11 @@ feature 'GFM autocomplete', :js do
it 'triggers autocomplete after selecting a quick action' do it 'triggers autocomplete after selecting a quick action' do
note = find('#note-body') note = find('#note-body')
page.within '.timeline-content-form' do page.within '.timeline-content-form' do
note.native.send_keys('')
note.native.send_keys('/as') note.native.send_keys('/as')
note.click
end end
find('.atwho-view li', text: '/assign').native.send_keys(:tab) find('.atwho-view li', text: '/assign')
note.native.send_keys(:tab)
user_item = find('.atwho-view li', text: user.username) user_item = find('.atwho-view li', text: user.username)
expect(user_item).to have_content(user.username) expect(user_item).to have_content(user.username)
......
...@@ -130,8 +130,8 @@ feature 'Issue Sidebar' do ...@@ -130,8 +130,8 @@ feature 'Issue Sidebar' do
it 'adds new label' do it 'adds new label' do
page.within('.block.labels') do page.within('.block.labels') do
fill_in 'new_label_name', with: 'wontfix' fill_in 'new_label_name', with: 'wontfix'
page.find('.suggest-colors a', match: :first).trigger('click') page.find('.suggest-colors a', match: :first).click
page.find('button', text: 'Create').trigger('click') page.find('button', text: 'Create').click
page.within('.dropdown-page-one') do page.within('.dropdown-page-one') do
expect(page).to have_content 'wontfix' expect(page).to have_content 'wontfix'
...@@ -142,8 +142,8 @@ feature 'Issue Sidebar' do ...@@ -142,8 +142,8 @@ feature 'Issue Sidebar' do
it 'shows error message if label title is taken' do it 'shows error message if label title is taken' do
page.within('.block.labels') do page.within('.block.labels') do
fill_in 'new_label_name', with: label.title fill_in 'new_label_name', with: label.title
page.find('.suggest-colors a', match: :first).trigger('click') page.find('.suggest-colors a', match: :first).click
page.find('button', text: 'Create').trigger('click') page.find('button', text: 'Create').click
page.within('.dropdown-page-two') do page.within('.dropdown-page-two') do
expect(page).to have_content 'Title has already been taken' expect(page).to have_content 'Title has already been taken'
...@@ -170,7 +170,7 @@ feature 'Issue Sidebar' do ...@@ -170,7 +170,7 @@ feature 'Issue Sidebar' do
end end
def open_issue_sidebar 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') find('aside.right-sidebar.right-sidebar-expanded')
end end
end end
...@@ -38,7 +38,7 @@ feature 'issue move to another project' do ...@@ -38,7 +38,7 @@ feature 'issue move to another project' do
end end
scenario 'moving issue to another project', :js do scenario 'moving issue to another project', :js do
find('.js-move-issue').trigger('click') find('.js-move-issue').click
wait_for_requests wait_for_requests
all('.js-move-issue-dropdown-item')[0].click all('.js-move-issue-dropdown-item')[0].click
find('.js-move-issue-confirmation-button').click find('.js-move-issue-confirmation-button').click
...@@ -52,7 +52,7 @@ feature 'issue move to another project' do ...@@ -52,7 +52,7 @@ feature 'issue move to another project' do
scenario 'searching project dropdown', :js do scenario 'searching project dropdown', :js do
new_project_search.team << [user, :reporter] new_project_search.team << [user, :reporter]
find('.js-move-issue').trigger('click') find('.js-move-issue').click
wait_for_requests wait_for_requests
page.within '.js-sidebar-move-issue-block' do page.within '.js-sidebar-move-issue-block' do
...@@ -69,7 +69,7 @@ feature 'issue move to another project' do ...@@ -69,7 +69,7 @@ feature 'issue move to another project' do
background { another_project.team << [user, :guest] } background { another_project.team << [user, :guest] }
scenario 'browsing projects in projects select' do scenario 'browsing projects in projects select' do
find('.js-move-issue').trigger('click') find('.js-move-issue').click
wait_for_requests wait_for_requests
page.within '.js-sidebar-move-issue-block' do page.within '.js-sidebar-move-issue-block' do
......
...@@ -118,7 +118,7 @@ feature 'Multiple issue updating from issues#index', :js do ...@@ -118,7 +118,7 @@ feature 'Multiple issue updating from issues#index', :js do
end end
def click_update_issues_button def click_update_issues_button
find('.update-selected-issues').trigger('click') find('.update-selected-issues').click
wait_for_requests wait_for_requests
end end
end end
...@@ -226,7 +226,7 @@ feature 'Issues > User uses quick actions', :js do ...@@ -226,7 +226,7 @@ feature 'Issues > User uses quick actions', :js do
end end
it 'applies the commands to both issues and moves the issue' do it 'applies the commands to both issues and moves the issue' do
write_note("/label ~#{bug.title} ~#{wontfix.title}\n/milestone %\"#{milestone.title}\"\n/move #{target_project.full_path}") write_note("/label ~#{bug.title} ~#{wontfix.title}\n\n/milestone %\"#{milestone.title}\"\n\n/move #{target_project.full_path}")
expect(page).to have_content 'Commands applied' expect(page).to have_content 'Commands applied'
expect(issue.reload).to be_closed expect(issue.reload).to be_closed
...@@ -245,7 +245,7 @@ feature 'Issues > User uses quick actions', :js do ...@@ -245,7 +245,7 @@ feature 'Issues > User uses quick actions', :js do
end end
it 'moves the issue and applies the commands to both issues' do it 'moves the issue and applies the commands to both issues' do
write_note("/move #{target_project.full_path}\n/label ~#{bug.title} ~#{wontfix.title}\n/milestone %\"#{milestone.title}\"") write_note("/move #{target_project.full_path}\n\n/label ~#{bug.title} ~#{wontfix.title}\n\n/milestone %\"#{milestone.title}\"")
expect(page).to have_content 'Commands applied' expect(page).to have_content 'Commands applied'
expect(issue.reload).to be_closed expect(issue.reload).to be_closed
......
...@@ -367,7 +367,7 @@ describe 'Issues' do ...@@ -367,7 +367,7 @@ describe 'Issues' do
it 'changes incoming email address token', :js do it 'changes incoming email address token', :js do
find('.issue-email-modal-btn').click find('.issue-email-modal-btn').click
previous_token = find('input#issue_email').value previous_token = find('input#issue_email').value
find('.incoming-email-token-reset').trigger('click') find('.incoming-email-token-reset').click
wait_for_requests wait_for_requests
...@@ -585,9 +585,11 @@ describe 'Issues' do ...@@ -585,9 +585,11 @@ describe 'Issues' do
end end
it "cancels a file upload correctly" do it "cancels a file upload correctly" do
dropzone_file([Rails.root.join('spec', 'fixtures', 'dk.png')], 0, false) slow_requests do
dropzone_file([Rails.root.join('spec', 'fixtures', 'dk.png')], 0, false)
click_button 'Cancel' click_button 'Cancel'
end
expect(page).to have_button('Attach a file') expect(page).to have_button('Attach a file')
expect(page).not_to have_button('Cancel') expect(page).not_to have_button('Cancel')
......
...@@ -23,11 +23,11 @@ feature 'Merge request conflict resolution', :js do ...@@ -23,11 +23,11 @@ feature 'Merge request conflict resolution', :js do
within find('.files-wrapper .diff-file', text: 'files/ruby/regex.rb') do within find('.files-wrapper .diff-file', text: 'files/ruby/regex.rb') do
all('button', text: 'Use ours').each do |button| all('button', text: 'Use ours').each do |button|
button.trigger('click') button.send_keys(:return)
end end
end end
click_button 'Commit conflict resolution' find_button('Commit conflict resolution').send_keys(:return)
expect(page).to have_content('All merge conflicts were resolved') expect(page).to have_content('All merge conflicts were resolved')
merge_request.reload_diff merge_request.reload_diff
...@@ -71,7 +71,7 @@ feature 'Merge request conflict resolution', :js do ...@@ -71,7 +71,7 @@ feature 'Merge request conflict resolution', :js do
execute_script('ace.edit($(".files-wrapper .diff-file pre")[1]).setValue("Gregor Samsa woke from troubled dreams");') execute_script('ace.edit($(".files-wrapper .diff-file pre")[1]).setValue("Gregor Samsa woke from troubled dreams");')
end end
click_button 'Commit conflict resolution' find_button('Commit conflict resolution').send_keys(:return)
expect(page).to have_content('All merge conflicts were resolved') expect(page).to have_content('All merge conflicts were resolved')
merge_request.reload_diff merge_request.reload_diff
......
...@@ -22,7 +22,7 @@ feature 'Diff note avatars', :js do ...@@ -22,7 +22,7 @@ feature 'Diff note avatars', :js do
project.team << [user, :master] project.team << [user, :master]
sign_in user sign_in user
page.driver.set_cookie('sidebar_collapsed', 'true') set_cookie('sidebar_collapsed', 'true')
end end
context 'discussion tab' do context 'discussion tab' do
...@@ -56,7 +56,7 @@ feature 'Diff note avatars', :js do ...@@ -56,7 +56,7 @@ feature 'Diff note avatars', :js do
end end
it 'does not render avatar after commenting' do it 'does not render avatar after commenting' do
first('.diff-line-num').trigger('mouseover') first('.diff-line-num').click
find('.js-add-diff-note-button').click find('.js-add-diff-note-button').click
page.within('.js-discussion-note-form') do page.within('.js-discussion-note-form') do
...@@ -85,7 +85,7 @@ feature 'Diff note avatars', :js do ...@@ -85,7 +85,7 @@ feature 'Diff note avatars', :js do
it 'shows note avatar' do it 'shows note avatar' do
page.within find_line(position.line_code(project.repository)) do page.within find_line(position.line_code(project.repository)) do
find('.diff-notes-collapse').click find('.diff-notes-collapse').send_keys(:return)
expect(page).to have_selector('img.js-diff-comment-avatar', count: 1) expect(page).to have_selector('img.js-diff-comment-avatar', count: 1)
end end
...@@ -93,7 +93,7 @@ feature 'Diff note avatars', :js do ...@@ -93,7 +93,7 @@ feature 'Diff note avatars', :js do
it 'shows comment on note avatar' do it 'shows comment on note avatar' do
page.within find_line(position.line_code(project.repository)) do page.within find_line(position.line_code(project.repository)) do
find('.diff-notes-collapse').click find('.diff-notes-collapse').send_keys(:return)
expect(first('img.js-diff-comment-avatar')["data-original-title"]).to eq("#{note.author.name}: #{note.note.truncate(17)}") expect(first('img.js-diff-comment-avatar')["data-original-title"]).to eq("#{note.author.name}: #{note.note.truncate(17)}")
end end
...@@ -101,7 +101,7 @@ feature 'Diff note avatars', :js do ...@@ -101,7 +101,7 @@ feature 'Diff note avatars', :js do
it 'toggles comments when clicking avatar' do it 'toggles comments when clicking avatar' do
page.within find_line(position.line_code(project.repository)) do page.within find_line(position.line_code(project.repository)) do
find('.diff-notes-collapse').click find('.diff-notes-collapse').send_keys(:return)
end end
expect(page).to have_selector('.notes_holder', visible: false) expect(page).to have_selector('.notes_holder', visible: false)
...@@ -117,7 +117,7 @@ feature 'Diff note avatars', :js do ...@@ -117,7 +117,7 @@ feature 'Diff note avatars', :js do
open_more_actions_dropdown(note) open_more_actions_dropdown(note)
page.within find(".note-row-#{note.id}") do page.within find(".note-row-#{note.id}") do
find('.js-note-delete').click accept_confirm { find('.js-note-delete').click }
end end
wait_for_requests wait_for_requests
...@@ -139,7 +139,7 @@ feature 'Diff note avatars', :js do ...@@ -139,7 +139,7 @@ feature 'Diff note avatars', :js do
end end
page.within find_line(position.line_code(project.repository)) do page.within find_line(position.line_code(project.repository)) do
find('.diff-notes-collapse').trigger('click') find('.diff-notes-collapse').send_keys(:return)
expect(page).to have_selector('img.js-diff-comment-avatar', count: 2) expect(page).to have_selector('img.js-diff-comment-avatar', count: 2)
end end
...@@ -152,14 +152,14 @@ feature 'Diff note avatars', :js do ...@@ -152,14 +152,14 @@ feature 'Diff note avatars', :js do
page.within '.js-discussion-note-form' do page.within '.js-discussion-note-form' do
find('.js-note-text').native.send_keys('Test') find('.js-note-text').native.send_keys('Test')
find('.js-comment-button').trigger('click') find('.js-comment-button').click
wait_for_requests wait_for_requests
end end
end end
page.within find_line(position.line_code(project.repository)) do page.within find_line(position.line_code(project.repository)) do
find('.diff-notes-collapse').trigger('click') find('.diff-notes-collapse').send_keys(:return)
expect(page).to have_selector('img.js-diff-comment-avatar', count: 3) expect(page).to have_selector('img.js-diff-comment-avatar', count: 3)
expect(find('.diff-comments-more-count')).to have_content '+1' expect(find('.diff-comments-more-count')).to have_content '+1'
...@@ -177,7 +177,7 @@ feature 'Diff note avatars', :js do ...@@ -177,7 +177,7 @@ feature 'Diff note avatars', :js do
it 'shows extra comment count' do it 'shows extra comment count' do
page.within find_line(position.line_code(project.repository)) do page.within find_line(position.line_code(project.repository)) do
find('.diff-notes-collapse').click find('.diff-notes-collapse').send_keys(:return)
expect(find('.diff-comments-more-count')).to have_content '+1' expect(find('.diff-comments-more-count')).to have_content '+1'
end end
......
...@@ -192,7 +192,7 @@ feature 'Diff notes resolve', :js do ...@@ -192,7 +192,7 @@ feature 'Diff notes resolve', :js do
page.find('.discussion-next-btn').click page.find('.discussion-next-btn').click
end end
expect(page.evaluate_script("$('body').scrollTop()")).to be > 0 expect(page.evaluate_script("window.pageYOffset")).to be > 0
end end
it 'hides jump to next button when all resolved' do it 'hides jump to next button when all resolved' do
...@@ -241,10 +241,8 @@ feature 'Diff notes resolve', :js do ...@@ -241,10 +241,8 @@ feature 'Diff notes resolve', :js do
end end
it 'resolves discussion' do it 'resolves discussion' do
page.all('.note').each do |note| page.all('.note .line-resolve-btn').each do |button|
note.all('.line-resolve-btn').each do |button| button.click
button.click
end
end end
expect(page).to have_content('Resolved by') expect(page).to have_content('Resolved by')
...@@ -305,10 +303,10 @@ feature 'Diff notes resolve', :js do ...@@ -305,10 +303,10 @@ feature 'Diff notes resolve', :js do
end end
page.within '.line-resolve-all-container' do page.within '.line-resolve-all-container' do
page.find('.discussion-next-btn').trigger('click') page.find('.discussion-next-btn').click
end end
expect(page.evaluate_script("$('body').scrollTop()")).to be > 0 expect(page.evaluate_script("window.pageYOffset")).to be > 0
end end
it 'updates updated text after resolving note' do it 'updates updated text after resolving note' do
......
...@@ -7,14 +7,12 @@ feature 'Diffs URL', :js do ...@@ -7,14 +7,12 @@ feature 'Diffs URL', :js do
let(:merge_request) { create(:merge_request, source_project: project) } let(:merge_request) { create(:merge_request, source_project: project) }
context 'when visit with */* as accept header' do context 'when visit with */* as accept header' do
before do
page.driver.add_header('Accept', '*/*')
end
it 'renders the notes' do it 'renders the notes' do
create :note_on_merge_request, project: project, noteable: merge_request, note: 'Rebasing with master' create :note_on_merge_request, project: project, noteable: merge_request, note: 'Rebasing with master'
visit diffs_project_merge_request_path(project, merge_request) inspect_requests(inject_headers: { 'Accept' => '*/*' }) do
visit diffs_project_merge_request_path(project, merge_request)
end
# Load notes and diff through AJAX # Load notes and diff through AJAX
expect(page).to have_css('.note-text', visible: false, text: 'Rebasing with master') expect(page).to have_css('.note-text', visible: false, text: 'Rebasing with master')
...@@ -90,7 +88,7 @@ feature 'Diffs URL', :js do ...@@ -90,7 +88,7 @@ feature 'Diffs URL', :js do
visit diffs_project_merge_request_path(project, merge_request) visit diffs_project_merge_request_path(project, merge_request)
# Throws `Capybara::Poltergeist::InvalidSelector` if we try to use `#hash` syntax # Throws `Capybara::Poltergeist::InvalidSelector` if we try to use `#hash` syntax
find("[id=\"#{changelog_id}\"] .js-edit-blob").trigger('click') find("[id=\"#{changelog_id}\"] .js-edit-blob").click
expect(page).to have_selector('.js-fork-suggestion-button', count: 1) expect(page).to have_selector('.js-fork-suggestion-button', count: 1)
expect(page).to have_selector('.js-cancel-fork-suggestion-button', count: 1) expect(page).to have_selector('.js-cancel-fork-suggestion-button', count: 1)
......
...@@ -43,7 +43,7 @@ describe 'New/edit merge request', :js do ...@@ -43,7 +43,7 @@ describe 'New/edit merge request', :js do
expect(page).to have_content user2.name expect(page).to have_content user2.name
end end
find('a', text: 'Assign to me').trigger('click') find('a', text: 'Assign to me').click
expect(find('input[name="merge_request[assignee_id]"]', visible: false).value).to match(user.id.to_s) expect(find('input[name="merge_request[assignee_id]"]', visible: false).value).to match(user.id.to_s)
page.within '.js-assignee-search' do page.within '.js-assignee-search' do
expect(page).to have_content user.name expect(page).to have_content user.name
......
...@@ -83,7 +83,7 @@ feature 'Mini Pipeline Graph', :js do ...@@ -83,7 +83,7 @@ feature 'Mini Pipeline Graph', :js do
end end
before do before do
toggle.trigger('click') toggle.click
wait_for_requests wait_for_requests
end end
...@@ -92,7 +92,7 @@ feature 'Mini Pipeline Graph', :js do ...@@ -92,7 +92,7 @@ feature 'Mini Pipeline Graph', :js do
end end
it 'should close when toggle is clicked again' do 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') expect(toggle.find(:xpath, '..')).not_to have_selector('.mini-pipeline-graph-dropdown-menu')
end end
......
...@@ -127,7 +127,7 @@ feature 'Multiple merge requests updating from merge_requests#index' do ...@@ -127,7 +127,7 @@ feature 'Multiple merge requests updating from merge_requests#index' do
end end
def click_update_merge_requests_button def click_update_merge_requests_button
find('.update-selected-issues').trigger('click') find('.update-selected-issues').click
wait_for_requests wait_for_requests
end end
end end
...@@ -8,7 +8,7 @@ feature 'Merge requests > User posts diff notes', :js do ...@@ -8,7 +8,7 @@ feature 'Merge requests > User posts diff notes', :js do
let(:project) { merge_request.source_project } let(:project) { merge_request.source_project }
before do before do
page.driver.set_cookie('sidebar_collapsed', 'true') set_cookie('sidebar_collapsed', 'true')
project.add_developer(user) project.add_developer(user)
sign_in(user) sign_in(user)
...@@ -103,7 +103,10 @@ feature 'Merge requests > User posts diff notes', :js do ...@@ -103,7 +103,10 @@ feature 'Merge requests > User posts diff notes', :js do
it 'allows commenting' do it 'allows commenting' do
should_allow_commenting(find('[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9"]')) should_allow_commenting(find('[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9"]'))
first('.js-note-delete', visible: false).trigger('click') accept_confirm do
first('button.more-actions-toggle').click
first('.js-note-delete').click
end
should_allow_commenting(find('[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9"]')) should_allow_commenting(find('[id="2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9"]'))
end end
...@@ -236,7 +239,7 @@ feature 'Merge requests > User posts diff notes', :js do ...@@ -236,7 +239,7 @@ feature 'Merge requests > User posts diff notes', :js do
def should_allow_dismissing_a_comment(line_holder, diff_side = nil) def should_allow_dismissing_a_comment(line_holder, diff_side = nil)
write_comment_on_line(line_holder, diff_side) 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) assert_comment_dismissal(line_holder)
end end
......
...@@ -141,7 +141,7 @@ describe 'Merge requests > User posts notes', :js do ...@@ -141,7 +141,7 @@ describe 'Merge requests > User posts notes', :js do
end end
it 'removes the attachment div and resets the edit form' do it 'removes the attachment div and resets the edit form' do
find('.js-note-attachment-delete').click accept_confirm { find('.js-note-attachment-delete').click }
is_expected.not_to have_css('.note-attachment') is_expected.not_to have_css('.note-attachment')
is_expected.not_to have_css('.current-note-edit-form') is_expected.not_to have_css('.current-note-edit-form')
wait_for_requests wait_for_requests
......
...@@ -67,8 +67,8 @@ feature 'Merge Request versions', :js do ...@@ -67,8 +67,8 @@ feature 'Merge Request versions', :js do
line_code = '7445606fbf8f3683cd42bdc54b05d7a0bc2dfc44_2_2' line_code = '7445606fbf8f3683cd42bdc54b05d7a0bc2dfc44_2_2'
page.within(diff_file_selector) 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}'] td:nth-of-type(1)").hover
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 page.within("form[data-line-code='#{line_code}']") do
fill_in "note[note]", with: "Typo, please fix" fill_in "note[note]", with: "Typo, please fix"
...@@ -137,8 +137,8 @@ feature 'Merge Request versions', :js do ...@@ -137,8 +137,8 @@ feature 'Merge Request versions', :js do
line_code = '7445606fbf8f3683cd42bdc54b05d7a0bc2dfc44_4_4' line_code = '7445606fbf8f3683cd42bdc54b05d7a0bc2dfc44_4_4'
page.within(diff_file_selector) 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}'] td:nth-of-type(1)").hover
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 page.within("form[data-line-code='#{line_code}']") do
fill_in "note[note]", with: "Typo, please fix" fill_in "note[note]", with: "Typo, please fix"
......
...@@ -42,7 +42,7 @@ feature 'Widget Deployments Header', :js do ...@@ -42,7 +42,7 @@ feature 'Widget Deployments Header', :js do
end end
scenario 'does start build when stop button clicked' do scenario 'does start build when stop button clicked' do
click_button('Stop environment') accept_confirm { click_button('Stop environment') }
expect(page).to have_content('close_app') expect(page).to have_content('close_app')
end end
......
...@@ -65,7 +65,7 @@ describe 'Profile account page', :js do ...@@ -65,7 +65,7 @@ describe 'Profile account page', :js do
within('.rss-token-reset') do within('.rss-token-reset') do
previous_token = find("#rss_token").value previous_token = find("#rss_token").value
click_link('reset it') accept_confirm { click_link('reset it') }
expect(find('#rss_token').value).not_to eq(previous_token) expect(find('#rss_token').value).not_to eq(previous_token)
end end
...@@ -84,7 +84,7 @@ describe 'Profile account page', :js do ...@@ -84,7 +84,7 @@ describe 'Profile account page', :js do
within('.incoming-email-token-reset') do within('.incoming-email-token-reset') do
previous_token = find('#incoming_email_token').value previous_token = find('#incoming_email_token').value
click_link('reset it') accept_confirm { click_link('reset it') }
expect(find('#incoming_email_token').value).not_to eq(previous_token) expect(find('#incoming_email_token').value).not_to eq(previous_token)
end end
......
...@@ -14,7 +14,7 @@ describe 'Profile > Applications' do ...@@ -14,7 +14,7 @@ describe 'Profile > Applications' do
page.within('.oauth-applications') do page.within('.oauth-applications') do
expect(page).to have_content('Your applications (1)') expect(page).to have_content('Your applications (1)')
click_button 'Destroy' accept_confirm { click_button 'Destroy' }
end end
expect(page).to have_content('The application was deleted successfully') expect(page).to have_content('The application was deleted successfully')
...@@ -28,7 +28,7 @@ describe 'Profile > Applications' do ...@@ -28,7 +28,7 @@ describe 'Profile > Applications' do
page.within('.oauth-authorized-applications') do page.within('.oauth-authorized-applications') do
expect(page).to have_content('Authorized applications (1)') expect(page).to have_content('Authorized applications (1)')
click_button 'Revoke' accept_confirm { click_button 'Revoke' }
end end
expect(page).to have_content('The application was revoked access.') expect(page).to have_content('The application was revoked access.')
......
...@@ -34,7 +34,7 @@ describe 'Profile > Personal Access Tokens', :js do ...@@ -34,7 +34,7 @@ describe 'Profile > Personal Access Tokens', :js do
fill_in "Name", with: name fill_in "Name", with: name
# Set date to 1st of next month # Set date to 1st of next month
find_field("Expires at").trigger('focus') find_field("Expires at").click
find(".pika-next").click find(".pika-next").click
click_on "1" click_on "1"
...@@ -78,7 +78,7 @@ describe 'Profile > Personal Access Tokens', :js do ...@@ -78,7 +78,7 @@ describe 'Profile > Personal Access Tokens', :js do
it "allows revocation of an active token" do it "allows revocation of an active token" do
visit profile_personal_access_tokens_path visit profile_personal_access_tokens_path
click_on "Revoke" accept_confirm { click_on "Revoke" }
expect(page).to have_selector(".settings-message") expect(page).to have_selector(".settings-message")
expect(no_personal_access_tokens_message).to have_text("This user has no active Personal Access Tokens.") expect(no_personal_access_tokens_message).to have_text("This user has no active Personal Access Tokens.")
...@@ -100,7 +100,7 @@ describe 'Profile > Personal Access Tokens', :js do ...@@ -100,7 +100,7 @@ describe 'Profile > Personal Access Tokens', :js do
errors = ActiveModel::Errors.new(PersonalAccessToken.new).tap { |e| e.add(:name, "cannot be nil") } errors = ActiveModel::Errors.new(PersonalAccessToken.new).tap { |e| e.add(:name, "cannot be nil") }
allow_any_instance_of(PersonalAccessToken).to receive(:errors).and_return(errors) allow_any_instance_of(PersonalAccessToken).to receive(:errors).and_return(errors)
click_on "Revoke" accept_confirm { click_on "Revoke" }
expect(active_personal_access_tokens).to have_text(personal_access_token.name) expect(active_personal_access_tokens).to have_text(personal_access_token.name)
expect(page).to have_content("Could not revoke") expect(page).to have_content("Could not revoke")
end end
......
...@@ -13,7 +13,7 @@ feature 'User visits the notifications tab', :js do ...@@ -13,7 +13,7 @@ feature 'User visits the notifications tab', :js do
it 'changes the project notifications setting' do it 'changes the project notifications setting' do
expect(page).to have_content('Notifications') expect(page).to have_content('Notifications')
first('#notifications-button').trigger('click') first('#notifications-button').click
click_link('On mention') click_link('On mention')
expect(page).to have_content('On mention') expect(page).to have_content('On mention')
......
...@@ -53,7 +53,7 @@ describe 'User visits the profile preferences page' do ...@@ -53,7 +53,7 @@ describe 'User visits the profile preferences page' do
expect(page).to have_content("You don't have starred projects yet") expect(page).to have_content("You don't have starred projects yet")
expect(page.current_path).to eq starred_dashboard_projects_path expect(page.current_path).to eq starred_dashboard_projects_path
find('.shortcuts-activity').trigger('click') find('.shortcuts-activity').click
expect(page).not_to have_content("You don't have starred projects yet") expect(page).not_to have_content("You don't have starred projects yet")
expect(page.current_path).to eq dashboard_projects_path expect(page.current_path).to eq dashboard_projects_path
......
require 'spec_helper' require 'spec_helper'
feature 'Download artifact', :js do feature 'Download artifact' do
let(:project) { create(:project, :public) } let(:project) { create(:project, :public) }
let(:pipeline) { create(:ci_empty_pipeline, status: :success, project: project) } let(:pipeline) { create(:ci_empty_pipeline, status: :success, project: project) }
let(:job) { create(:ci_build, :artifacts, :success, pipeline: pipeline) } let(:job) { create(:ci_build, :artifacts, :success, pipeline: pipeline) }
......
...@@ -39,7 +39,6 @@ feature 'Artifact file', :js do ...@@ -39,7 +39,6 @@ feature 'Artifact file', :js do
context 'JPG file' do context 'JPG file' do
before do before do
page.driver.browser.url_blacklist = []
visit_file('rails_sample.jpg') visit_file('rails_sample.jpg')
wait_for_requests wait_for_requests
......
...@@ -67,7 +67,7 @@ describe 'Branches' do ...@@ -67,7 +67,7 @@ describe 'Branches' do
expect(page).to have_content('fix') expect(page).to have_content('fix')
expect(find('.all-branches')).to have_selector('li', count: 1) expect(find('.all-branches')).to have_selector('li', count: 1)
find('.js-branch-fix .btn-remove').trigger(:click) accept_confirm { find('.js-branch-fix .btn-remove').click }
expect(page).not_to have_content('fix') expect(page).not_to have_content('fix')
expect(find('.all-branches')).to have_selector('li', count: 0) expect(find('.all-branches')).to have_selector('li', count: 0)
......
...@@ -20,8 +20,8 @@ feature 'Commit diff', :js do ...@@ -20,8 +20,8 @@ feature 'Commit diff', :js do
it "adds comment to diff" do it "adds comment to diff" do
diff_line_num = first('.diff-line-num.new') diff_line_num = first('.diff-line-num.new')
diff_line_num.trigger('mouseover') diff_line_num.hover
diff_line_num.find('.js-add-diff-note-button').trigger('click') diff_line_num.find('.js-add-diff-note-button').click
page.within(first('.diff-viewer')) do page.within(first('.diff-viewer')) do
find('.js-note-text').set 'test comment' find('.js-note-text').set 'test comment'
......
...@@ -18,7 +18,7 @@ feature 'Mini Pipeline Graph in Commit View', :js do ...@@ -18,7 +18,7 @@ feature 'Mini Pipeline Graph in Commit View', :js do
expect(page).to have_selector('.mr-widget-pipeline-graph') expect(page).to have_selector('.mr-widget-pipeline-graph')
first('.mini-pipeline-graph-dropdown-toggle').trigger('click') first('.mini-pipeline-graph-dropdown-toggle').click
wait_for_requests wait_for_requests
......
...@@ -20,7 +20,7 @@ describe 'Project deploy keys', :js do ...@@ -20,7 +20,7 @@ describe 'Project deploy keys', :js do
page.within(find('.deploy-keys')) do page.within(find('.deploy-keys')) do
expect(page).to have_selector('.deploy-keys li', count: 1) expect(page).to have_selector('.deploy-keys li', count: 1)
click_on 'Remove' accept_confirm { find(:button, text: 'Remove').send_keys(:return) }
expect(page).not_to have_selector('.fa-spinner', count: 0) expect(page).not_to have_selector('.fa-spinner', count: 0)
expect(page).to have_selector('.deploy-keys li', count: 0) expect(page).to have_selector('.deploy-keys li', count: 0)
......
...@@ -193,12 +193,14 @@ feature 'Environment' do ...@@ -193,12 +193,14 @@ feature 'Environment' do
create(:environment, project: project, create(:environment, project: project,
name: 'staging-1.0/review', name: 'staging-1.0/review',
state: :available) state: :available)
visit folder_project_environments_path(project, id: 'staging-1.0')
end end
it 'renders a correct environment folder' do it 'renders a correct environment folder' do
expect(page).to have_gitlab_http_status(:ok) reqs = inspect_requests do
visit folder_project_environments_path(project, id: 'staging-1.0')
end
expect(reqs.first.status_code).to eq(200)
expect(page).to have_content('Environments / staging-1.0') expect(page).to have_content('Environments / staging-1.0')
end end
end end
......
...@@ -151,7 +151,7 @@ feature 'Environments page', :js do ...@@ -151,7 +151,7 @@ feature 'Environments page', :js do
find('.js-dropdown-play-icon-container').click find('.js-dropdown-play-icon-container').click
expect(page).to have_content(action.name.humanize) expect(page).to have_content(action.name.humanize)
expect { find('.js-manual-action-link').trigger('click') } expect { find('.js-manual-action-link').click }
.not_to change { Ci::Pipeline.count } .not_to change { Ci::Pipeline.count }
end end
......
...@@ -22,7 +22,7 @@ describe 'Edit Project Settings' do ...@@ -22,7 +22,7 @@ describe 'Edit Project Settings' do
# disable by clicking toggle # disable by clicking toggle
toggle_feature_off("project[project_feature_attributes][#{tool_name}_access_level]") toggle_feature_off("project[project_feature_attributes][#{tool_name}_access_level]")
page.within('.sharing-permissions') do page.within('.sharing-permissions') do
click_button 'Save changes' find('input[value="Save changes"]').click
end end
wait_for_requests wait_for_requests
expect(page).not_to have_selector(".shortcuts-#{shortcut_name}") expect(page).not_to have_selector(".shortcuts-#{shortcut_name}")
...@@ -30,7 +30,7 @@ describe 'Edit Project Settings' do ...@@ -30,7 +30,7 @@ describe 'Edit Project Settings' do
# re-enable by clicking toggle again # re-enable by clicking toggle again
toggle_feature_on("project[project_feature_attributes][#{tool_name}_access_level]") toggle_feature_on("project[project_feature_attributes][#{tool_name}_access_level]")
page.within('.sharing-permissions') do page.within('.sharing-permissions') do
click_button 'Save changes' find('input[value="Save changes"]').click
end end
wait_for_requests wait_for_requests
expect(page).to have_selector(".shortcuts-#{shortcut_name}") expect(page).to have_selector(".shortcuts-#{shortcut_name}")
......
...@@ -7,18 +7,18 @@ feature 'User uses soft wrap whilst editing file', :js do ...@@ -7,18 +7,18 @@ feature 'User uses soft wrap whilst editing file', :js do
project.team << [user, :master] project.team << [user, :master]
sign_in user sign_in user
visit project_new_blob_path(project, 'master', file_name: 'test_file-name') visit project_new_blob_path(project, 'master', file_name: 'test_file-name')
editor = find('.file-editor.code') page.within('.file-editor.code') do
editor.click find('.ace_text-input', visible: false).send_keys 'Touch water with paw then recoil in horror chase dog then
editor.send_keys 'Touch water with paw then recoil in horror chase dog then run away chase the pig around the house eat owner\'s food, and knock
run away chase the pig around the house eat owner\'s food, and knock dish off table head butt cant eat out of my own dish. Cat is love, cat
dish off table head butt cant eat out of my own dish. Cat is love, cat is life rub face on everything poop on grasses so meow. Playing with
is life rub face on everything poop on grasses so meow. Playing with balls of wool flee in terror at cucumber discovered on floor run in
balls of wool flee in terror at cucumber discovered on floor run in circles tuxedo cats always looking dapper, but attack dog, run away
circles tuxedo cats always looking dapper, but attack dog, run away and pretend to be victim so all of a sudden cat goes crazy, yet chase
and pretend to be victim so all of a sudden cat goes crazy, yet chase laser. Make muffins sit in window and stare ooo, a bird! yum lick yarn
laser. Make muffins sit in window and stare ooo, a bird! yum lick yarn hanging out of own butt jump off balcony, onto stranger\'s head yet
hanging out of own butt jump off balcony, onto stranger\'s head yet chase laser. Purr for no reason stare at ceiling hola te quiero.'.squish
chase laser. Purr for no reason stare at ceiling hola te quiero.'.squish end
end end
let(:toggle_button) { find('.soft-wrap-toggle') } let(:toggle_button) { find('.soft-wrap-toggle') }
...@@ -36,6 +36,6 @@ feature 'User uses soft wrap whilst editing file', :js do ...@@ -36,6 +36,6 @@ feature 'User uses soft wrap whilst editing file', :js do
end end
def get_content_width def get_content_width
find('.ace_content')[:style].slice!(/width: \d+/).slice!(/\d+/) find('.ace_content')[:style].slice!(/width: \d+/).slice!(/\d+/).to_i
end end
end end
...@@ -41,7 +41,7 @@ feature 'Import/Export - project export integration test', :js do ...@@ -41,7 +41,7 @@ feature 'Import/Export - project export integration test', :js do
expect(page).to have_content('Export project') expect(page).to have_content('Export project')
click_link 'Export project' find(:link, 'Export project').send_keys(:return)
visit edit_project_path(project) visit edit_project_path(project)
......
...@@ -94,6 +94,6 @@ feature 'Import/Export - project import integration test', :js do ...@@ -94,6 +94,6 @@ feature 'Import/Export - project import integration test', :js do
end end
def click_import_project_tab def click_import_project_tab
find('#import-project-tab').trigger('click') find('#import-project-tab').click
end end
end end
...@@ -52,7 +52,7 @@ feature 'Import/Export - Namespace export file cleanup', :js do ...@@ -52,7 +52,7 @@ feature 'Import/Export - Namespace export file cleanup', :js do
expect(page).to have_content('Export project') expect(page).to have_content('Export project')
click_link 'Export project' find(:link, 'Export project').send_keys(:return)
visit edit_project_path(project) visit edit_project_path(project)
......
...@@ -21,12 +21,12 @@ describe 'User browses a job', :js do ...@@ -21,12 +21,12 @@ describe 'User browses a job', :js do
expect(page).to have_content("Job ##{build.id}") expect(page).to have_content("Job ##{build.id}")
expect(page).to have_css('#build-trace') expect(page).to have_css('#build-trace')
click_link('Erase') accept_confirm { click_link('Erase') }
expect(page).to have_no_css('.artifacts')
expect(build).not_to have_trace expect(build).not_to have_trace
expect(build.artifacts_file.exists?).to be_falsy expect(build.artifacts_file.exists?).to be_falsy
expect(build.artifacts_metadata.exists?).to be_falsy expect(build.artifacts_metadata.exists?).to be_falsy
expect(page).to have_no_css('.artifacts')
page.within('.erased') do page.within('.erased') do
expect(page).to have_content('Job has been erased') expect(page).to have_content('Job has been erased')
......
...@@ -380,7 +380,6 @@ feature 'Jobs' do ...@@ -380,7 +380,6 @@ feature 'Jobs' do
end end
it 'loads the page and shows all needed controls' do it 'loads the page and shows all needed controls' do
expect(page.status_code).to eq(200)
expect(page).to have_content 'Retry' expect(page).to have_content 'Retry'
end end
end end
...@@ -392,11 +391,10 @@ feature 'Jobs' do ...@@ -392,11 +391,10 @@ feature 'Jobs' do
job.run! job.run!
visit project_job_path(project, job) visit project_job_path(project, job)
find('.js-cancel-job').click() find('.js-cancel-job').click()
find('.js-retry-button').trigger('click') find('.js-retry-button').click
end end
it 'shows the right status and buttons', :js do it 'shows the right status and buttons', :js do
expect(page).to have_gitlab_http_status(200)
page.within('aside.right-sidebar') do page.within('aside.right-sidebar') do
expect(page).to have_content 'Cancel' expect(page).to have_content 'Cancel'
end end
...@@ -443,28 +441,30 @@ feature 'Jobs' do ...@@ -443,28 +441,30 @@ feature 'Jobs' do
context 'access source' do context 'access source' do
context 'job from project' do context 'job from project' do
before do before do
Capybara.current_session.driver.headers = { 'X-Sendfile-Type' => 'X-Sendfile' }
job.run! job.run!
visit project_job_path(project, job)
find('.js-raw-link-controller').click()
end end
it 'sends the right headers' do it 'sends the right headers' do
expect(page.status_code).to eq(200) requests = inspect_requests(inject_headers: { 'X-Sendfile-Type' => 'X-Sendfile' }) do
expect(page.response_headers['Content-Type']).to eq('text/plain; charset=utf-8') visit raw_project_job_path(project, job)
expect(page.response_headers['X-Sendfile']).to eq(job.trace.send(:current_path)) end
expect(requests.first.status_code).to eq(200)
expect(requests.first.response_headers['Content-Type']).to eq('text/plain; charset=utf-8')
expect(requests.first.response_headers['X-Sendfile']).to eq(job.trace.send(:current_path))
end end
end end
context 'job from other project' do context 'job from other project' do
before do before do
Capybara.current_session.driver.headers = { 'X-Sendfile-Type' => 'X-Sendfile' }
job2.run! job2.run!
visit raw_project_job_path(project, job2)
end end
it 'sends the right headers' do it 'sends the right headers' do
expect(page.status_code).to eq(404) requests = inspect_requests(inject_headers: { 'X-Sendfile-Type' => 'X-Sendfile' }) do
visit raw_project_job_path(project, job2)
end
expect(requests.first.status_code).to eq(404)
end end
end end
end end
...@@ -473,8 +473,6 @@ feature 'Jobs' do ...@@ -473,8 +473,6 @@ feature 'Jobs' do
let(:existing_file) { Tempfile.new('existing-trace-file').path } let(:existing_file) { Tempfile.new('existing-trace-file').path }
before do before do
Capybara.current_session.driver.headers = { 'X-Sendfile-Type' => 'X-Sendfile' }
job.run! job.run!
end end
...@@ -483,16 +481,14 @@ feature 'Jobs' do ...@@ -483,16 +481,14 @@ feature 'Jobs' do
allow_any_instance_of(Gitlab::Ci::Trace) allow_any_instance_of(Gitlab::Ci::Trace)
.to receive(:paths) .to receive(:paths)
.and_return([existing_file]) .and_return([existing_file])
visit project_job_path(project, job)
find('.js-raw-link-controller').click
end end
it 'sends the right headers' do it 'sends the right headers' do
expect(page.status_code).to eq(200) requests = inspect_requests(inject_headers: { 'X-Sendfile-Type' => 'X-Sendfile' }) do
expect(page.response_headers['Content-Type']).to eq('text/plain; charset=utf-8') visit raw_project_job_path(project, job)
expect(page.response_headers['X-Sendfile']).to eq(existing_file) end
expect(requests.first.response_headers['Content-Type']).to eq('text/plain; charset=utf-8')
expect(requests.first.response_headers['X-Sendfile']).to eq(existing_file)
end end
end end
......
...@@ -31,6 +31,7 @@ feature 'Projects > Members > Groups with access list', :js do ...@@ -31,6 +31,7 @@ feature 'Projects > Members > Groups with access list', :js do
tomorrow = Date.today + 3 tomorrow = Date.today + 3
fill_in "member_expires_at_#{group.id}", with: tomorrow.strftime("%F") fill_in "member_expires_at_#{group.id}", with: tomorrow.strftime("%F")
find('body').click
wait_for_requests wait_for_requests
page.within(find('li.group_member')) do page.within(find('li.group_member')) do
...@@ -40,7 +41,7 @@ feature 'Projects > Members > Groups with access list', :js do ...@@ -40,7 +41,7 @@ feature 'Projects > Members > Groups with access list', :js do
scenario 'deletes group link' do scenario 'deletes group link' do
page.within(first('.group_member')) do page.within(first('.group_member')) do
find('.btn-remove').click accept_confirm { find('.btn-remove').click }
end end
wait_for_requests wait_for_requests
......
...@@ -20,7 +20,7 @@ feature 'Projects > Members > Master adds member with expiration date', :js do ...@@ -20,7 +20,7 @@ feature 'Projects > Members > Master adds member with expiration date', :js do
page.within '.users-project-form' do page.within '.users-project-form' do
select2(new_member.id, from: '#user_ids', multiple: true) select2(new_member.id, from: '#user_ids', multiple: true)
fill_in 'expires_at', with: date.to_s(:medium) fill_in 'expires_at', with: date.to_s(:medium) + "\n"
click_on 'Add to project' click_on 'Add to project'
end end
...@@ -37,7 +37,7 @@ feature 'Projects > Members > Master adds member with expiration date', :js do ...@@ -37,7 +37,7 @@ feature 'Projects > Members > Master adds member with expiration date', :js do
visit project_project_members_path(project) visit project_project_members_path(project)
page.within "#project_member_#{new_member.project_members.first.id}" do page.within "#project_member_#{new_member.project_members.first.id}" do
find('.js-access-expiration-date').set date.to_s(:medium) find('.js-access-expiration-date').set date.to_s(:medium) + "\n"
wait_for_requests wait_for_requests
expect(page).to have_content('Expires in 3 days') expect(page).to have_content('Expires in 3 days')
end end
......
...@@ -41,7 +41,7 @@ feature 'Project > Members > Share with Group', :js do ...@@ -41,7 +41,7 @@ feature 'Project > Members > Share with Group', :js do
select2 group_to_share_with.id, from: '#link_group_id' select2 group_to_share_with.id, from: '#link_group_id'
page.find('body').click page.find('body').click
find('.btn-create').trigger('click') find('.btn-create').click
page.within('.project-members-groups') do page.within('.project-members-groups') do
expect(page).to have_content(group_to_share_with.name) expect(page).to have_content(group_to_share_with.name)
...@@ -123,7 +123,7 @@ feature 'Project > Members > Share with Group', :js do ...@@ -123,7 +123,7 @@ feature 'Project > Members > Share with Group', :js do
fill_in 'expires_at_groups', with: (Time.now + 4.5.days).strftime('%Y-%m-%d') fill_in 'expires_at_groups', with: (Time.now + 4.5.days).strftime('%Y-%m-%d')
page.find('body').click page.find('body').click
find('.btn-create').trigger('click') find('.btn-create').click
end end
scenario 'the group link shows the expiration time with a warning class' do scenario 'the group link shows the expiration time with a warning class' do
......
...@@ -60,7 +60,7 @@ feature 'Projects > Members > User requests access', :js do ...@@ -60,7 +60,7 @@ feature 'Projects > Members > User requests access', :js do
expect(project.requesters.exists?(user_id: user)).to be_truthy expect(project.requesters.exists?(user_id: user)).to be_truthy
click_link 'Withdraw Access Request' accept_confirm { click_link 'Withdraw Access Request' }
expect(project.requesters.exists?(user_id: user)).to be_falsey expect(project.requesters.exists?(user_id: user)).to be_falsey
expect(page).to have_content 'Your access request to the project has been withdrawn.' expect(page).to have_content 'Your access request to the project has been withdrawn.'
......
...@@ -31,7 +31,7 @@ describe 'User comments on a diff', :js do ...@@ -31,7 +31,7 @@ describe 'User comments on a diff', :js do
page.within('.files > div:nth-child(3)') do page.within('.files > div:nth-child(3)') do
expect(page).to have_content('Line is wrong') expect(page).to have_content('Line is wrong')
find('.js-toggle-diff-comments').trigger('click') find('.js-toggle-diff-comments').click
expect(page).not_to have_content('Line is wrong') expect(page).not_to have_content('Line is wrong')
end end
...@@ -64,7 +64,7 @@ describe 'User comments on a diff', :js do ...@@ -64,7 +64,7 @@ describe 'User comments on a diff', :js do
# Hide the comment. # Hide the comment.
page.within('.files > div:nth-child(3)') do page.within('.files > div:nth-child(3)') do
find('.js-toggle-diff-comments').trigger('click') find('.js-toggle-diff-comments').click
expect(page).not_to have_content('Line is wrong') expect(page).not_to have_content('Line is wrong')
end end
...@@ -77,7 +77,7 @@ describe 'User comments on a diff', :js do ...@@ -77,7 +77,7 @@ describe 'User comments on a diff', :js do
# Show the comment. # Show the comment.
page.within('.files > div:nth-child(3)') do page.within('.files > div:nth-child(3)') do
find('.js-toggle-diff-comments').trigger('click') find('.js-toggle-diff-comments').click
end end
# Now both the comments should be shown. # Now both the comments should be shown.
...@@ -90,6 +90,7 @@ describe 'User comments on a diff', :js do ...@@ -90,6 +90,7 @@ describe 'User comments on a diff', :js do
end end
# Check the same comments in the side-by-side view. # Check the same comments in the side-by-side view.
execute_script("window.scrollTo(0,0);")
click_link('Side-by-side') click_link('Side-by-side')
wait_for_requests wait_for_requests
...@@ -153,11 +154,11 @@ describe 'User comments on a diff', :js do ...@@ -153,11 +154,11 @@ describe 'User comments on a diff', :js do
find('.more-actions').click find('.more-actions').click
find('.more-actions .dropdown-menu li', match: :first) find('.more-actions .dropdown-menu li', match: :first)
find('.js-note-delete').click accept_confirm { find('.js-note-delete').click }
end end
page.within('.merge-request-tabs') do page.within('.merge-request-tabs') do
find('.notes-tab').trigger('click') find('.notes-tab').click
end end
wait_for_requests wait_for_requests
......
require 'spec_helper' require 'spec_helper'
describe 'User edits a merge request', :js do describe 'User edits a merge request', :js do
include Select2Helper
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:user) { create(:user) } let(:user) { create(:user) }
...@@ -15,8 +17,7 @@ describe 'User edits a merge request', :js do ...@@ -15,8 +17,7 @@ describe 'User edits a merge request', :js do
it 'changes the target branch' do it 'changes the target branch' do
expect(page).to have_content('Target branch') expect(page).to have_content('Target branch')
first('.target_branch').click select2('merge-test', from: '#merge_request_target_branch')
select('merge-test', from: 'merge_request_target_branch', visible: false)
click_button('Save changes') click_button('Save changes')
expect(page).to have_content("Request to merge #{merge_request.source_branch} into merge-test") expect(page).to have_content("Request to merge #{merge_request.source_branch} into merge-test")
......
...@@ -15,7 +15,7 @@ feature 'New project' do ...@@ -15,7 +15,7 @@ feature 'New project' do
expect(page).to have_content('Project path') expect(page).to have_content('Project path')
expect(page).to have_content('Project name') expect(page).to have_content('Project name')
find('#import-project-tab').trigger('click') find('#import-project-tab').click
expect(page).to have_link('GitHub') expect(page).to have_link('GitHub')
expect(page).to have_link('Bitbucket') expect(page).to have_link('Bitbucket')
...@@ -137,7 +137,7 @@ feature 'New project' do ...@@ -137,7 +137,7 @@ feature 'New project' do
context 'Import project options', :js do context 'Import project options', :js do
before do before do
visit new_project_path visit new_project_path
find('#import-project-tab').trigger('click') find('#import-project-tab').click
end end
context 'from git repository url' do context 'from git repository url' do
......
...@@ -54,7 +54,7 @@ feature 'Pipeline Schedules', :js do ...@@ -54,7 +54,7 @@ feature 'Pipeline Schedules', :js do
end end
it 'deletes the pipeline' do it 'deletes the pipeline' do
click_link 'Delete' accept_confirm { click_link 'Delete' }
expect(page).not_to have_css(".pipeline-schedule-table-row") expect(page).not_to have_css(".pipeline-schedule-table-row")
end end
......
...@@ -73,7 +73,7 @@ describe 'Pipeline', :js do ...@@ -73,7 +73,7 @@ describe 'Pipeline', :js do
end end
it 'should be possible to cancel the running build' do 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') expect(page).not_to have_content('Cancel running')
end end
...@@ -92,7 +92,7 @@ describe 'Pipeline', :js do ...@@ -92,7 +92,7 @@ describe 'Pipeline', :js do
end end
it 'should be possible to retry the success job' do 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') expect(page).not_to have_content('Retry job')
end end
...@@ -111,7 +111,7 @@ describe 'Pipeline', :js do ...@@ -111,7 +111,7 @@ describe 'Pipeline', :js do
end end
it 'should be possible to retry the failed build' do 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') expect(page).not_to have_content('Retry job')
end end
...@@ -130,7 +130,7 @@ describe 'Pipeline', :js do ...@@ -130,7 +130,7 @@ describe 'Pipeline', :js do
end end
it 'should be possible to play the manual job' do 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') expect(page).not_to have_content('Play job')
end end
...@@ -165,7 +165,7 @@ describe 'Pipeline', :js do ...@@ -165,7 +165,7 @@ describe 'Pipeline', :js do
context 'when retrying' do context 'when retrying' do
before do before do
find('.js-retry-button').trigger('click') find('.js-retry-button').click
end end
it { expect(page).not_to have_content('Retry') } it { expect(page).not_to have_content('Retry') }
...@@ -231,7 +231,7 @@ describe 'Pipeline', :js do ...@@ -231,7 +231,7 @@ describe 'Pipeline', :js do
context 'when retrying' do context 'when retrying' do
before do before do
find('.js-retry-button').trigger('click') find('.js-retry-button').click
end end
it { expect(page).not_to have_content('Retry') } it { expect(page).not_to have_content('Retry') }
......
...@@ -103,7 +103,7 @@ describe 'Pipelines', :js do ...@@ -103,7 +103,7 @@ describe 'Pipelines', :js do
context 'when canceling' do context 'when canceling' do
before do before do
find('.js-pipelines-cancel-button').click accept_confirm { find('.js-pipelines-cancel-button').click }
wait_for_requests wait_for_requests
end end
...@@ -232,7 +232,7 @@ describe 'Pipelines', :js do ...@@ -232,7 +232,7 @@ describe 'Pipelines', :js do
context 'when canceling' do context 'when canceling' do
before do before do
find('.js-pipelines-cancel-button').trigger('click') accept_alert { find('.js-pipelines-cancel-button').click }
end end
it 'indicates that pipeline was canceled' do it 'indicates that pipeline was canceled' do
...@@ -345,14 +345,14 @@ describe 'Pipelines', :js do ...@@ -345,14 +345,14 @@ describe 'Pipelines', :js do
context 'when clicking a stage badge' do context 'when clicking a stage badge' do
it 'should open a dropdown' 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 expect(page).to have_link build.name
end end
it 'should be possible to cancel pending build' do it 'should be possible to cancel pending build' do
find('.js-builds-dropdown-button').trigger('click') find('.js-builds-dropdown-button').click
find('a.js-ci-action-icon').trigger('click') find('a.js-ci-action-icon').click
expect(page).to have_content('canceled') expect(page).to have_content('canceled')
expect(build.reload).to be_canceled expect(build.reload).to be_canceled
...@@ -361,11 +361,16 @@ describe 'Pipelines', :js do ...@@ -361,11 +361,16 @@ describe 'Pipelines', :js do
context 'dropdown jobs list' do context 'dropdown jobs list' do
it 'should keep the dropdown open when the user ctr/cmd + clicks in the job name' 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
dropdown_item = find('.mini-pipeline-graph-dropdown-item').native
execute_script('var e = $.Event("keydown", { keyCode: 64 }); $("body").trigger(e);')
%i(alt control).each do |meta_key|
find('.mini-pipeline-graph-dropdown-item').trigger('click') page.driver.browser.action
.key_down(meta_key)
.click(dropdown_item)
.key_up(meta_key)
.perform
end
expect(page).to have_selector('.js-ci-action-icon') expect(page).to have_selector('.js-ci-action-icon')
end end
...@@ -525,7 +530,6 @@ describe 'Pipelines', :js do ...@@ -525,7 +530,6 @@ describe 'Pipelines', :js do
let(:project) { create(:project, :public, :repository) } let(:project) { create(:project, :public, :repository) }
it { expect(page).to have_content 'Build with confidence' } it { expect(page).to have_content 'Build with confidence' }
it { expect(page).to have_gitlab_http_status(:success) }
end end
context 'when project is private' do context 'when project is private' do
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment