最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to find specific html elements, AngularJS, protractor - Stack Overflow

programmeradmin1浏览0评论

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?

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?

Share Improve this question asked Apr 23, 2014 at 17:02 user2600346user2600346 811 silver badge3 bronze badges 1
  • strange, row.findElement(...) should throw an error, because it is an array and should not have the function findElement. row[0].findElement should work. "foo exists?" appears in console log? – nilsK Commented Apr 28, 2014 at 7:56
Add a ment  | 

3 Answers 3

Reset to default 1

Before addressing your specific question, a couple of things seem to be amiss here.

1) I don't think line 4 in the above is what you want to do. It is going to go back to the browser for every row, re-running the by.repeater query each time. All you really need to do is row = rows[i].

2) Better yet you could simply replace the first four lines with element.all(by.repeater('item in myList')).each(function(row){

As for the question of finding the foo span in context, you might try finding by.css(':scope #foo'). That should give you a search for id='foo' in the scope of the current element.

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!

var eleB = element(by.css('.ui-grid-render-container.ng-isolate-scope.ui-grid-render-container-body'));

eleB.element(by.repeater('(rowRenderIndex, row) in rowContainer.renderedRows track by $index').row(10)).$('.ui-grid-cell.ng-scope.ui-grid-coluiGrid-000B').getText().then(function(arr){
            console.log("-------------------\n" + arr);
});
发布评论

评论列表(0)

  1. 暂无评论