capybara-playwright-driver 0.5.9 → 0.5.10

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a319465a40c53ac5b47d86ccd4d15136c20dcf7f6dde6fe17b3906d44cb2fd94
4
- data.tar.gz: 1e38fb6020a87a07e6eaa8e997084b3abd98a0a8d5cbec4e92819a960c525f62
3
+ metadata.gz: a9766817ce50a7580acf4f72c062780da5a2363ea838dea3a8f17207c359c144
4
+ data.tar.gz: 5b48eb5b0eb4145088457e8b0c1a26c5843f80dc3e3d9acf120c095fd2d7691a
5
5
  SHA512:
6
- metadata.gz: 5d1d8aeccb05f0c667c3b1a617cb1d2f19eb7fa096788a46b81985730f1a75b6ee7196ad952d2152c173b7401980090f738db399503b3ddceac097ced637678c
7
- data.tar.gz: 141fd5024a9d322faf9031951e0f74a61426af350ed06d73017b2db90ec5b866e1af9b17edd5017e5c35f79f198cfa5916b220afcf621db9a2538c5fb50f443b
6
+ metadata.gz: d7b079c7c184643a16cfae94e7aaafd325460a3a13e3ece9cf453b127045a44a8ea008b29b65c326325ad3cbb7b3a8f092ff325267df512ac3f1645565ef6baa
7
+ data.tar.gz: 46290aabe5623d54094efa2cd30369261ca32525b99835e0f6e393ddc48de3e9d1e21011e64cd61dfd00531bf05818dab69525c1cb450f9f2d46679b9c19b0c5
data/AGENTS.md CHANGED
@@ -105,3 +105,11 @@ end
105
105
  ## General Guidance
106
106
  - Prefer concise Ruby that reads top-to-bottom without carrying unnecessary temporary state.
107
107
  - Prefer small private helper objects only when they reduce complexity. Once extracted, give them Ruby-like method names and keep their public surface minimal.
108
+
109
+ ## How to execute RSpec or Ruby
110
+
111
+ `ruby` uses macOS system ruby interpreter (typically 2.6 or older). rbenv should be used.
112
+
113
+ - Do not run the full `spec/capybara/playwright_spec.rb` or full RSpec suite locally; run broad coverage in GitHub Actions.
114
+ - To run a focused Playwright compatibility check locally, use an example filter, for example:
115
+ `RBENV_VERSION=$(cat .ruby-version) ~/.rbenv/shims/bundle exec rspec spec/capybara/playwright_spec.rb --example fill_in`
data/Gemfile CHANGED
@@ -15,6 +15,7 @@ gem 'rack-test_server'
15
15
  gem 'rake', '~> 13.0.3'
16
16
  gem 'rspec', '~> 3.11.0'
17
17
  gem 'rubocop-rspec'
18
+ gem 'selenium-webdriver', '~> 4.34.0' if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.2')
18
19
  gem 'sinatra', '>= 1.4.0'
19
20
  gem 'webrick'
20
21
  gem 'websocket-driver'
@@ -89,10 +89,20 @@ module Capybara
89
89
  }
90
90
  end
91
91
 
92
+ private def firefox?
93
+ @playwright_browser.browser_type.name == 'firefox'
94
+ end
95
+
92
96
  def refresh
93
- assert_page_alive {
97
+ if firefox?
98
+ # ref: https://github.com/microsoft/playwright/issues/39738
94
99
  @playwright_page.capybara_current_frame.evaluate('() => { location.reload(true) }')
95
- }
100
+ else
101
+ assert_page_alive {
102
+ response = @playwright_page.reload
103
+ @playwright_page.capybara_set_last_response(response)
104
+ }
105
+ end
96
106
  end
97
107
 
98
108
  def find_xpath(query, **options)
@@ -255,7 +265,8 @@ module Capybara
255
265
  when /Element is not attached to the DOM/,
256
266
  /Execution context was destroyed, most likely because of a navigation/,
257
267
  /Cannot find context with specified id/,
258
- /Unable to adopt element handle from a different document/
268
+ /Unable to adopt element handle from a different document/,
269
+ /maybe frame was detached/
259
270
  # ignore error for retry
260
271
  @internal_logger.warn(err.message)
261
272
  else
@@ -318,16 +329,35 @@ module Capybara
318
329
 
319
330
  def window_size(handle)
320
331
  on_window(handle) do |page|
321
- page.evaluate('() => [window.innerWidth, window.innerHeight]')
332
+ outer_window_size(page)
322
333
  end
323
334
  end
324
335
 
325
336
  def resize_window_to(handle, width, height)
326
337
  on_window(handle) do |page|
327
- page.viewport_size = { width: width, height: height }
338
+ page.viewport_size = viewport_size_for(page, width, height)
328
339
  end
329
340
  end
330
341
 
342
+ # Capybara follows Selenium's outer window size semantics.
343
+ private def outer_window_size(page)
344
+ page.evaluate('() => [window.outerWidth || window.innerWidth, window.outerHeight || window.innerHeight]')
345
+ end
346
+
347
+ private def viewport_size_for(page, width, height)
348
+ inset_width, inset_height = page.evaluate(<<~JAVASCRIPT)
349
+ () => [
350
+ Math.max(0, (window.outerWidth || window.innerWidth) - window.innerWidth),
351
+ Math.max(0, (window.outerHeight || window.innerHeight) - window.innerHeight)
352
+ ]
353
+ JAVASCRIPT
354
+
355
+ {
356
+ width: [width - inset_width, 0].max,
357
+ height: [height - inset_height, 0].max
358
+ }
359
+ end
360
+
331
361
  def maximize_window(handle)
332
362
  @internal_logger.warn("maximize_window is not supported in Playwright driver")
333
363
  # incomplete in Playwright
@@ -258,7 +258,7 @@ module Capybara
258
258
  end
259
259
 
260
260
  private def capybara_default_wait_time
261
- Capybara.default_max_wait_time * 1100 # with 10% buffer for allowing overhead.
261
+ Capybara.default_max_wait_time.to_f * 1100 # with 10% buffer for allowing overhead.
262
262
  end
263
263
 
264
264
  class NotActionableError < StandardError ; end
@@ -411,15 +411,13 @@ module Capybara
411
411
  end
412
412
 
413
413
  text = value.to_s
414
- if press_enter = text.end_with?("\n")
414
+ if press_enter = text.end_with?("\r\n")
415
+ text = text[0...-2]
416
+ elsif press_enter = text.end_with?("\n")
415
417
  text = text[0...-1]
416
418
  end
417
419
 
418
- if options[:clear] == :none
419
- @element.type(text, timeout: @timeout)
420
- else
421
- @element.fill(text, timeout: @timeout)
422
- end
420
+ set_text(text, append: options[:clear] == :none)
423
421
 
424
422
  if press_enter
425
423
  @element.press('Enter', timeout: @timeout)
@@ -429,6 +427,41 @@ module Capybara
429
427
 
430
428
  @internal_logger.info("Node#set: element is not editable. #{@element}")
431
429
  end
430
+
431
+ private def set_text(text, append:)
432
+ # ElementHandle#type can refocus inherited contenteditable descendants and drop the input.
433
+ if @element.evaluate('el => el.isContentEditable') && !append
434
+ @element.fill(text, timeout: @timeout)
435
+ return
436
+ end
437
+
438
+ if text.include?("\t")
439
+ type_tab_separated_text(text, append: append)
440
+ return
441
+ end
442
+
443
+ grapheme_clusters = text.scan(/\X/)
444
+ fill_text = grapheme_clusters[0...-1].join
445
+ typed_text = grapheme_clusters[-1].to_s
446
+
447
+ if append
448
+ @element.type(fill_text, timeout: @timeout) unless fill_text.empty?
449
+ else
450
+ @element.fill(fill_text, timeout: @timeout)
451
+ end
452
+ @element.type(typed_text, timeout: @timeout) unless typed_text.empty?
453
+ end
454
+
455
+ private def type_tab_separated_text(text, append:)
456
+ head, *tail = text.split("\t", -1)
457
+ set_text(head, append: append)
458
+ keyboard = @element.owner_frame.page.keyboard
459
+
460
+ tail.each do |part|
461
+ keyboard.press('Tab')
462
+ keyboard.type(part) unless part.empty?
463
+ end
464
+ end
432
465
  end
433
466
 
434
467
  class FileUpload < Settable
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Capybara
4
4
  module Playwright
5
- VERSION = '0.5.9'
5
+ VERSION = '0.5.10'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara-playwright-driver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.9
4
+ version: 0.5.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - YusukeIwaki