2
votes

I use ruby, cucumber and capybara.

My html looks like this:

     <tr>
        <th>
            Promotion codes
            </th><td><div class="t-zone" id="promocodesZone">
            <span style="display: inline-block;">
        <span class="field"><label class="field-label">File name:
                <span style="text-transform: none;" class="status-ok"></span></label></span>
        <span class="field"><label class="field-label">Codes available:
                <span style="text-transform: none;" class="status-ok">0</span></label></span>
        <span class="field"><label class="field-label">Codes used:
                <span style="text-transform: none;" class="status-ok"></span></label></span>
        <span class="field"><label class="field-label">Codes uploaded on:
                <span style="text-transform: none;" class="status-ok"></span></label></span>
        </span>
    <div style="margin-bottom: 15px;"><div class="t-upload">
        <div id="promocodesUpload">
        <div class="qq-uploader">
        <div class="qq-upload-drop-area" style="display: none;"><span>Drop </span></div>
        <a class="qq-upload-button btn" style="position: relative; overflow: hidden; direction: ltr;">Upload
<input type="file" name="file" style="position: absolute; right: 0px; top: 0px; font-family: Arial; font-size: 118px; margin: 0px; padding: 0px; cursor: pointer; opacity: 0;"></a>
<ul class="qq-upload-list"></ul></div></div>
        </div>
        </div>
        </div>
        </td>
        </tr>

Basically what I need to do is to upload a file by clicking on link "Upload":

<a class="qq-upload-button btn" style="position: relative; overflow: hidden; direction: ltr;">Upload<input type="file" name="file" style="position: absolute; right: 0px; top: 0px; font-family: Arial; font-size: 118px; margin: 0px; padding: 0px; cursor: pointer; opacity: 0;"></a>

But I keep failing because capybara is unable to find the necessary element... I have tried many things already:

attach_file('//*[@id="promocodesUpload"]/div/a/input', File.absolute_path($campaign_promotional_code_path))

Result: Unable to find file field "//*[@id=\"promocodesUpload\"]/div/a/input" (Capybara::ElementNotFound)

and

within(:xpath, '//*[@id="promocodesUpload"]/div/a') do
   attach_file("input", File.absolute_path($campaign_promotional_code_path))
 end

Result: Unable to find file field "input" (Capybara::ElementNotFound)

and

attach_file("Upload", File.absolute_path($campaign_promotional_code_path)

Result: Unable to find file field "Upload" (Capybara::ElementNotFound)

and

click_link("Upload")

Result: Unable to find link "Upload" (Capybara::ElementNotFound)

and

Any help please? :)

5

5 Answers

4
votes

Try this:

page.driver.browser.all(:xpath, '//input[@name="file"]')[0].send_keys('/home/userA/Desktop/chivalry-medieval-warfare.jpg')

or:

page.driver.browser.all(:xpath, '//input[@type="file"]').last.send_keys('/home/userA/Desktop/chivalry-medieval-warfare.jpg') 
3
votes

Capybara can't find the file input because it's opacity is 0, so it's hidden on the page. - Your best bet is to use execute_script to modify the file inputs style attribute so it becomes visible before calling attach_file

3
votes

If you have jQuery on your web page:

page.execute_script("$('input[name=file]').css('opacity','1')")

If you don't have jQuery on your web page:

page.execute_script("document.getElementsByName('file')[0].style.opacity = 1")
0
votes

As per documentation you can set make_visible option to true if the element is hidden somehow.

# will attach file to a descendant file input element that has a name, id, or label_text matching 'My File'
page.attach_file('My File', '/path/to/file.png', make_visible: true)
0
votes
attach_file("user[logo]", Rails.root + "app/assets/images/image.jpeg", make_visible: true)

It is better: "In the case of the file field being hidden for styling reasons the make_visible option can be used to temporarily change the CSS of the file field, attach the file, and then revert the CSS back to original."

make_visible: true

As recommended here: https://www.rubydoc.info/gems/capybara/Capybara%2FNode%2FActions:attach_file