Allow Pathname objects to be used with `attach_file`
dtinth opened this issue · 2 comments
There is a common Rails pattern for uploading files:
attach_file "post[attachment]", Rails.root.join('spec', 'fixtures', 'image.png'), visible: false
This resulted in an error with the following backtrace:
file must be a String or File. (ArgumentError)
/home/ubuntu/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/playwright-ruby-client-1.27.0/lib/playwright/input_files.rb:83:in `raise_argument_error'
/home/ubuntu/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/playwright-ruby-client-1.27.0/lib/playwright/input_files.rb:32:in `block in has_large_file?'
/home/ubuntu/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/playwright-ruby-client-1.27.0/lib/playwright/input_files.rb:25:in `any?'
/home/ubuntu/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/playwright-ruby-client-1.27.0/lib/playwright/input_files.rb:25:in `has_large_file?'
/home/ubuntu/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/playwright-ruby-client-1.27.0/lib/playwright/input_files.rb:15:in `as_method_and_params'
/home/ubuntu/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/playwright-ruby-client-1.27.0/lib/playwright/channel_owners/element_handle.rb:213:in `set_input_files'
/home/ubuntu/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/playwright-ruby-client-1.27.0/lib/playwright_api/element_handle.rb:449:in `set_input_files'
/home/ubuntu/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/capybara-playwright-driver-0.3.0/lib/capybara/playwright/node.rb:248:in `set'
/home/ubuntu/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/capybara-playwright-driver-0.3.0/lib/capybara/playwright/node.rb:208:in `set'
/home/ubuntu/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/capybara-3.36.0/lib/capybara/node/element.rb:123:in `block in set'
/home/ubuntu/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/capybara-3.36.0/lib/capybara/node/base.rb:83:in `synchronize'
/home/ubuntu/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/capybara-3.36.0/lib/capybara/node/element.rb:123:in `set'
/home/ubuntu/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/capybara-3.36.0/lib/capybara/node/actions.rb:304:in `attach_file'
/home/ubuntu/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/capybara-3.36.0/lib/capybara/session.rb:778:in `block (2 levels) in <class:Session>'
/home/ubuntu/.asdf/installs/ruby/2.6.5/lib/ruby/gems/2.6.0/gems/capybara-3.36.0/lib/capybara/dsl.rb:58:in `block (2 levels) in <module:DSL>'
Upon investigation, I found that Rails.root.join
results in a Pathname
object.
As a workaround, I am converting all pathnames to string using .to_s
but IMO it would be great if this is supported natively, so it matches Capybara behavior.
Monkey-patch
# Monkey-patch Capybara::Playwright::Node::FileUpload#set to
# convert paths to String prior to passing them to Playwright.
#
# See: https://github.com/YusukeIwaki/capybara-playwright-driver/issues/52
#
module Capybara::Playwright::Node::FileUploadSetHack
def set(value, **options)
if value.is_a?(Array)
value = value.map(&:to_s)
else
value = value.to_s
end
super(value, **options)
end
end
Capybara::Playwright::Node::FileUpload.prepend(Capybara::Playwright::Node::FileUploadSetHack)
ref: Selenium driver implementation. https://github.com/teamcapybara/capybara/blob/5c8674713fa964211de43138180edfab1cc041ce/lib/capybara/selenium/node.rb#L365
ref: Cuprite, Apprition
https://github.com/rubycdp/cuprite/blob/2fe6236fe66e546915bec67d42fbda35df0d7d4d/lib/capybara/cuprite/node.rb#L102
https://github.com/twalpole/apparition/blob/ca86be4d54af835d531dbcd2b86e7b2c77f85f34/lib/capybara/apparition/node.rb#L125
root cause is YusukeIwaki/playwright-ruby-client#229
However workaround can be implemented in capybara-playwright-driver as Cuprite or Apparition does.