Watir-Webriver - Automating autocompletion field - autocomplete

Using Watir-webdriver I am trying to input an answer to a question that autocompletes as you type from a selection, I have searched all over the place for an answer but to no avail.
heres the snippet of code that i am trying to get some form of a id from so i can just inject into it ;)
<input type="text" data-bind="source: MultiOptionsList,events:{select:AutoSelect},value: AutocomplateText" data-text-field="Value" data-role="autocomplete" class="form-input k-input" style="width: 100%;" autocomplete="off" role="textbox" aria-haspopup="true" aria-disabled="false" aria-readonly="false" aria-autocomplete="list" aria-owns="" aria-busy="false">
Hope this makes sense, looking for something along the lines of "#browser.(:id => "blah").set "#{arg}""
Thanks Guys!

Given that this is the only autocomplete control on the page and the text field does not have any descriptive attributes, you could locate the element by its data-role attribute:
browser.text_field(:data_role => 'autocomplete').set('some text')

Related

How to locale angular element using by.model in protractor

I have this text box element.
<input type="text" name="textbox" class="box-input ng-pristine ng-scope md-input ng-empty ng-valid ng-valid-required ng-touched" ng-required="field.required" ng-model="$ctrl.model[field.nameField.uuid]" ng-disabled="::field.readOnly" id="input_15" aria-invalid="false" style="">
In protractor how should I use it to locate the element? I am not quite sure how to use ng-model="$ctrl.model[field.nameField.uuid]"
If you are using angular 2 or above by model might not work for you, see here.
You could still use the model attribute to identify your element through css like so
$('[ng-model="$ctrl.model[field.nameField.uuid]"]')
or
element(by.css('[ng-model="$ctrl.model[field.nameField.uuid]"]'))
try like this
let input = element(by.model('$ctrl.model[field.nameField.uuid]'));
I suggest to use unique ID if its possible, or some unique class styles leading to single element.

how to find the span in protractor

i want to turn on the toggle button in protractor. below is the DOM
<input type="checkbox" id="UseRecipientList" ng-model="newProduct.useRecipientList" class="ng-pristine ng-untouched ng-valid">
<span>
::before
::after
</span>
if I identify the element by xpath, it is working fine. i have used, element(by.xpath("//input[#id='UseRecipientList']/following-sibling::span"));
if I want to go by ng-model, how to identify the span which comes after ng-model as above in protractor?
Use css as below
const locator= element(by.css('input#UseRecipientList > span'));
So the above locator help you to get the span as below
locator.getText();
To inspect using model name.Try the below one.
var input = element(by.model('newProduct.useRecipientList'));
For more on ng-model refer https://www.protractortest.org/#/api?view=ProtractorBy.prototype.model
Hope it helps you!!
Try with css locator
(by.css('[ng-model="newProduct.useRecipientList"] span'));

Is it possible to find elements that do not follow the locator?

Current situation that is repeated several times:
<div ng-repeat="r in ids">
<span> DESIRED TEXT </span>
<div ng-repeat="c in ids">
<span> ng-bind-html="" UNDESIRED TEXT</span>
</div>
</div>
I tried using: element.all(by.repeater('r in ids')).all(by.tagName('span')).getText()
The problem is that this includes the second span as well. I would greatly prefer not to use xpath in the answer. So is there a way to specify only the first of each <span>, or to filter by not having ng-bind-html, etc?
Thanks!
Found a solution:
element.all(by.repeater('r in ids')).each(function (theElement, index) {
theElement.all(by.tagName('span')).first().getText().then(function (text){
console.log(text);
});
});
You can also use css selector to find the same:
element.all(by.css("div[ng-repeat='r in ids'] span")).getText();
Hope this helps.

Bootstrap validator form plugin: how to change feedback icons

The bootstrap validator plugin helps validating the form fields providing a bunch of cool features. One of those features are the feedback icons, which defaults to glyphicon.
Suppose I want to replace glyphicon with font awesome.
The documentation says they can be changed by passing a "feedback" JSON object as data attribute or via JavaScript.
Via JavaScript it's easy. But as data attribute, it is unclear where and how exactly add it, because simply adding:
feedback: {
success: 'fa-check',
error: 'fa-times'
}
as data attribute to the <form> or the <div class="form-group"> or the <input> itself it doesn't work.
After some time struggling with it, I realized that the JSON feedback object should be added to the element and also it needs to be added using this syntax (which was not specified in the docs):
<form ... data-feedback='{"success": "fa-check", "error": "fa-times"}'>
Note the quotes syntax.
Also, if we are not just changing the glyphicon but replacing it with a font-awesome one (like in my example), in the <div class="form-group"> we need to replace:
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
with:
<span class="fa form-control-feedback" aria-hidden="true"></span>
This is not very well documented, and I could not make it work. I ended up using a different form validator which accomplish the same functionality and it's easier to configure success/error formats using bootstrap classes:
var validator = $('#submitForm').validate({
validClass: "is-valid",
errorClass: "is-invalid",
jQuery Validator

Change class of div based on a field's validation result

I want to wrap fields in a <div class="validation-error"> when they have validation errors, and in plain <div>s otherwise:
Validation Error:
<div class="validation-error">
<sf:input path="title" cssErrorClass="validation-error"/>
<sf:errors path="title" cssErrorClass="validation-error" />
</div>
No Validation Error:
<div>
<sf:input path="title" cssErrorClass="validation-error"/>
<sf:errors path="title" cssErrorClass="validation-error" />
</div>
How can I check that title has an error or not?
You shouldn't apply validation-error class to whole <div> element of your input. I don't think that <errors> tag was meant to work like that.
What you could do is very simple and neat solution. Simply display error message with all proper classes and styles applied to it or don't display it at all. For instance:
<tr>
<td><label>Username</label></td>
<td><form:input id="username" path="nickname" /></td>
<td><span id="usernameError" class="error"><form:errors path="nickname" /></span></td>
</tr>
When there is no error message, appropriate cell will be left blank and user won't see anything. However, if the message will be displayed - it will have proper styling thanks to class="error" notation in mine example.
Ohh, and you can use divs, spans or any other elements if you wish. I just tend to use table for forms.