Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find specific html elements, AngularJS, protractor

I'm new to AngularJS/protractor so any guidance on this is much appreciated. Since Angular JS instantiates html elements via ng- directives there are no 'id's etc that allow me to locate specific elements. (Obviously I want to do this to validate content, click them etc.) My angular js snippet looks like:

<div ng-repeat="item in myList">
    <span ng-if="item.category == 'lights'">
        <img src="../../../{{item.icon}}"/>
        &nbsp<span id="foo">{{item.name}}</span>&nbsp
    </span>
</div>

I'm trying to locate the elements {{item.name}} as I iterate over the list with this:

element.all(by.repeater('item in myList')).then(function(rows) {
    noOfItems = rows.length;
    for (i = 0; i < noOfItems; i++) {
        row = element.all(by.repeater('item in myList')).get(i);
        row.isElementPresent(By.id('foo')).then(function (isP) {
            if (isP) {
                console.log("foo exists?" + isP);
                row.findElement(By.id('foo')).then(function (el) {
                    el.getText(txt).then(function (txt) {
                        console.log("Item name  " + txt);
                    });
                });
            }
        });
    }
});

From inspection the 'row' element seems to be selenium object so I invoke 'isElementPresent(...) and this works great. It detects the correct number of 'foo' elements. However when row.findElement(...) runs, the test spec terminates prematurely. (No errors, it just ends)

I know that there will be multiple 'foo' elements in the document however I was hoping that since they are being queried within a sub html element, (row) this might work.

Any suggestions/workarounds?

like image 420
user2600346 Avatar asked Apr 23 '14 17:04

user2600346


1 Answers

By the way another approach to finding the right Angular generated elements is to use the by.js locator. This is not a Protractor specific locator but one provided by the underlying WebDriverJS so you have to look there for the docs.

Essentially by.js lets you provide a javascript function that will be run on the browser to find the element you are looking for. The javascript in turn can interrogate DOM elements to find and inspect the Angular $scopes that have been attached to them and thereby find elements that have specific scope values. For example, you can thereby find an element associated with an actual recordId which is present in the scope but was never rendered into HTML. This is very useful because, given how angular works, you rarely need to render these sorts of ids into HTML, but tests still need to be able to find the elements that represent them!

like image 132
Kenneth Baltrinic Avatar answered Nov 14 '22 18:11

Kenneth Baltrinic