have trouble with using capybara-webkit attach_file upload an image

1.1k views Asked by At

I want to test the function to add an image to the application. How can I do this. attach_file method is not work. I don't know why.

html:

<form id="edit_user_5577b0c4a851ac600c000002" class="form-horizontal user-settings" method="post" enctype="multipart/form-data" action="/tardis54" accept-charset="UTF-8">
    <div id="upload-avatar" class="control-group">
        ::before
        <label class="control-label" for="user_avatar">
            Setting avatar
        </label>
        <div class="controls">
            <div class="form-fileupload">
                <div class="image-preview">
                    <img class="gravatar img-circle" width="60" height="60" src="http://gravatar.com/avatar/7046a07b25397e4a0c838a47c88d8742?default=identicon&secure=false&size=60" data-retina-url="http://gravatar.com/avatar/7046a07b25397e4a0c838a47c88d8742?default=identicon&secure=false&size=120" alt="tardis54"></img>
                </div>
                <span class="btn btn-fileinput btn-default">
                    <span>
                        Choose file ...
                    </span>
                    <input id="user_avatar" class="input-file" type="file" name="user[avatar]"></input>
                </span>
            </div>
        </div>
   </div>
    <div class="form-actions pull-right">
        <input class="btn btn-large btn-primary" type="submit" value="Update" name="commit"></input>
    </div>
</form>

test code:

scenario "upload a custom avatar" do
    attach_file("user[avatar]", Rails.root + "temp4.png")
end 

error log:

Failure/Error: attach_file("user[avatar]", Rails.root + "temp4.png")
 Capybara::Webkit::ClickFailed:
   Failed to click element /html/body/div[@id='content']/div/div/div/div/div/div[2]/form[@id='edit_user_5580e19da851ac6a51000002']/div[@id='upload-avatar']/div/div/span/input[@id='user_avatar'] 
because of overlapping element /html/body/div[@id='content']/div/div/div/div/div at position 740, 627;
4

There are 4 answers

0
Joe Ferris On BEST ANSWER

It looks like you're using CSS to overlay another element on top of the HTML input. Some people do this because it's difficult to style HTML file inputs directly. However, doing so breaks capybara-webkit, because it needs to click on the actual HTML input field and the styled element is positioned on top of it.

This is being discussed in a GitHub issue.

You can work around it in the test by using execute_script to hide the overlay element, and then attempting to upload the file.

0
dmr On

I could assume that input[type=file] is not visible, thus you need initially make it visible f.e. execute javascript $("input[type=file]").show() and than attach file

0
tardis On

I find a way to solve this problem.

script = "$('#user_avatar').css({opacity: 100, display: 'block', position: 'relative', left: ''});" page.execute_script(script)

0
bovender On

Here's my implementation of @tardis answer (which itself is an implementation of @joe-ferris' suggestion). I put it as an answer to be able to use code formatting.

# spec/support/file_uploads.rb
module FileUploads
  # Enables file uploads by capybara-webkit on pages that 
  # style file their input fields
  def attach_file_styled_input(element_id, file)
    page.execute_script("$('##{element_id}')" +
      ".css({opacity: 100, display: 'block', position: 'relative', left: ''});")
    attach_file element_id, file
  end
end

Don't forget to include this support module in spec/rails_helper.rb:

config.include FileUploads

Then use it in your feature spec like this (not spectacular):

attach_file_styled_input 'my_input_id', 'my_file'