Testing HTML5 File Upload with Capybara/Selenium Webdriver - Ruby

Testing HTML5 File Upload with Capybara/Selenium Webdriver - Ruby

So I have solved it, and its not too ugly. I used the automation route via AutoIT. The bundle you download with AutoIT includes a script to exe converter and using the below script (I can not take credit for the script) I created an exe:

Local Const $dialogTitle = $CmdLine[2]
Local Const $timeout = 5

Local $windowFound = WinWait($dialogTitle, "", $timeout)

$windowFound = WinWait($dialogTitle, "", $timeout)
Local $windowHandle

If $windowFound Then
$windowHandle = WinGetHandle("[LAST]")
WinActivate($windowHandle)

ControlSetText($windowHandle, "", "[CLASS:Edit; INSTANCE:1]", $CmdLine[1])
ControlClick($windowHandle, "", "[CLASS:Button; TEXT:&Open]")
Else
MsgBox(0, "", "Could not find window.")
Exit 1
EndIf

In my capybara script, I merely run:

find_field(<<upload_file_id>>).click
system("<<full_path>>\\file_upload.exe \"#{<<file_path>>}\" \"File Upload\"")

and it works perfectly! In fact, I think I prefer the fact it exactly mimics what a user would be doing.

Capybara returns Argument error when attach the file

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.

Capybara doesn't wait till the end of file upload

So, the turnaround was maybe not the most professional but at least it worked and I can automate some things now.

Basically, I used has_button? to make my script wait till the APK file will be uploaded. 200sec is enough for file upload (statistically).
In the end, the script makes a pause but I decided to add sleep 3 in the end just to be on the safe side.

Here is the function which uploads APK for me. Maybe someone will need it

 def create_release
puts('Create release and upload APK')
browser.find(:element, 'div', role: 'menuitem', text: 'Production').click
create_release_btn = browser.all(:button, text: 'Create new release')
create_release_btn[0].click

#OPT out
browser.click_button('Manage preferences', wait: 200)
sleep 2
browser.choose('Opt out of app signing by Google Play')
browser.click_button('Update', wait: 100)
sleep 3
op_out_btn = browser.all(:button, text: 'Opt out', wait: 500)
op_out_btn[0].click
sleep 4

#File upload part and saving
upload_btn = browser.all(:element, 'span', text: 'Upload')
browser.attach_file($app_path) do
upload_btn[0].click
end
save_btn = browser.all(:element, 'material-button', text: 'Save', disabled: false, wait: 200)
browser.has_button?(save_btn, disabled: false, wait: 200)
button_test = browser.all(:button, text: 'Save', wait: 100)
button_test[0].click

sleep 3
end

capybara poltergeist cant upload file

File inputs are often hidden for styling reasons, which makes them non-interactable. Because of that capybara'sattach_file has an option to make it easier to temporarily make the file input visible/interactable

page.attach_file field, file_path, make_visible: true

That will temporarily apply CSS { opacity: 1, display: 'block', visibility: 'visible' } to the file input element. If that CSS won't make the input visible you can set make_visible to a hash that will rather than true



Related Topics



Leave a reply



Submit