2016-03-07 19:52:19 -05:00
# frozen_string_literal: true
2018-02-28 19:11:41 -05:00
2010-09-17 19:56:32 -04:00
require 'spec_helper'
2018-07-10 17:18:39 -04:00
require 'selenium-webdriver'
2013-11-14 16:25:00 -05:00
2018-07-10 17:18:39 -04:00
RSpec . shared_examples 'Capybara::Session' do | session , mode |
2018-02-28 19:11:41 -05:00
let ( :session ) { session }
2016-07-26 14:15:35 -04:00
2009-11-14 04:44:46 -05:00
context 'with selenium driver' do
describe '#driver' do
2018-07-10 17:18:39 -04:00
it 'should be a selenium driver' do
2018-04-27 14:01:47 -04:00
expect ( session . driver ) . to be_an_instance_of ( Capybara :: Selenium :: Driver )
2009-11-14 04:44:46 -05:00
end
end
2009-12-11 16:40:23 -05:00
2009-11-14 04:44:46 -05:00
describe '#mode' do
2018-07-10 17:18:39 -04:00
it 'should remember the mode' do
2018-04-27 14:01:47 -04:00
expect ( session . mode ) . to eq ( mode )
2009-11-14 04:44:46 -05:00
end
end
2009-12-11 16:40:23 -05:00
2018-07-10 17:18:39 -04:00
describe '#reset!' do
it 'freshly reset session should not be touched' do
2018-04-27 14:01:47 -04:00
session . instance_variable_set ( :@touched , true )
session . reset!
2022-04-30 13:26:55 -04:00
expect ( session . instance_variable_get ( :@touched ) ) . to be false
2014-01-17 02:57:06 -05:00
end
end
2018-07-10 17:18:39 -04:00
describe 'exit codes' do
2019-02-25 18:50:24 -05:00
let ( :env ) { { 'SELENIUM_BROWSER' = > session . driver . options [ :browser ] . to_s } }
let! ( :orig_dir ) { Dir . getwd }
2012-07-13 07:15:44 -04:00
before do
2012-07-13 07:28:33 -04:00
Dir . chdir ( File . join ( File . dirname ( __FILE__ ) , '..' ) )
2012-07-13 07:15:44 -04:00
end
after do
2019-02-25 18:50:24 -05:00
Dir . chdir ( orig_dir )
2012-07-13 07:15:44 -04:00
end
2018-07-10 17:18:39 -04:00
it 'should have return code 1 when running selenium_driver_rspec_failure.rb' do
2018-08-01 17:25:08 -04:00
skip 'only setup for local non-headless' if headless_or_remote?
2019-06-01 21:17:59 -04:00
skip 'Not setup for edge' if edge? ( session )
2018-04-24 18:47:53 -04:00
2019-02-25 18:50:24 -05:00
system ( env , 'rspec spec/fixtures/selenium_driver_rspec_failure.rb' , out : File :: NULL , err : File :: NULL )
2018-02-28 19:11:41 -05:00
expect ( $CHILD_STATUS . exitstatus ) . to eq ( 1 )
2012-07-13 07:15:44 -04:00
end
2018-07-10 17:18:39 -04:00
it 'should have return code 0 when running selenium_driver_rspec_success.rb' do
2018-08-01 17:25:08 -04:00
skip 'only setup for local non-headless' if headless_or_remote?
2019-06-01 21:17:59 -04:00
skip 'Not setup for edge' if edge? ( session )
2018-04-24 18:47:53 -04:00
2019-02-25 18:50:24 -05:00
system ( env , 'rspec spec/fixtures/selenium_driver_rspec_success.rb' , out : File :: NULL , err : File :: NULL )
2018-02-28 19:11:41 -05:00
expect ( $CHILD_STATUS . exitstatus ) . to eq ( 0 )
2012-07-13 07:15:44 -04:00
end
end
2015-04-12 23:32:12 -04:00
2018-07-10 17:18:39 -04:00
describe '#accept_alert' , requires : [ :modals ] do
it 'supports a blockless mode' do
2018-04-27 14:01:47 -04:00
session . visit ( '/with_js' )
session . click_link ( 'Open alert' )
session . accept_alert
expect { session . driver . browser . switch_to . alert } . to raise_error ( session . driver . send ( :modal_error ) )
2014-07-02 22:10:30 -04:00
end
2017-08-14 19:25:57 -04:00
2018-07-10 17:18:39 -04:00
it 'can be called before visiting' do
session . accept_alert 'Initial alert' do
2018-04-27 14:01:47 -04:00
session . visit ( '/initial_alert' )
2018-02-12 13:07:06 -05:00
end
2018-04-27 14:01:47 -04:00
expect ( session ) . to have_text ( 'Initial alert page' )
2017-08-14 19:25:57 -04:00
end
2014-07-02 22:10:30 -04:00
end
2015-04-12 23:32:12 -04:00
2019-10-15 20:40:27 -04:00
describe '#fill_in_with empty string and no options' do
2017-09-07 12:58:14 -04:00
it 'should trigger change when clearing a field' do
2018-04-27 14:01:47 -04:00
session . visit ( '/with_js' )
session . fill_in ( 'with_change_event' , with : '' )
2017-09-07 12:58:14 -04:00
# click outside the field to trigger the change event
2018-04-27 14:01:47 -04:00
session . find ( :css , 'body' ) . click
expect ( session ) . to have_selector ( :css , '.change_event_triggered' , match : :one )
2017-09-07 12:58:14 -04:00
end
end
2019-10-15 20:40:27 -04:00
describe '#fill_in with { :clear => :backspace } fill_option' , requires : [ :js ] do
2018-07-11 13:05:45 -04:00
before do
# Firefox has an issue with change events if the main window doesn't think it's focused
session . execute_script ( 'window.focus()' )
end
2015-04-12 23:32:12 -04:00
it 'should fill in a field, replacing an existing value' do
2018-04-27 14:01:47 -04:00
session . visit ( '/form' )
session . fill_in ( 'form_first_name' ,
with : 'Harry' ,
fill_options : { clear : :backspace } )
expect ( session . find ( :fillable_field , 'form_first_name' ) . value ) . to eq ( 'Harry' )
2015-04-12 23:32:12 -04:00
end
2018-07-16 12:19:35 -04:00
it 'should fill in a field, replacing an existing value, even with caret position' do
session . visit ( '/form' )
2018-07-10 17:18:39 -04:00
session . find ( :css , '#form_first_name' ) . execute_script <<-JS
2018-07-16 12:19:35 -04:00
this . focus ( ) ;
this . setSelectionRange ( 0 , 0 ) ;
JS
session . fill_in ( 'form_first_name' ,
2018-07-10 17:18:39 -04:00
with : 'Harry' ,
fill_options : { clear : :backspace } )
2018-07-16 12:19:35 -04:00
expect ( session . find ( :fillable_field , 'form_first_name' ) . value ) . to eq ( 'Harry' )
end
2018-05-18 13:29:53 -04:00
it 'should fill in if the option is set via global option' do
Capybara . default_set_options = { clear : :backspace }
session . visit ( '/form' )
session . fill_in ( 'form_first_name' , with : 'Thomas' )
expect ( session . find ( :fillable_field , 'form_first_name' ) . value ) . to eq ( 'Thomas' )
end
2015-04-12 23:32:12 -04:00
it 'should only trigger onchange once' do
2018-04-27 14:01:47 -04:00
session . visit ( '/with_js' )
2019-03-13 21:21:53 -04:00
sleep 2 if safari? ( session ) # Safari needs a delay (to load event handlers maybe ???)
2018-04-27 14:01:47 -04:00
session . fill_in ( 'with_change_event' ,
with : 'some value' ,
fill_options : { clear : :backspace } )
2015-04-12 23:32:12 -04:00
# click outside the field to trigger the change event
2018-07-11 13:05:45 -04:00
session . find ( :css , '#with_focus_event' ) . click
2018-07-05 20:14:36 -04:00
expect ( session . find ( :css , '.change_event_triggered' , match : :one , wait : 5 ) ) . to have_text 'some value'
2015-04-12 23:32:12 -04:00
end
it 'should trigger change when clearing field' do
2018-04-27 14:01:47 -04:00
session . visit ( '/with_js' )
session . fill_in ( 'with_change_event' ,
with : '' ,
fill_options : { clear : :backspace } )
2015-04-12 23:32:12 -04:00
# click outside the field to trigger the change event
2018-07-11 13:05:45 -04:00
session . find ( :css , '#with_focus_event' ) . click
2018-07-05 20:14:36 -04:00
expect ( session ) . to have_selector ( :css , '.change_event_triggered' , match : :one , wait : 5 )
2015-04-12 23:32:12 -04:00
end
2017-09-07 12:58:14 -04:00
it 'should trigger input event field_value.length times' do
2018-04-27 14:01:47 -04:00
session . visit ( '/with_js' )
session . fill_in ( 'with_change_event' ,
with : '' ,
fill_options : { clear : :backspace } )
2017-09-07 12:58:14 -04:00
# click outside the field to trigger the change event
2019-03-13 21:21:53 -04:00
# session.find(:css, 'body').click
session . find ( :css , 'h1' , text : 'FooBar' ) . click
2018-04-27 14:01:47 -04:00
expect ( session ) . to have_xpath ( '//p[@class="input_event_triggered"]' , count : 13 )
2017-09-07 12:58:14 -04:00
end
2015-04-12 23:32:12 -04:00
end
2015-08-09 12:55:56 -04:00
2019-10-15 20:40:27 -04:00
describe '#fill_in with { clear: :none } fill_options' do
2015-04-13 00:25:13 -04:00
it 'should append to content in a field' do
2019-03-13 21:21:53 -04:00
pending 'Safari overwrites by default - need to figure out a workaround' if safari? ( session )
2018-04-27 14:01:47 -04:00
session . visit ( '/form' )
session . fill_in ( 'form_first_name' ,
with : 'Harry' ,
fill_options : { clear : :none } )
expect ( session . find ( :fillable_field , 'form_first_name' ) . value ) . to eq ( 'JohnHarry' )
2015-04-13 00:25:13 -04:00
end
2020-05-29 08:15:16 -04:00
it 'works with rapid fill' do
pending 'Safari overwrites by default - need to figure out a workaround' if safari? ( session )
long_string = ( 0 ... 60 ) . map { | i | ( ( i % 26 ) + 65 ) . chr } . join
session . visit ( '/form' )
session . fill_in ( 'form_first_name' , with : long_string , fill_options : { clear : :none } )
2020-09-05 15:24:43 -04:00
expect ( session . find ( :fillable_field , 'form_first_name' ) . value ) . to eq ( " John #{ long_string } " )
2020-05-29 08:15:16 -04:00
end
2015-04-13 00:25:13 -04:00
end
2019-10-15 20:40:27 -04:00
describe '#fill_in with Date' do
2018-05-09 15:44:47 -04:00
before do
session . visit ( '/form' )
2018-07-10 17:18:39 -04:00
session . find ( :css , '#form_date' ) . execute_script <<-JS
2018-05-09 15:44:47 -04:00
window . capybara_formDateFiredEvents = [ ] ;
2018-07-12 15:32:41 -04:00
var fd = this ;
2018-05-09 15:44:47 -04:00
[ 'focus' , 'input' , 'change' ] . forEach ( function ( eventType ) {
2018-07-12 15:32:41 -04:00
fd . addEventListener ( eventType , function ( ) { window . capybara_formDateFiredEvents . push ( eventType ) ; } ) ;
2018-05-09 15:44:47 -04:00
} ) ;
JS
# work around weird FF issue where it would create an extra focus issue in some cases
2019-03-13 21:21:53 -04:00
session . find ( :css , 'h1' , text : 'Form' ) . click
# session.find(:css, 'body').click
2018-05-09 15:44:47 -04:00
end
2018-07-10 17:18:39 -04:00
it 'should generate standard events on changing value' do
2018-07-30 13:37:47 -04:00
pending " IE 11 doesn't support date input type " if ie? ( session )
2018-05-09 15:44:47 -04:00
session . fill_in ( 'form_date' , with : Date . today )
expect ( session . evaluate_script ( 'window.capybara_formDateFiredEvents' ) ) . to eq %w[ focus input change ]
end
2018-07-10 17:18:39 -04:00
it 'should not generate input and change events if the value is not changed' do
2018-07-30 13:37:47 -04:00
pending " IE 11 doesn't support date input type " if ie? ( session )
2018-05-09 15:44:47 -04:00
session . fill_in ( 'form_date' , with : Date . today )
session . fill_in ( 'form_date' , with : Date . today )
# Chrome adds an extra focus for some reason - ok for now
expect ( session . evaluate_script ( 'window.capybara_formDateFiredEvents' ) ) . to eq ( %w[ focus input change ] )
end
end
2019-10-15 20:40:27 -04:00
describe '#fill_in with { clear: Array } fill_options' do
2016-04-05 12:33:19 -04:00
it 'should pass the array through to the element' do
2018-02-28 19:11:41 -05:00
# this is mainly for use with [[:control, 'a'], :backspace] - however since that is platform dependant I'm testing with something less useful
2018-04-27 14:01:47 -04:00
session . visit ( '/form' )
session . fill_in ( 'form_first_name' ,
with : 'Harry' ,
fill_options : { clear : [ [ :shift , 'abc' ] , :backspace ] } )
expect ( session . find ( :fillable_field , 'form_first_name' ) . value ) . to eq ( 'JohnABHarry' )
2015-04-13 00:25:13 -04:00
end
end
2020-06-21 17:21:45 -04:00
describe '#fill_in with Emoji' do
it 'sends emojis' do
session . visit ( '/form' )
session . fill_in ( 'form_first_name' , with : 'a😀cd😴 🛌🏽🇵🇹 e🤾🏽 ♀️ f' )
expect ( session . find ( :fillable_field , 'form_first_name' ) . value ) . to eq ( 'a😀cd😴 🛌🏽🇵🇹 e🤾🏽 ♀️ f' )
end
end
2015-04-13 00:25:13 -04:00
2020-11-16 20:26:59 -05:00
describe '#send_keys' do
2021-08-18 08:08:54 -04:00
it 'defaults to sending keys to the active_element' do
2020-11-16 20:26:59 -05:00
session . visit ( '/form' )
2021-08-18 08:08:54 -04:00
expect ( session . active_element ) . to match_selector ( :css , 'body' )
2020-11-16 20:26:59 -05:00
session . send_keys ( :tab )
2021-08-18 08:08:54 -04:00
expect ( session . active_element ) . to match_selector ( :css , '[tabindex="1"]' )
2020-11-16 20:26:59 -05:00
end
end
2018-07-10 17:18:39 -04:00
describe '#path' do
it 'returns xpath' do
2015-08-20 17:35:15 -04:00
# this is here because it is testing for an XPath that is specific to the algorithm used in the selenium driver
2018-04-27 14:01:47 -04:00
session . visit ( '/path' )
element = session . find ( :link , 'Second Link' )
2018-12-29 16:13:33 -05:00
expect ( element . path ) . to eq ( '/HTML/BODY[1]/DIV[2]/A[1]' )
2015-08-09 12:55:56 -04:00
end
2018-06-12 16:06:25 -04:00
2018-09-14 13:27:02 -04:00
it 'handles namespaces in xhtml' do
2018-07-30 13:37:47 -04:00
pending " IE 11 doesn't handle all XPath querys (namespace-uri, etc) " if ie? ( session )
2018-07-10 17:18:39 -04:00
session . visit '/with_namespace'
2018-07-30 13:37:47 -04:00
rect = session . find ( :css , 'div svg rect:first-of-type' )
2018-12-29 16:13:33 -05:00
expect ( rect . path ) . to eq ( " /HTML/BODY[1]/DIV[1]/*[local-name()='svg' and namespace-uri()='http://www.w3.org/2000/svg'][1]/*[local-name()='rect' and namespace-uri()='http://www.w3.org/2000/svg'][1] " )
2018-06-12 16:06:25 -04:00
expect ( session . find ( :xpath , rect . path ) ) . to eq rect
end
2018-06-13 16:15:18 -04:00
2018-09-14 13:27:02 -04:00
it 'handles default namespaces in html5' do
pending " IE 11 doesn't handle all XPath querys (namespace-uri, etc) " if ie? ( session )
session . visit '/with_html5_svg'
rect = session . find ( :css , 'div svg rect:first-of-type' )
2018-12-29 16:13:33 -05:00
expect ( rect . path ) . to eq ( " /HTML/BODY[1]/DIV[1]/*[local-name()='svg' and namespace-uri()='http://www.w3.org/2000/svg'][1]/*[local-name()='rect' and namespace-uri()='http://www.w3.org/2000/svg'][1] " )
2018-09-14 13:27:02 -04:00
expect ( session . find ( :xpath , rect . path ) ) . to eq rect
end
2018-07-10 17:18:39 -04:00
it 'handles case sensitive element names' do
2018-07-30 13:37:47 -04:00
pending " IE 11 doesn't handle all XPath querys (namespace-uri, etc) " if ie? ( session )
2018-07-10 17:18:39 -04:00
session . visit '/with_namespace'
els = session . all ( :css , 'div *' , visible : :all )
2018-06-13 16:15:18 -04:00
expect { els . map ( & :path ) } . not_to raise_error
2018-07-10 17:18:39 -04:00
lg = session . find ( :css , 'div linearGradient' , visible : :all )
2018-06-13 16:15:18 -04:00
expect ( session . find ( :xpath , lg . path , visible : :all ) ) . to eq lg
end
2015-08-09 12:55:56 -04:00
end
2017-01-27 14:11:13 -05:00
2018-07-10 17:18:39 -04:00
describe 'all with disappearing elements' do
it 'ignores stale elements in results' do
2018-04-27 14:01:47 -04:00
session . visit ( '/path' )
elements = session . all ( :link ) { | _node | raise Selenium :: WebDriver :: Error :: StaleElementReferenceError }
2017-05-31 17:07:34 -04:00
expect ( elements . size ) . to eq 0
end
end
2018-07-10 17:18:39 -04:00
describe '#evaluate_script' do
it 'can return an element' do
2018-04-27 14:01:47 -04:00
session . visit ( '/form' )
element = session . evaluate_script ( " document.getElementById('form_title') " )
expect ( element ) . to eq session . find ( :id , 'form_title' )
2017-01-27 14:11:13 -05:00
end
2017-01-28 17:34:44 -05:00
2018-07-10 17:18:39 -04:00
it 'can return arrays of nested elements' do
2018-04-27 14:01:47 -04:00
session . visit ( '/form' )
elements = session . evaluate_script ( 'document.querySelectorAll("#form_city option")' )
expect ( elements ) . to all ( be_instance_of Capybara :: Node :: Element )
expect ( elements ) . to eq session . find ( :css , '#form_city' ) . all ( :css , 'option' ) . to_a
2017-01-28 17:34:44 -05:00
end
2018-07-10 17:18:39 -04:00
it 'can return hashes with elements' do
2018-04-27 14:01:47 -04:00
session . visit ( '/form' )
result = session . evaluate_script ( " { a: document.getElementById('form_title'), b: {c: document.querySelectorAll(' # form_city option')}} " )
2018-02-28 19:11:41 -05:00
expect ( result ) . to eq (
2018-04-27 14:01:47 -04:00
'a' = > session . find ( :id , 'form_title' ) ,
2017-01-28 17:34:44 -05:00
'b' = > {
2018-04-27 14:01:47 -04:00
'c' = > session . find ( :css , '#form_city' ) . all ( :css , 'option' ) . to_a
2017-01-28 17:34:44 -05:00
}
2018-02-28 19:11:41 -05:00
)
2017-01-28 17:34:44 -05:00
end
2017-10-25 20:09:32 -04:00
2018-07-10 17:18:39 -04:00
describe '#evaluate_async_script' do
it 'will timeout if the script takes too long' do
2019-03-13 21:21:53 -04:00
skip 'safaridriver returns the wrong error type' if safari? ( session )
2018-04-27 14:01:47 -04:00
session . visit ( '/with_js' )
2017-10-25 20:09:32 -04:00
expect do
2018-04-27 14:01:47 -04:00
session . using_wait_time ( 1 ) do
2018-07-10 17:18:39 -04:00
session . evaluate_async_script ( 'var cb = arguments[0]; setTimeout(function(){ cb(null) }, 3000)' )
2017-10-25 20:09:32 -04:00
end
end . to raise_error Selenium :: WebDriver :: Error :: ScriptTimeoutError
end
end
2017-01-27 14:11:13 -05:00
end
2017-03-21 18:34:18 -04:00
2018-07-10 17:18:39 -04:00
describe 'Element#inspect' do
it 'outputs obsolete elements' do
2018-04-27 14:01:47 -04:00
session . visit ( '/form' )
el = session . find ( :button , 'Click me!' ) . click
expect ( session ) . to have_no_button ( 'Click me!' )
allow ( el ) . to receive ( :synchronize )
2018-07-10 17:18:39 -04:00
expect ( el . inspect ) . to eq 'Obsolete #<Capybara::Node::Element>'
2018-04-27 14:01:47 -04:00
expect ( el ) . not_to have_received ( :synchronize )
2017-03-21 18:34:18 -04:00
end
end
2017-10-02 14:55:13 -04:00
2018-07-10 17:18:39 -04:00
describe 'Element#click' do
it 'should handle fixed headers/footers' do
2018-04-27 14:01:47 -04:00
session . visit ( '/with_fixed_header_footer' )
2019-11-29 13:42:59 -05:00
session . using_wait_time ( 2 ) do
session . find ( :link , 'Go to root' ) . click
end
2018-04-27 14:01:47 -04:00
expect ( session ) . to have_current_path ( '/' )
2017-10-02 14:55:13 -04:00
end
end
2018-03-15 15:48:19 -04:00
2018-09-24 12:41:47 -04:00
describe 'Capybara#Node#attach_file' do
2018-09-25 03:15:02 -04:00
it 'can attach a directory' do
2018-11-18 16:27:00 -05:00
pending " Geckodriver doesn't support uploading a directory " if firefox? ( session )
2018-09-24 12:41:47 -04:00
pending " Selenium remote doesn't support transferring a directory " if remote? ( session )
2022-04-30 13:26:55 -04:00
pending " Headless Chrome doesn't support directory upload - https://bugs.chromium.org/p/chromedriver/issues/detail?id=2521&q=directory%20upload&colspec=ID%20Status%20Pri%20Owner%20Summary " if chrome? ( session ) && ENV . fetch ( 'HEADLESS' , nil )
2018-12-20 15:37:14 -05:00
pending " IE doesn't support uploading a directory " if ie? ( session )
2019-06-04 01:37:49 -04:00
pending 'Chrome/chromedriver 73 breaks this' if chrome? ( session ) && chrome_gte? ( 73 , session ) && chrome_lt? ( 75 , session )
2019-03-13 21:21:53 -04:00
pending " Safari doesn't support uploading a directory " if safari? ( session )
2019-06-01 21:17:59 -04:00
# pending "Edge/msedgedriver doesn't support directory upload" if edge?(session) && edge_gte?(75, session)
2018-09-24 12:41:47 -04:00
session . visit ( '/form' )
2019-02-25 18:50:24 -05:00
test_file_dir = File . expand_path ( './fixtures' , File . dirname ( __FILE__ ) )
session . attach_file ( 'Directory Upload' , test_file_dir )
2018-09-24 12:41:47 -04:00
session . click_button ( 'Upload Multiple' )
expect ( session . body ) . to include ( '5 | ' ) # number of files
end
2019-06-10 17:45:25 -04:00
it 'can attach a relative file' do
2019-07-12 18:40:35 -04:00
pending 'Geckdoriver on windows requires alternate file separator which path expansion replaces' if Gem . win_platform? && firefox? ( session )
2019-06-10 17:45:25 -04:00
session . visit ( '/form' )
session . attach_file ( 'Single Document' , 'spec/fixtures/capybara.csv' )
session . click_button ( 'Upload Single' )
expect ( session . body ) . to include ( 'Content-type: text/csv' )
end
2018-09-24 12:41:47 -04:00
end
2018-07-10 17:18:39 -04:00
context 'Windows' do
2018-03-15 15:48:19 -04:00
it " can't close the primary window " do
expect do
2018-04-27 14:01:47 -04:00
session . current_window . close
2018-03-15 15:48:19 -04:00
end . to raise_error ( ArgumentError , 'Not allowed to close the primary window' )
end
end
2018-05-16 23:04:24 -04:00
2019-02-25 18:50:24 -05:00
# rubocop:disable RSpec/InstanceVariable
2018-08-17 16:57:12 -04:00
describe 'Capybara#disable_animation' do
2018-08-21 12:24:35 -04:00
context 'when set to `true`' do
before ( :context ) do # rubocop:disable RSpec/BeforeAfterAll
2019-03-13 21:21:53 -04:00
skip " Safari doesn't support multiple sessions " if safari? ( session )
2018-08-21 12:24:35 -04:00
# NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
# it doesn't affect any of these tests because the settings are applied per-session
Capybara . disable_animation = true
@animation_session = Capybara :: Session . new ( session . mode , TestApp . new )
end
2018-05-16 23:04:24 -04:00
2021-09-25 19:39:55 -04:00
it 'should add CSS to the <head> element' do
@animation_session . visit ( 'with_animation' )
expect ( @animation_session ) . to have_selector ( :css , 'head > style' , text : 'transition: none' , visible : :hidden )
end
2018-08-21 12:24:35 -04:00
it 'should disable CSS transitions' do
@animation_session . visit ( 'with_animation' )
@animation_session . click_link ( 'transition me away' )
expect ( @animation_session ) . to have_no_link ( 'transition me away' , wait : 0 . 5 )
end
2018-05-16 23:04:24 -04:00
2019-06-19 19:04:43 -04:00
it 'should disable CSS animations (set to 0s)' do
2018-08-21 12:24:35 -04:00
@animation_session . visit ( 'with_animation' )
2020-07-07 01:34:20 -04:00
sleep 1
2018-08-21 12:24:35 -04:00
@animation_session . click_link ( 'animate me away' )
expect ( @animation_session ) . to have_no_link ( 'animate me away' , wait : 0 . 5 )
end
2019-06-19 19:04:43 -04:00
it 'should disable CSS animations on pseudo elements (set to 0s)' do
@animation_session . visit ( 'with_animation' )
2020-07-07 01:34:20 -04:00
sleep 1
2019-06-19 19:04:43 -04:00
@animation_session . find_link ( 'animate me away' ) . right_click
expect ( @animation_session ) . to have_content ( 'Animation Ended' , wait : 0 . 1 )
end
2020-09-29 01:54:16 -04:00
it 'should scroll the page instantly' , requires : [ :js ] do
@animation_session . visit ( 'with_animation' )
scroll_y = @animation_session . evaluate_script ( << ~ JS )
( function ( ) {
window . scrollTo ( 0 , 500 ) ;
return window . scrollY ;
} ) ( )
JS
expect ( scroll_y ) . to eq 500
end
2021-01-23 04:05:17 -05:00
it 'should scroll the page instantly without jquery animation' , requires : [ :js ] do
@animation_session . visit ( 'with_jquery_animation' )
@animation_session . click_link ( 'scroll top 500' )
scroll_y = @animation_session . evaluate_script ( 'window.scrollY' )
expect ( scroll_y ) . to eq 500
end
2020-09-29 01:54:16 -04:00
end
context 'when set to `false`' do
before ( :context ) do # rubocop:disable RSpec/BeforeAfterAll
skip " Safari doesn't support multiple sessions " if safari? ( session )
# NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
# it doesn't affect any of these tests because the settings are applied per-session
Capybara . disable_animation = false
@animation_session = Capybara :: Session . new ( session . mode , TestApp . new )
end
it 'should scroll the page with a smooth animation' , requires : [ :js ] do
@animation_session . visit ( 'with_animation' )
scroll_y = @animation_session . evaluate_script ( << ~ JS )
( function ( ) {
window . scrollTo ( 0 , 500 ) ;
return window . scrollY ;
} ) ( )
JS
# measured over 0.5 seconds: 0, 75, 282, 478, 500
expect ( scroll_y ) . to be < 500
end
2021-01-23 04:05:17 -05:00
it 'should scroll the page with jquery animation' , requires : [ :js ] do
@animation_session . visit ( 'with_jquery_animation' )
@animation_session . click_link ( 'scroll top 500' )
scroll_y = @animation_session . evaluate_script ( 'window.scrollY' )
expect ( scroll_y ) . to be < 500
end
2018-05-16 23:04:24 -04:00
end
2018-08-17 14:07:21 -04:00
2018-08-21 12:24:35 -04:00
context 'if we pass in css that matches elements' do
2018-08-17 14:07:21 -04:00
before ( :context ) do # rubocop:disable RSpec/BeforeAfterAll
2019-03-13 21:21:53 -04:00
skip " safaridriver doesn't support multiple sessions " if safari? ( session )
2018-08-17 14:07:21 -04:00
# NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
# it doesn't affect any of these tests because the settings are applied per-session
Capybara . disable_animation = '#with_animation a'
@animation_session_with_matching_css = Capybara :: Session . new ( session . mode , TestApp . new )
end
it 'should disable CSS transitions' do
@animation_session_with_matching_css . visit ( 'with_animation' )
2020-07-07 01:34:20 -04:00
sleep 1
2018-08-17 14:07:21 -04:00
@animation_session_with_matching_css . click_link ( 'transition me away' )
expect ( @animation_session_with_matching_css ) . to have_no_link ( 'transition me away' , wait : 0 . 5 )
end
it 'should disable CSS animations' do
@animation_session_with_matching_css . visit ( 'with_animation' )
2020-07-07 01:34:20 -04:00
sleep 1
2018-08-17 14:07:21 -04:00
@animation_session_with_matching_css . click_link ( 'animate me away' )
expect ( @animation_session_with_matching_css ) . to have_no_link ( 'animate me away' , wait : 0 . 5 )
end
end
2018-08-21 12:24:35 -04:00
context 'if we pass in css that does not match elements' do
2018-08-17 14:07:21 -04:00
before ( :context ) do # rubocop:disable RSpec/BeforeAfterAll
2019-03-13 21:21:53 -04:00
skip " Safari doesn't support multiple sessions " if safari? ( session )
2018-08-17 14:07:21 -04:00
# NOTE: Although Capybara.SpecHelper.reset! sets Capybara.disable_animation to false,
# it doesn't affect any of these tests because the settings are applied per-session
Capybara . disable_animation = '.this-class-matches-nothing'
@animation_session_without_matching_css = Capybara :: Session . new ( session . mode , TestApp . new )
end
2018-08-21 12:24:35 -04:00
it 'should not disable CSS transitions' do
2018-08-17 14:07:21 -04:00
@animation_session_without_matching_css . visit ( 'with_animation' )
2020-07-07 01:34:20 -04:00
sleep 1
2018-08-17 14:07:21 -04:00
@animation_session_without_matching_css . click_link ( 'transition me away' )
2018-08-21 12:24:35 -04:00
sleep 0 . 5 # Wait long enough for click to have been processed
expect ( @animation_session_without_matching_css ) . to have_link ( 'transition me away' , wait : false )
expect ( @animation_session_without_matching_css ) . to have_no_link ( 'transition me away' , wait : 5 )
2018-08-17 14:07:21 -04:00
end
2018-08-21 12:24:35 -04:00
it 'should not disable CSS animations' do
2018-08-17 14:07:21 -04:00
@animation_session_without_matching_css . visit ( 'with_animation' )
2020-07-07 01:34:20 -04:00
sleep 1
2018-08-17 14:07:21 -04:00
@animation_session_without_matching_css . click_link ( 'animate me away' )
2018-08-21 12:24:35 -04:00
sleep 0 . 5 # Wait long enough for click to have been processed
expect ( @animation_session_without_matching_css ) . to have_link ( 'animate me away' , wait : false )
expect ( @animation_session_without_matching_css ) . to have_no_link ( 'animate me away' , wait : 5 )
2018-08-17 14:07:21 -04:00
end
end
2018-05-16 23:04:24 -04:00
end
2019-02-25 18:50:24 -05:00
# rubocop:enable RSpec/InstanceVariable
2022-04-30 20:02:14 -04:00
2018-09-14 16:00:29 -04:00
describe ':element selector' do
it 'can find html5 svg elements' do
2018-09-14 13:27:02 -04:00
session . visit ( 'with_html5_svg' )
expect ( session ) . to have_selector ( :element , :svg )
2020-05-03 15:00:14 -04:00
expect ( session ) . to have_selector ( :element , :rect , visible : :visible )
2018-09-14 13:27:02 -04:00
expect ( session ) . to have_selector ( :element , :circle )
2018-09-14 16:00:29 -04:00
expect ( session ) . to have_selector ( :element , :linearGradient , visible : :all )
2018-09-14 13:27:02 -04:00
end
2018-09-20 18:15:32 -04:00
it 'can query attributes with strange characters' do
session . visit ( '/form' )
2021-06-10 01:57:25 -04:00
expect ( session ) . to have_selector ( :element , '{custom}' : true )
expect ( session ) . to have_selector ( :element , '{custom}' : 'abcdef' )
2018-09-20 18:15:32 -04:00
end
2018-09-14 13:27:02 -04:00
end
2019-02-19 10:57:40 -05:00
describe 'with react' do
2019-02-24 18:32:07 -05:00
context 'controlled components' do
2019-02-19 10:57:40 -05:00
it 'can set and clear a text field' do
2019-05-20 16:18:34 -04:00
skip " This test doesn't support older browsers " if ie? ( session )
2020-04-04 17:41:18 -04:00
2019-04-04 19:49:47 -04:00
session . visit 'react'
2020-04-04 17:41:18 -04:00
2019-04-04 19:49:47 -04:00
session . fill_in ( 'Name:' , with : 'abc' )
session . accept_prompt 'A name was submitted: abc' do
session . click_button ( 'Submit' )
end
2020-04-04 17:41:18 -04:00
2019-04-04 19:49:47 -04:00
session . fill_in ( 'Name:' , with : '' )
session . accept_prompt ( / A name was submitted: $ / ) do
session . click_button ( 'Submit' )
2019-02-19 10:57:40 -05:00
end
2020-04-04 17:41:18 -04:00
end
2020-04-04 17:46:11 -04:00
it 'works with rapid fill' do
2020-04-04 17:41:18 -04:00
skip " This test doesn't support older browsers " if ie? ( session )
session . visit 'react'
long_string = ( 0 ... 60 ) . map { | i | ( ( i % 26 ) + 65 ) . chr } . join
session . fill_in ( 'Name:' , with : long_string )
session . accept_prompt " A name was submitted: #{ long_string } " do
session . click_button ( 'Submit' )
end
2019-02-19 10:57:40 -05:00
end
end
end
2009-11-14 04:44:46 -05:00
end
2018-04-24 18:47:53 -04:00
def headless_or_remote?
! ENV [ 'HEADLESS' ] . nil? || session . driver . options [ :browser ] == :remote
end
2009-11-14 04:44:46 -05:00
end