Search code examples
rubycapybarabrowser-automation

Capybara returns Argument error when attach the file


I am working on browser automation and trying to attach the file using the Capybara software. I have a button by clicking which my script should start to upload the file. It works already in one place on the same website for me, so I am trying to implement it again.

The way I do it:

$private_key_path = '/Users/user1/Desktop/my_file.zip'

upload_generated_zip_btn = browser.all(:element, 'material-button', text: 'Upload generated ZIP')

browser.attach_file($private_key_path) do
  upload_generated_zip_btn[0].click
end

But in fact my script just clicks the button, then appears the pop-up where I can manually choose the file. After several seconds the script fails with the following error:

ArgumentError: Capybara was unable to determine the file input you're attaching to

I looked at the docs, at original code but didn't understand the issue. The manual upload of the same files works. Tried to change the locator - no results.

The screenshot of the button code:

enter image description here

Source Code:

enter image description here


Solution

  • When using the block version of attach_file Capybara attaches a listener for clicks on <input type="file"> elements and uses that to determine which input you want a file attached to. Since it's not finding it either it's not triggering the click, or the way your code is structured is hiding the click from Capybara. First I'd ask why you're using all and the element selector type to find the button and instead suggest (assuming browser is the Capybara session??)

    browser.attach_file($private_key_path) do
      browser.find('material-button', text: 'Upload generated ZIP').click
    end
    

    It's tough to say if that's correct because you don't actually show the HTML for a button with that text in your question though. If that still doesn't work then you're going to need to actually locate the file input element and use the non-block version of attach_file. Something like

    attach_file($private_key_path, make_visible: true)
    

    or by first finding the file input yourself

    browser.find('input[type="file"]', visible: false).attach_file($private_key_path, make_visible: true)
    

    Again it's hard to say for sure since your HTML doesn't appear to actually show the button you're trying to click.