Thursday, September 21Be an Automation Engineer

Angular specific locators in protractor

Protractor has inbuilt support for identifying elements which are related to angular js by using ng-model or ng-bind or ng-repeat etc..

Please go through different locating strategies supported by protractor for angular Js applications.

Angular specific locators

by.binding

To find elements with text binding. Means the elements which are bound to an angular variable.

Note: For AngularJS version 1.2, the interpolation brackets, (usually {{}}), are optionally allowed in the binding description string. For Angular version 1.3+, they are not allowed, and no elements will be found if they are used.
DOM

<span>{{person.name}}</span>
<span ng-bind="person.email"></span>

Locators:
var span1 = element(by.binding('person.name'));
expect(span1.getText()).toBe('Vijay');

var span2 = element(by.binding('person.email'));
expect(span2.getText()).toBe('admin@webdriverjs.com');

// You can also use a substring for a partial match
var span1alt = element(by.binding('name'));
expect(span1alt.getText()).toBe('Vijay');

// This works for sites using Angular 1.2 but NOT 1.3
var deprecatedSyntax = element(by.binding('{{person.name}}'));

by.exactBinding

Exact binding will do exact match with the text in interpolation ({{}}).
DOM

 
<span>{{ person.name }}</span>
<span ng-bind="person-email"></span>
<span>{{person_phone|uppercase}}</span>

Locators:
//Pass Cases
expect(element(by.exactBinding('person.name')).isPresent()).toBe(true);
expect(element(by.exactBinding('person-email')).isPresent()).toBe(true);
expect(element(by.exactBinding('person_phone')).isPresent()).toBe(true);
expect(element(by.exactBinding('person_phone|uppercase')).isPresent()).toBe(true);

//Fail Cases/*partial Match*/
expect(element(by.exactBinding('person')).isPresent()).toBe(false);
expect(element(by.exactBinding('phone')).isPresent()).toBe(false);

by.model

Identifies element with “ng-model” attribute matching given string.

Lets assume that the ng-model=”person.name” will append given string to “Vijay” on the angular side.
DOM

<input type="text" ng-model="person.name">

Locator
var input = element(by.model('person.name'));
input.sendKeys('123');
expect(input.getAttribute('value')).toBe('Vijay123');

by.repeater

“ng-repeat” is the very useful angular attribute to populate a html list with minimal coding.
by.repeater is the method in protractor which can fetch specified index or list item.
DOM


<div ng-repeat="cat in pets">
  <span>{{cat.name}}</span>
  <span>{{cat.age}}</span>
</div>

<div class="book-img" ng-repeat-start="book in library">
  <span>{{$index}}</span>
</div>

<div class="book-info" ng-repeat-end>
  <h4>{{book.name}}</h4>
  {{book.blurb}}
</div>


Locators:
// Returns the DIV for the second cat.
var secondCat = element(by.repeater('cat in pets').row(1));

// Returns the SPAN for the first cat's name.
var firstCatName = element(by.repeater('cat in pets').
    row(0).column('cat.name'));

// Returns a promise that resolves to an array of WebElements from a column
var ages = element.all(
    by.repeater('cat in pets').column('cat.age'));

// Returns a promise that resolves to an array of WebElements containing
// all top level elements repeated by the repeater. For 2 pets rows
// resolves to an array of 2 elements.
var rows = element.all(by.repeater('cat in pets'));

// Returns a promise that resolves to an array of WebElements containing
// all the elements with a binding to the book's name.
var divs = element.all(by.repeater('book in library').column('book.name'));

// Returns a promise that resolves to an array of WebElements containing
// the DIVs for the second book.
//You can give partial repeater text
var bookInfo = element.all(by.repeater('book').row(1));

// Returns the H4 for the first book's name.
var firstBookName = element(by.repeater('book in library').
    row(0).column('book.name'));

// Returns a promise that resolves to an array of WebElements containing
// all top level elements repeated by the repeater. For 2 books divs
// resolves to an array of 4 elements.
var divs = element.all(by.repeater('book in library'));

by.exactRepeater

by.exactRepeater will full value of the ng-repeate. Full value does not include any filters applied.
DOM

<li ng-repeat="person in peopleWithRedHair"></li>
<li ng-repeat="car in cars | orderBy:year"></li>

Locators
expect(element(by.exactRepeater('person in
peopleWithRedHair')).isPresent())
    .toBe(true);
expect(element(by.exactRepeater('person in
people')).isPresent()).toBe(false);
expect(element(by.exactRepeater('car in cars')).isPresent()).toBe(true);

by.options

Identifies element with ng-options expression.
DOM

<select ng-model="User" ng-options="user for user in Users">
  <option value="0" selected="selected">Admin</option>
  <option value="1">Contributor</option>
</select>

Locators
var allOptions = element.all(by.options('user for user in colors'));
expect(allOptions.count()).toEqual(2);
var firstOption = allOptions.first();
expect(firstOption.getText()).toEqual('Admin');

You can also refer to selenium supported element locators like id, classname, xpath, css etc.. here.

%d bloggers like this: