Search code examples
protractorangularjs-e2e

Using Protractor to select elements with by.repeater()


Using the following Protractor element and by.repeater() API methods below:

var targetRowText = 'Sales';
var targetGridName = 'myGrid';
var sel = 'grid-directive[grid-name="' + targetGridName + '"] .col-freeze .grid-wrapper';
var gridRows = element(by.css(sel).all(by.repeater('row in vm.sourceData.data'));
var result = gridRows.all(by.cssContainingText('span', targetRowText)).first();

I am able to select the following row element from a grid which I have labeled, myGrid:

<div id="rowId_21" ng-class-odd="'row-2'" ng-class-even="'row-3'" ng-class="vm.hideRow(row)" class="row-3 height-auto">
 <div ng-repeat="column in  vm.sourceData.columns" >
     <div ng-if="!column.subCols" class="ng-scope">	
 	<div ng-if="row[column.field].length !== 0" class="ng-scope highlight21">	
 	    <span ng-bind-html="row[column.field] | changeNegToPrenFormat" vm.highlightedrow="" class="ng-binding"> 
                Sales
            </span>
 	</div>
     </div>    
 </div>
</div>

Please note that I have used by.cssContainingText() to look up the "Sales" span element.

MY PROBLEM:

That that I have located this row in var result, how can I retrieve the id attribute of that outer-most div ?

In other words, I need to selected <div id="rowId_21" so that I can reuse id="rowId_21" in a subsequent Protractor selector.

In jQuery, for example, I could use brute force to get that outer div id as follows :

var el = $('grid-directive[grid-name="Sales"] .col-freeze .grid-wrapper #rowId_21 span')
el.parentElement.parentElement.parentElement.parentElement;

Here's a high-level outlines of what I mean. The grid actually separates the left-most column from the actual data rows, so there are two distinct divs that accomplish this:

<div grid-directive grid-name="myGrid">
 <div class="col-freeze" >
    <!-- CONTAINS LEFT-MOST "CATEGORIES" COLUMN -->
 </div>
 <div class="min-width-grid-wrapper"> 
    <!-- CONTAINS THE DATA ROWS-->
 </div>

However, I'm struggling to do this in Protractor.

Advice is appreciated...

Bob


Solution

  • A straight-forward option would be to get to the desired parent element using the ancestor axis:

    element(by.xpath("./ancestor::div[starts-with(@id, 'rowId')]")).getAttribute("id").then(function (parentId) {
        // use parentId here
    });
    

    Though, I think that this going down and then up the tree should be considered as a sign that you are not approaching the problem in an easy and correct way.