capybara 3.20.0 → 3.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -244,6 +244,11 @@ Capybara::SpecHelper.spec 'node' do
244
244
  expect(@session.find('//input[@id="hidden_input"]')).not_to be_visible
245
245
  end
246
246
 
247
+ it 'template elements should not be visible' do
248
+ Capybara.ignore_hidden_elements = false
249
+ expect(@session.find('//template')).not_to be_visible
250
+ end
251
+
247
252
  it 'should be boolean' do
248
253
  Capybara.ignore_hidden_elements = false
249
254
  expect(@session.first('//a').visible?).to be true
@@ -413,6 +418,87 @@ Capybara::SpecHelper.spec 'node' do
413
418
  link.drag_to target
414
419
  expect(@session).to have_xpath('//div[contains(., "Dropped!")]')
415
420
  end
421
+
422
+ context 'HTML5', requires: %i[js html5_drag] do
423
+ it 'should HTML5 drag and drop an object' do
424
+ @session.visit('/with_js')
425
+ element = @session.find('//div[@id="drag_html5"]')
426
+ target = @session.find('//div[@id="drop_html5"]')
427
+ element.drag_to(target)
428
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain drag_html5")]')
429
+ end
430
+
431
+ it 'should set clientX/Y in dragover events' do
432
+ @session.visit('/with_js')
433
+ element = @session.find('//div[@id="drag_html5"]')
434
+ target = @session.find('//div[@id="drop_html5"]')
435
+ element.drag_to(target)
436
+ expect(@session).to have_css('div.log', text: /DragOver with client position: [1-9]\d*,[1-9]\d*/, count: 2)
437
+ end
438
+
439
+ it 'should not HTML5 drag and drop on a non HTML5 drop element' do
440
+ @session.visit('/with_js')
441
+ element = @session.find('//div[@id="drag_html5"]')
442
+ target = @session.find('//div[@id="drop_html5"]')
443
+ target.execute_script("$(this).removeClass('drop');")
444
+ element.drag_to(target)
445
+ sleep 1
446
+ expect(@session).not_to have_xpath('//div[contains(., "HTML5 Dropped")]')
447
+ end
448
+
449
+ it 'should HTML5 drag and drop when scrolling needed' do
450
+ @session.visit('/with_js')
451
+ element = @session.find('//div[@id="drag_html5_scroll"]')
452
+ target = @session.find('//div[@id="drop_html5_scroll"]')
453
+ element.drag_to(target)
454
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain drag_html5_scroll")]')
455
+ end
456
+
457
+ it 'should drag HTML5 default draggable elements' do
458
+ @session.visit('/with_js')
459
+ link = @session.find_link('drag_link_html5')
460
+ target = @session.find(:id, 'drop_html5')
461
+ link.drag_to target
462
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped")]')
463
+ end
464
+ end
465
+ end
466
+
467
+ describe 'Element#drop', requires: %i[js html5_drag] do
468
+ it 'can drop a file' do
469
+ @session.visit('/with_js')
470
+ target = @session.find('//div[@id="drop_html5"]')
471
+ target.drop(
472
+ with_os_path_separators(File.expand_path('../fixtures/capybara.jpg', File.dirname(__FILE__)))
473
+ )
474
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped file: capybara.jpg")]')
475
+ end
476
+
477
+ it 'can drop multiple files' do
478
+ @session.visit('/with_js')
479
+ target = @session.find('//div[@id="drop_html5"]')
480
+ target.drop(
481
+ with_os_path_separators(File.expand_path('../fixtures/capybara.jpg', File.dirname(__FILE__))),
482
+ with_os_path_separators(File.expand_path('../fixtures/test_file.txt', File.dirname(__FILE__)))
483
+ )
484
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped file: capybara.jpg")]')
485
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped file: test_file.txt")]')
486
+ end
487
+
488
+ it 'can drop strings' do
489
+ @session.visit('/with_js')
490
+ target = @session.find('//div[@id="drop_html5"]')
491
+ target.drop('text/plain' => 'Some dropped text')
492
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain Some dropped text")]')
493
+ end
494
+
495
+ it 'can drop multiple strings' do
496
+ @session.visit('/with_js')
497
+ target = @session.find('//div[@id="drop_html5"]')
498
+ target.drop('text/plain' => 'Some dropped text', 'text/url' => 'http://www.google.com')
499
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain Some dropped text")]')
500
+ expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/url http://www.google.com")]')
501
+ end
416
502
  end
417
503
 
418
504
  describe '#hover', requires: [:hover] do
@@ -24,7 +24,7 @@ Capybara::SpecHelper.spec '#scroll_to', requires: [:scroll] do
24
24
  @session.scroll_to(el, align: :center)
25
25
  el_center = el.evaluate_script('(function(rect){return (rect.top + rect.bottom)/2})(this.getBoundingClientRect())')
26
26
  viewport_bottom = el.evaluate_script('document.body.clientHeight')
27
- expect(el_center).to be_within(1).of(viewport_bottom / 2)
27
+ expect(el_center).to be_within(2).of(viewport_bottom / 2)
28
28
  end
29
29
 
30
30
  it 'can scroll the window to the vertical top' do
@@ -124,6 +124,10 @@ module Capybara
124
124
  def be_an_invalid_element_error(session)
125
125
  satisfy { |error| session.driver.invalid_element_errors.any? { |e| error.is_a? e } }
126
126
  end
127
+
128
+ def with_os_path_separators(path)
129
+ Gem.win_platform? ? path.to_s.tr('/', '\\') : path.to_s
130
+ end
127
131
  end
128
132
  end
129
133
 
@@ -178,5 +178,9 @@ banana</textarea>
178
178
  &#x20;&#x1680;&#x2000;&#x2001;&#x2002; &#x2003;&#x2004;&nbsp;&#x2005; &#x2006;&#x2007;&#x2008;&#x2009;&#x200A;&#x202F;&#x205F;&#x3000;
179
179
  </div>
180
180
 
181
+ <template id="template">
182
+ <input />
183
+ </template>
184
+
181
185
  <a href="/download.csv" download>Download Me</a>
182
186
  <a href="/download.csv" download="other.csv">Download Other</a>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Capybara
4
- VERSION = '3.20.0'
4
+ VERSION = '3.21.0'
5
5
  end
data/lib/capybara.rb CHANGED
@@ -73,22 +73,24 @@ module Capybara
73
73
  # [asset_host = String] Where dynamic assets are hosted - will be prepended to relative asset locations if present (Default: nil)
74
74
  # [run_server = Boolean] Whether to start a Rack server for the given Rack app (Default: true)
75
75
  # [raise_server_errors = Boolean] Should errors raised in the server be raised in the tests? (Default: true)
76
- # [server_errors = Array\<Class\>] Error classes that should be raised in the tests if they are raised in the server and Capybara.raise_server_errors is true (Default: [Exception])
76
+ # [server_errors = Array\<Class\>] Error classes that should be raised in the tests if they are raised in the server and {configure raise_server_errors} is true (Default: [Exception])
77
77
  # [default_selector = :css/:xpath] Methods which take a selector use the given type by default (Default: :css)
78
78
  # [default_max_wait_time = Numeric] The maximum number of seconds to wait for asynchronous processes to finish (Default: 2)
79
79
  # [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: true)
80
80
  # [automatic_reload = Boolean] Whether to automatically reload elements as Capybara is waiting (Default: true)
81
81
  # [save_path = String] Where to put pages saved through save_(page|screenshot), save_and_open_(page|screenshot) (Default: Dir.pwd)
82
- # [automatic_label_click = Boolean] Whether Node#choose, Node#check, Node#uncheck will attempt to click the associated label element if the checkbox/radio button are non-visible (Default: false)
82
+ # [automatic_label_click = Boolean] Whether {Capybara::Node::Element#choose Element#choose}, {Capybara::Node::Element#check Element#check}, {Capybara::Node::Element#uncheck Element#uncheck} will attempt to click the associated label element if the checkbox/radio button are non-visible (Default: false)
83
83
  # [enable_aria_label = Boolean] Whether fields, links, and buttons will match against aria-label attribute (Default: false)
84
84
  # [reuse_server = Boolean] Reuse the server thread between multiple sessions using the same app object (Default: true)
85
85
  # [threadsafe = Boolean] Whether sessions can be configured individually (Default: false)
86
- # [server = Symbol] The name of the registered server to use when running the app under test (Default: :webrick)
87
- # [default_set_options = Hash] The default options passed to Node::set (Default: {})
86
+ # [server = Symbol] The name of the registered server to use when running the app under test (Default: :default which uses puma)
87
+ # [default_set_options = Hash] The default options passed to {Capybara::Node::Element#set Element#set} (Default: {})
88
88
  # [test_id = Symbol/String/nil] Optional attribute to match locator aginst with builtin selectors along with id (Default: nil)
89
- # [predicates_wait = Boolean] Whether Capybaras predicate matchers use waiting behavior by default (Default: true)
89
+ # [predicates_wait = Boolean] Whether Capybara's predicate matchers use waiting behavior by default (Default: true)
90
90
  # [default_normalize_ws = Boolean] Whether text predicates and matchers use normalize whitespace behaviour (Default: false)
91
91
  # [allow_gumbo = Boolean] When `nokogumbo` is available, whether it will be used to parse HTML strings (Default: false)
92
+ # [match = :one/:first/:prefer_exact/:smart] The matching strategy to find nodes (Default: :smart)
93
+ # [exact_text = Boolean] Whether the text matchers and `:text` filter match exactly or on substrings (Default: false)
92
94
  #
93
95
  # === DSL Options
94
96
  #
@@ -201,15 +203,13 @@ module Capybara
201
203
  # any string containing HTML in the exact same way you would query the current document in a Capybara
202
204
  # session.
203
205
  #
204
- # Example: A single element
205
- #
206
+ # @example A single element
206
207
  # node = Capybara.string('<a href="foo">bar</a>')
207
208
  # anchor = node.first('a')
208
209
  # anchor[:href] #=> 'foo'
209
210
  # anchor.text #=> 'bar'
210
211
  #
211
- # Example: Multiple elements
212
- #
212
+ # @example Multiple elements
213
213
  # node = Capybara.string <<-HTML
214
214
  # <ul>
215
215
  # <li id="home">Home</li>
@@ -297,7 +297,7 @@ module Capybara
297
297
 
298
298
  ##
299
299
  #
300
- # The current Capybara::Session based on what is set as Capybara.app and Capybara.current_driver
300
+ # The current {Capybara::Session} based on what is set as {app} and {current_driver}.
301
301
  #
302
302
  # @return [Capybara::Session] The currently used session
303
303
  #
@@ -340,7 +340,7 @@ module Capybara
340
340
 
341
341
  ##
342
342
  #
343
- # Yield a block using a specific session name or Capybara::Session instance.
343
+ # Yield a block using a specific session name or {Capybara::Session} instance.
344
344
  #
345
345
  def using_session(name_or_session)
346
346
  previous_session_info = {
@@ -371,6 +371,10 @@ module Capybara
371
371
  def HTML(html) # rubocop:disable Naming/MethodName
372
372
  if Nokogiri.respond_to?(:HTML5) && Capybara.allow_gumbo # Nokogumbo installed and allowed for use
373
373
  Nokogiri::HTML5(html).tap do |document|
374
+ document.xpath('//template').each do |template|
375
+ # template elements content is not part of the document
376
+ template.inner_html = ''
377
+ end
374
378
  document.xpath('//textarea').each do |textarea|
375
379
  # The Nokogumbo HTML5 parser already returns spec compliant contents
376
380
  textarea['_capybara_raw_value'] = textarea.content
@@ -378,6 +382,10 @@ module Capybara
378
382
  end
379
383
  else
380
384
  Nokogiri::HTML(html).tap do |document|
385
+ document.xpath('//template').each do |template|
386
+ # template elements content is not part of the document
387
+ template.inner_html = ''
388
+ end
381
389
  document.xpath('//textarea').each do |textarea|
382
390
  textarea['_capybara_raw_value'] = textarea.content.sub(/\A\n/, '')
383
391
  end
@@ -64,6 +64,8 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumFirefox, 'selenium', capyba
64
64
  pending "Geckodriver doesn't provide a way to remove cookies outside the current domain"
65
65
  when 'Capybara::Session selenium #attach_file with a block can upload by clicking the file input'
66
66
  pending "Geckodriver doesn't allow clicking on file inputs"
67
+ when /drag_to.*HTML5/
68
+ pending "Firefox < 62 doesn't support a DataTransfer constuctor" if firefox_lt?(62.0, @session)
67
69
  end
68
70
  end
69
71
 
@@ -6,13 +6,13 @@ require 'shared_selenium_session'
6
6
  require 'shared_selenium_node'
7
7
  require 'rspec/shared_spec_matchers'
8
8
 
9
- if ENV['CI']
10
- if ::Selenium::WebDriver::Service.respond_to? :driver_path=
11
- ::Selenium::WebDriver::IE::Service
12
- else
13
- ::Selenium::WebDriver::IE
14
- end.driver_path = 'C:\Tools\WebDriver\IEDriverServer.exe'
15
- end
9
+ # if ENV['CI']
10
+ # if ::Selenium::WebDriver::Service.respond_to? :driver_path=
11
+ # ::Selenium::WebDriver::IE::Service
12
+ # else
13
+ # ::Selenium::WebDriver::IE
14
+ # end.driver_path = 'C:\Tools\WebDriver\IEDriverServer.exe'
15
+ # end
16
16
 
17
17
  def selenium_host
18
18
  ENV.fetch('SELENIUM_HOST', '192.168.56.102')
@@ -110,6 +110,12 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumIE, 'selenium', capybara_sk
110
110
  pending 'IE treats blank href as a parent request (against HTML spec)'
111
111
  when /#attach_file with a block/
112
112
  skip 'Hangs IE testing for unknown reason'
113
+ when /drag_to.*HTML5/
114
+ pending "IE doesn't support a DataTransfer constuctor"
115
+ when /template elements should not be visible/
116
+ skip "IE doesn't support template elements"
117
+ when /Element#drop/
118
+ pending "IE doesn't support DataTransfer constructor"
113
119
  end
114
120
  end
115
121
 
@@ -73,6 +73,8 @@ Capybara::SpecHelper.run_specs TestSessions::Safari, SAFARI_DRIVER.to_s, capybar
73
73
  when 'Capybara::Session selenium_safari #go_back should fetch a response from the driver from the previous page',
74
74
  'Capybara::Session selenium_safari #go_forward should fetch a response from the driver from the previous page'
75
75
  skip 'safaridriver loses the ability to find elements in the document after `go_back`'
76
+ when /drag_to.*HTML5/
77
+ pending "Safari doesn't support"
76
78
  end
77
79
  end
78
80
 
@@ -303,57 +303,6 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
303
303
  end
304
304
  end
305
305
 
306
- describe 'Element#drag_to' do
307
- before do
308
- skip "Firefox < 62 doesn't support a DataTransfer constuctor" if firefox_lt?(62.0, session)
309
- skip "IE doesn't support a DataTransfer constuctor" if ie?(session)
310
- skip "Safari doesn't support" if safari?(session)
311
- end
312
-
313
- it 'should HTML5 drag and drop an object' do
314
- session.visit('/with_js')
315
- element = session.find('//div[@id="drag_html5"]')
316
- target = session.find('//div[@id="drop_html5"]')
317
- element.drag_to(target)
318
- expect(session).to have_xpath('//div[contains(., "HTML5 Dropped drag_html5")]')
319
- end
320
-
321
- it 'should set clientX/Y in dragover events' do
322
- session.visit('/with_js')
323
- element = session.find('//div[@id="drag_html5"]')
324
- target = session.find('//div[@id="drop_html5"]')
325
- element.drag_to(target)
326
- session.all(:css, 'div.log').each { |el| puts el.text }
327
- expect(session).to have_css('div.log', text: /DragOver with client position: [1-9]\d*,[1-9]\d*/, count: 2)
328
- end
329
-
330
- it 'should not HTML5 drag and drop on a non HTML5 drop element' do
331
- session.visit('/with_js')
332
- element = session.find('//div[@id="drag_html5"]')
333
- target = session.find('//div[@id="drop_html5"]')
334
- target.execute_script("$(this).removeClass('drop');")
335
- element.drag_to(target)
336
- sleep 1
337
- expect(session).not_to have_xpath('//div[contains(., "HTML5 Dropped drag_html5")]')
338
- end
339
-
340
- it 'should HTML5 drag and drop when scrolling needed' do
341
- session.visit('/with_js')
342
- element = session.find('//div[@id="drag_html5_scroll"]')
343
- target = session.find('//div[@id="drop_html5_scroll"]')
344
- element.drag_to(target)
345
- expect(session).to have_xpath('//div[contains(., "HTML5 Dropped drag_html5_scroll")]')
346
- end
347
-
348
- it 'should drag HTML5 default draggable elements' do
349
- session.visit('/with_js')
350
- link = session.find_link('drag_link_html5')
351
- target = session.find(:id, 'drop_html5')
352
- link.drag_to target
353
- expect(session).to have_xpath('//div[contains(., "HTML5 Dropped")]')
354
- end
355
- end
356
-
357
306
  describe 'Capybara#Node#attach_file' do
358
307
  it 'can attach a directory' do
359
308
  pending "Geckodriver doesn't support uploading a directory" if firefox?(session)
@@ -472,6 +421,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
472
421
  describe 'with react' do
473
422
  context 'controlled components' do
474
423
  it 'can set and clear a text field' do
424
+ skip "This test doesn't support older browsers" if ie?(session)
475
425
  # session.visit 'https://reactjs.org/docs/forms.html'
476
426
  # session.all(:css, 'h2#controlled-components ~ p a', text: 'Try it on CodePen')[0].click
477
427
  # copied into local view
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.20.0
4
+ version: 3.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Walpole
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain:
12
12
  - gem-public_cert.pem
13
- date: 2019-05-15 00:00:00.000000000 Z
13
+ date: 2019-05-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: addressable
@@ -88,28 +88,14 @@ dependencies:
88
88
  requirements:
89
89
  - - "~>"
90
90
  - !ruby/object:Gem::Version
91
- version: '1.2'
91
+ version: '1.5'
92
92
  type: :runtime
93
93
  prerelease: false
94
94
  version_requirements: !ruby/object:Gem::Requirement
95
95
  requirements:
96
96
  - - "~>"
97
97
  - !ruby/object:Gem::Version
98
- version: '1.2'
99
- - !ruby/object:Gem::Dependency
100
- name: uglifier
101
- requirement: !ruby/object:Gem::Requirement
102
- requirements:
103
- - - ">="
104
- - !ruby/object:Gem::Version
105
- version: '0'
106
- type: :runtime
107
- prerelease: false
108
- version_requirements: !ruby/object:Gem::Requirement
109
- requirements:
110
- - - ">="
111
- - !ruby/object:Gem::Version
112
- version: '0'
98
+ version: '1.5'
113
99
  - !ruby/object:Gem::Dependency
114
100
  name: xpath
115
101
  requirement: !ruby/object:Gem::Requirement
@@ -376,6 +362,20 @@ dependencies:
376
362
  - - ">="
377
363
  - !ruby/object:Gem::Version
378
364
  version: 1.4.0
365
+ - !ruby/object:Gem::Dependency
366
+ name: uglifier
367
+ requirement: !ruby/object:Gem::Requirement
368
+ requirements:
369
+ - - ">="
370
+ - !ruby/object:Gem::Version
371
+ version: '0'
372
+ type: :development
373
+ prerelease: false
374
+ version_requirements: !ruby/object:Gem::Requirement
375
+ requirements:
376
+ - - ">="
377
+ - !ruby/object:Gem::Version
378
+ version: '0'
379
379
  - !ruby/object:Gem::Dependency
380
380
  name: webdrivers
381
381
  requirement: !ruby/object:Gem::Requirement