Problems uploading a file using file_field in Watir - ruby

My system:
Windows 10 Pro 64-bit
ruby 2.1.9p490 (2016-03-30 revision 54437) [x64-mingw32]
FireFox 47.0.1
To start, here is the code I'm dealing with:
<div class="dz-style col-sm-7" is="null">
<div is="null">You can drag and drop your supporting document files here, or click to select files to upload.</div>
<input style="display: none;" multiple="" is="null" type="file"></div>
Here is my watir testing code:
Identify and confirm file is valid
local_file = '/Users/tom.feodoroff/Desktop/Charlie_Snoopy.jpg'
File.exists? local_file
raise "error" unless File.exists? local_file
Change the style display so I can interact with control
element = BROWSER.input(:type => 'file')
puts element.attribute_value('style') #display: none;
script = "return arguments[0].style = 'display: inline'"
BROWSER.execute_script(script, element)
puts element.attribute_value('style') #display: inline;
Use suggested syntax to add file to application
BROWSER.file_field(:type => 'file').set(local_file)
This doesn't generate any errors, but it also doesn't attach the file so that my Submit button becomes active. Do I need a different version of Ruby (Watir) to make this work or is there something I'm missing?

I don't understand why, but I added sleep(5) just before clicking the submit button, and now it works. My file icon now appears on the page and the submit button is active and successfully submitted the form. Things that make you go 'hmmmm' :)
Thanks for the responses. Hopefully this will help someone else with this problem?

Related

How to use send keys when input='file' doesn't exist using Ruby and Selenium

I'm working on a web scraper with Ruby and Selenium that will take a CSV file and import it into Google Sheets.
Everything is fine until I need to target the "select a file from your device" input and upload the file using send keys. Normally I see an input='file' tag and use that, however I'm no longer seeing it.
What I would do is
driver.find_element(xpath: '//*[#type="file"]').send_keys("#{Dir.pwd}/my_file.csv")
but this no longer works as there's no type='file'.
This is what I see when I inspect:
<div role="button" class="a-b-c d-u d-u-F" tabindex="0" style="user-select: none;">Select a file from your device</div>
Is there a different way I could do this without targeting an input with a type of "file"?
You could try this XPath expression :
driver.manage.timeouts.implicit_wait=10
element = driver.find_element(:xpath, "//div[#class][contains(text(),'device')]")
element.click
element.send_keys "#{Dir.pwd}/my_file.csv", :enter

How do I click this button using Ruby Capybara?

I'm trying to click a button, but I'm getting the following error:
Unable to find link or button "My Tasks" (Capybara::ElementNotFound)
This is what I get when I inspect it on Chrome:
<a class="btn btn-lg btn-success" href="/tasks" role="button">My Tasks</a>
And this is my code (my steps.rb):
# go to my tasks page
def visitTasksPage
page.has_content?('Signed in succesfully') do
clicK_link 'My Tasks'
end
self
end
I'm new to Ruby Capybara, can anyone help me please?
The problem might be that it's really a link that you're trying to click (an Some Text tag) not a button (a <button type="button">Some text</button> tag). To not have this problem, I recommend that you use the following method:
click_on('My Tasks') # clicks on either links or buttons
Or it could be that the link or button does not appear on the page before Capybara times out. Capybara by default waits 2 seconds before it times out, but you can extend it with
Capybara.default_max_wait_time = 9
Another thing you can do to debug this problem is add a call to binding.pry right before clicking the link/button and check if the button is actually there with the text you expect it to have:
page.has_content?('Signed in succesfully') do
binding.pry # at this point you can test if the link is really there with page.has_content?('My Tasks')
click_link 'My Tasks'
end
Note you would need to install pry by adding it to you Gemfile or with gem install pry.

Copy and print text inside iframe by watir webdriver

I want to copy text inside iframe by watir webdrive and print it. iframe is inside a div.
Both iframe and div have ID.
<div id="sitbReaderKindleSample" style="visibility: visible; width: 497.5px; height: 18138px;">
<iframe id="sitbReaderFrame" scrolling="no" frameborder="0" style="height: 17945px;">
</div>
my code is
targetURL = "https://www.amazon.in/Secret-Druids-Christopher-C-Doyle- ebook/dp/B01BMD4JF0?ie=UTF8&qid=1472664339&ref_=lp_1318158031_1_2&s=books&sr=1"
browser.goto targetURL
browser.image(:id => "ebooksSitbLogoImg").click
itext = browser.div(:id => 'sitbReaderKindleSample').text
puts itext
OUTPUT is
End of this sample Kindle book.
Enjoyed the preview?
Buy now
or even:
See details for this book in the Kindle Store
but i do not need this. This is from outside iframe. i need the text inside iframe.
I tried
itext = browser.iframe(:id => 'sitbReaderFrame').text
its output is blank
Need help to print the text inside the iframe
I use rubymine IDE
You are correct in doing:
browser.iframe(:id => 'sitbReaderFrame').text
If you are getting an empty String, that means you are using an older version of Watir:
In Watir-Webdriver v0.9.1 (and prior): iframe.text returned the text nodes of the iframe element, which is always nothing.
In Watir-Webdriver v0.9.2 (and later): iframe.text was changed to switch to the iframe context and then return its body text (which is what you want).
You should make sure that you are using the latest version.
itext = browser.iframe(:id => 'sitbReaderFrame').body.text
This works for me, adding the body to the chain.

Pasting large text into a Watir Webdriver textfield in Ruby

I have a text field that I am trying to manipulate with Watir Webdriver in Ruby, which is in this format:
<div class="fieldwrapper" ng-hide="tempPageContent.eulaModal.standardEula">
<label class="ng-binding">Custom License Agreement</label>
<textarea ng-model="tempEula.EULAText" class="med ng-pristine ng-valid"></textarea>
<!-- <span text-area-with-counter="tempEula.EULAText"
text-limit="{{ referenceData.appMetaDataReference.maxEulaChars }}"
text-area-class="med"
text-area-required="tempPageContent.eulaModal.customEula"
text-area-itc-field-server-error="versionInfo.eula.errorKeys"
text-area-itc-field-orig-val="orignalVersionInfo.eula.EULAText"
text-area-itc-field-cur-val="tempEula.EULAText"
text-area-itc-empty-errormsg="Enter the license agreement"
text-area-itc-char-exceed-errormsg="The license agreement can not exceed {{ referenceData.appMetaDataReference.maxEulaChars }} characters"></span> -->
</div>
I need to insert a large String that is extracted from a text file into this text field, but using the standard Watir.textarea.set won't work as it would time-out in 30 seconds. Here is what I am trying to do at the moment:
#browser.execute_script("arguments[0].value = arguments[1]", text_field, eula_text)
which injects the text into the text field, but does not enable the 'Save' button, which is triggered by the native set method, but not by Javascript.
I saw some post by jarib, who proposed the usage of Mac's pbcopy for copying text and then using the send_keys([:command, 'v']), but using the send_keys does not work, although the text is in the IO buffer. I tried both open and popen methods. I also tried using pbpaste on Watir textarea element...
I cannot think of a novel idea to accomplish my task and any pointers in the right direction would be appreciated. I am just not familiar with the way AngularJS text fields work with text input.
I am using the latest watir-webdriver 0.9.1 and chromedriver.
3 possibilities:
1) Increase the client timeout:
client = Selenium::WebDriver::Remote::Http::Default.new
client.timeout = 180
b = Watir::Browser.new :chrome, http_client: client
2) Don't do all the text at once:
File.open('xxx.txt').each do |line|
textfield.append(line)
end
3) Use your javascript code to copy everything in, then use textfield.append(' ') to enable the save button.

A way around Element cannot be scrolled into view - Watir-webdriver with Ruby

So, we have the following code in our page:
<div class="toggle-wrapper">
<input id="HasRegistration_true" class="registration_required toggle" type="radio" value="True" name="HasRegistration" data-val-required="The HasRegistration field is required." data-val="true">
<label for="HasRegistration_true" class="">On</label>
<input id="HasRegistration_false" class="registration_required toggle" type="radio" value="False" name="HasRegistration" checked="checked">
<label class="checked" for="HasRegistration_false">Off</label>
</div>
These are 2 radio buttons. 'On' and 'Off'. 'Off' is the default value.
Using Watir-webdriver and Ruby, we want to select the 'On' radio button. We do so like this:
browser.radio(:id => "HasRegistration_true").set
But in doing so, we get the following error:
`WebElement.clickElement': Element cannot be scrolled into view:[object HTMLInputElement] (Selenium::WebDriver::Error::MoveTargetOutOfBoundsError)
We know Selenium 2 scrolls the page to the element, so trying to scroll down is useless.
We are always using the latest releases of watir-webdriver and ruby.
We can't change the HTML of the page since we're QA engineers.
Here are two solutions that have worked for me:
There is a Ruby gem called watir-scroll that can work.
Then
require 'watir-scroll'
browser.scroll.to browser.radio(:id, "HasRegistration_true")
If you don't want to add a gem, my co-worker suggested something that somewhat surprisingly (to me) had the same effect as the above code:
browser.radio(:id, "HasRegistration_true").focus
browser.radio(:id, "HasRegistration_true").set
In my code, ".focus" scrolled straight to the element that was previously not visible. It may work for you as well.
First of all try locating the element using XPATH:
browser.element(:xpath, "//input[#id='HasRegistration_true']").click
or
alternatively if it is a hidden element you are trying to locate then you are better off using CSS. Download firebug add-on for firefox and copy the CSS path of your element.
It should be something like:
browser.element(:css => "the CSS path you have copied from Firebug").click
One of the 2 should do it for you!!
Best of luck!
You could manipulate the html on the fly by executing some javascript to make the radio element settable. To execute javascript on a page, do something like:
#browser.execute_script("your javascript here")
I used something like the following javascript to strip the class out of a label tag which moved it out of the way of the input tag I was attempting to act on for a Chrome specific problem I had.
execute_script("$(\"label.classname\").removeClass(\"classname inline\")")
If the element is contained within a form and a div (Wrap) class I found that I had to do the following to click the 'No' radio button on the "https://quote.comparethemarket.com/Motor/Motor/AboutYourVehicle.aspx?" page:
div_list = #browser.form(:action => "AboutYourVehicle.aspx?ton_t=CTMMO&prdcls=PC&rqstyp=newmotorquote&AFFCLIE=CM01").div(:class => "inputWrap").divs(:class => "custom-radio")
And then:
div_list[1].click
Hope this solves your issue too :-)
I'm not using watir but I have the same error as you "...could not be scrolled into view ...". I tried to use watir just to solve it and didn't work for me. Then, I use an ActionBuilder (move_to with click) and the error disappeared.
My line to avoid the error is:
#driver.action.move_to(*webelement*).click.perform
I hope it will be useful for you

Resources