I have the following code on the page:
<div class="col-md-5 col-lg-3">
<div class="react-selectize bootstrap3 root-node simple-select open">
<div class="react-selectize-control">
<div class="react-selectize-placeholder">testing!</div>
<div class="react-selectize-search-field-and-selected-values">
<input class="resizable-input" style="width: 4px;" type="input">
If I physically select the input field and then run the following using watir-classic:
BROWSER.div(:class => 'col-md-5 col-lg-3')
.div(:class => 'react-selectize-search-field-and-selected-values')
.text_field(:class => 'resizable-input')
.send_keys('Magg')
it will enter Magg into the field, but if I don't manually select the field I can't seem to get watir to enter the text.
I've tried the following:
BROWSER.div(:class => 'col-md-5 col-lg-3')
.div(:class => 'react-selectize-search-field-and-selected-values')
.text_field(:class => 'resizable-input')
with
.set('Magg')
.fire_event('onfocus')
.fire_event('mousedown')
.fire_event('mouseup')
using
.parent.text_field(:class => 'resizable-input')
.parent.input(:class => 'resizable-input').set('Magg')
.input(:class => 'resizable-input').set('Magg')
.input(:class => 'resizable-input').send_keys('Magg')
I've been working with the developer using the control and neither of us can figure out how to give the control focus so that the send_keys works without manually selecting the control. Any guidance would be greatly appreciated.
First - obligatory warning that Watir Classic is deprecated and you should be using Watir WebDriver. (which may fix this issue)
Second - technically: div(:class => 'col-md-5 col-lg-3') should be div(:css => '.col-md-5.col-lg-3') since class should be singular.
Have you tried just doing element.fire_event(:click) before element.set?
Be aware that your HTML has an invalid 'type' value for the input tag. Per W3.org the type of 'input' is not a valid type choice for an input tag.
That is likely what is causing the method you expect to work (such as .set) to fail. It also means that all the watir methods to return the more specific sub-types of input (e.g. .text_field) will not work to select that tag.
Watir defines the specific input related methods (such as .set, .unset) according to the specific sub-type of input tag, and has methods to select those specific input types (such as .button). Normally you'd select an input tag using the method for it's sub-type, but because that value is not valid, that is not an option in this case, and you are forced to use .input. But as we just discussed, the input object in watir does not have methods like .set defined. So your only fallback is to use .sendkeys to send keystrokes to the element.
If it was me I'd write up a bug on that HTML, that it is not using a proper value for 'type' per the W3 spec.
Fixing the HTML to be valid will likely cause it to work far better with Watir or any other automation tool, especially those based on webdriver.
Related
The element in this html is dynamic:
<textarea class="Medium" id="z46a662fd68e143128cd31e6978f63a5c"
name="Description" placeholder="" data-val-length="Character limit (8000)
exceeded" data-val-length-max="8000" data-val-editor-
id="z46a662fd68e143128cd31e6978f63a5c" data-val-position="0"></textarea>
I am unable to use this code in my script more than once:
driver.find_element_by_css_selector('z46a662fd68e143128cd31e6978f63a5c')
With the code below, I was able to find the element by name - but unable to use send_keys to input data.
driver.find_element_by_name('Description')
I'd like to know more than one workaround for this type of issue - Thanks in advance.
The first statement is not a proper CSS selector, hence it fails. If you wanted to choose by CSS, you could specify it like this:
driver.find_element_by_css_selector('textarea#z46a662fd68e143128cd31e6978f63a5c')
Or you could search by ID, if ID is static:
driver.find_element_by_id('z46a662fd68e143128cd31e6978f63a5c')
However it looks like your ID is dynamic, in which case looking up by name, like you did, is actually the best approach.
To send keys, you can:
driver.find_element_by_name('Description').send_keys("Hello")
If that doesn't work, make sure page loaded and textarea is rendered. You may need to use Wait:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.Name, "Description"))
element.send_keys("Hello")
the HTML Element looks like
<div class="toggleButton" ng-class="{checked: settings.$storage.enabledApps[app.name]}" ng-click="settings.apps.toggleApp(app.name)"><input class="workplayEnabled switch" type="checkbox" ng-checked="settings.$storage.enabledApps[app.name]"></div>
i tried browser.click('.toggleButton .switch'),browser.click('.toggleButton'), browser.click(' .switch')
but it's not working
it throws the error as element not visible
whereas if i try browser.isSelected('.toggleButton .switch'),browser.isSelected('.toggleButton'), browser.isSelected(' .switch') it returns false
As it stands, it's really hard to pin-point your EXACT problem as you're doing multiple things wrong.
HTML breakdown:
that is HTML generated via AngularJS;
if you analyze the Angular attributes (ng-attributes/directives) you'll notice only your <div> has click-triggered functionality added (via ng-click="settings.apps.toggleApp(app.name)"), thus you only have to target the <div> element;
the <input> only has reactive behavior (if the toggle-button is checked, then it gets populated on ng-checked trigger);
Your problem: Now that we narrowed down the solution to clicking your <div>, we need to make sure your selector is returning the correct element.
open your Angular app, open the browser console & try seeing if your selector is working (e.g.: $(div.toggleButton)). If the CSS-selector returns more than an element($(div.toggleButton).length > 1), that means you have multiple <div>s with that class so you will have to find a more specific locator;
after you have found the correct locator for your <div>, I would add a .debug()(more info here) prior to your click in your WebdriverIO script so I could easily debug the scenario;
once in debug-mode, I would try with the same selector that found my element in the browser console.
!!! Note: .isSelected() will always return false in your scenario as you mentioned you failed to click the toggle switch, which is satisfying the ng-checked condition. You can verify this by manually selecting your toggle switch in debug-mode and then performing the .isSelected() command on your <input>. Then it should return true.
For the html:
<div class="controls">
<input type="text" id="13796781312861791131776">
I tried the following to clear the text field:
#browser.div(:class => /controls/).text_field(:topics_text_field, id:'13796781312861791131776').clear
Which gave the the following error:
expected one of [String, Regexp], got {:id=>"13796781312861791131776"}:Hash (TypeError)
Note: I am using Ruby 2.0.
It's because of how you're defining the attributes of the text field.
You are basically telling Watir that your text field can be identified by the Hash key/value pair of
:topics_text_field => :id=> '13796781312861791131776'
Watir doesn't know what to do with this (understandably, because that is a nonsensical key/value pair), so it throws an error telling you that you gave it something it didn't expect.
I would give you advice about exactly how to define it correctly, but you didn't include any of the HTML for the page containing this div and text field.
Does
#browser.div(:class => /controls/).text_field(:id, "13796781312861791131776").clear
work?
Sorry, I couldn't include the topics_text_field part since you didn't include that in the html.
I used set to insert a value in a text field under a div.
Below is the approach that I've used without success. This is the only way I was able to identify the element. When I tried to identify text field by name was not recognized.
#browser.div(:evaluation, :id => "evaluation_form_attributes").text_field(:id => "evaluation_form_name")
#browser.set('Teacher Evaluation Form')
The following error was displayed:
undefined method `set' for #<Watir::IE:0x4dd9348>
This is the HTML:
div id="evaluation_form_attributes"
Evaluation name:
input id="evaluation_form_name" type="text" size="50" name="evaluation_form[name]" maxlength="30"
Try this:
browser.text_field(:id => "evaluation_form_name").set 'Teacher Evaluation Form'
Is there an iframe involved perhaps? if you know the thing is there, and you are sure of the ID, and watir cannot locate it, then usually it's because that part of the page is inside of a frame.
To work with elements that are inside of a frame, you must specify the frame, then the element
browser.frame(:how, what).element(:how, what).method etc.
see http://wiki.openqa.org/display/WTR/Frames for more info
To set a value for a text field you simply need to find it and set it. The setting part you already know (set), so you need to string together something that finds the text field.
if Zejiko's answer doesn't work because of "unable to locate element" then it's not the setting that's failing, it's finding the text field. Use Firebug (in Firefox) or some kind of DOM toolkit (Tools>Developer Tools or F12 in IE8) to find the text field and see what kind of attributes it has.
Ensure the id is really "evaluation_form_name". This is case sensitive and sensitive to leading/trailing spaces. You could try the following to make your search broader:
#browser.text_field(:id => /evaluation/).set 'Teacher Evaluation Form'
This uses a regular expression to identify the id. You can search by many things, not just :id, and you can use more than one. For example:
#browser.text_field(:id => /eval/, :index => 2)
finds the second text field whose id contains "eval".
What you can use to identify the text field can be found here: https://github.com/watir/watir/wiki/HTML-Elements-Supported-by-Watir
I am new to Watir automation testing and would like to get some help for the drop down.On our website we have a state drop down where you enter the first letter of the state (in my example C for California) and it narrows it down to the all states starting with C. Once you have the list you need to click on the correct state. But I am having difficulties selecting the correct state.
(Below is the html from our website:
<div class="x-form-field-wrap x-trigger-wrap-focus" id="ext-gen202" style="width: 166px;">
<input type="hidden" id="entityStateCode" name="entityStateCode" value="">
<input type="text" id="ext-comp-1005" autocomplete="off" size="24" class=" x-form-text x-form-field x-form-focus">
I used the following to automate the scenario but none of these are giving me what i am looking for:
#browser.text_field(:id,"ext-comp-1005").value=("CA")
#browser.text_field(:id,"ext-comp-1005").set("CA")
#browser.text_field(:id=> "ext-comp-1055",:index => 5).set "CA"
I really appreciate that if you can point me to the right direction.
Thanks
I ran into a similar situation before. In my situation there was a TABLE inside the DIV which had a separate row for each item in the dynamic drop down. So, if that's the case for you then you would need to use something like this to access the items:
#browser.text_field(:id,"ext-comp-1055").set "C"
table = #browser.div(:id, "ext-gen336").table(:index, 1)
puts "First entry value: #{table[1][1].text}"
table[2][1].click # second entry
Try printing out the HTML for the DIV at runtime to see the specifics of what you need to interact with if that doesn't work.
You did not tell what the problem is, this is not enough:
none of these are giving me what i am
looking for
This should enter CA into text field:
browser.text_field(:id => "ext-comp-1005").set("CA")
If it is entering text into wrong text field, change :id => "ext-comp-1005".
If it is entering text into the correct text field, but list of states does not appear, you probably have to fire some javascript event. Take a look at How to find out which JavaScript events fired? question.