Nacho
Nacho

Reputation: 33

Protractor - looping through table to select option from listbox

I'm trying to loop through a table, using Protractor, to see if a row contains a select element. Then select 1 of two particular options. Thus far the test 'passes' but nothing is actually being selected. My latest attempts are below.

it('should loop through table and select an option if listbox is available', 
function () {
    var table= element(by.xpath("//table[@id='tableID']"));
    var count = table.length;
    var currentType = "";

    for (var i = 1; i <= count; i++) {
        tableSelect(i);
    }

    function tableSelect(i) {
        it('should loop through this table and associate', function () {
            expect(table.isDisplayed()).toBe(true);

            if (element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]")).isDisplayed()) {

                if (element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]//select[matches(@ng-change,'listChange()')]")).isDisplayed()) {

                    var varOne = element(by.xpath("//table[@id='tableID']/" + 
                         "tbody/tr[" + i + "]/td[4]/div/span/span")).getText();

                    if (currentType != "Moretext" || varOne.Length < 6) {
                        element(by.xpath("//table[@id='tableID']/tbody/tr[" + i +
                                         "]/td[6]/div/span/div/select")).
                            element(by.cssContainingText('option', 
                                    'This is option A')).click();
                    }
                    else {
                        element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[6]/div/span/div/select")).element(by.cssContainingText('option', 'This is option B')).click();
                    }
                }
                else if (element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[1]/div/span/span")).isDisplayed()) {
                    currentType = element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[1]/div/span/span")).getText();

                }
            }
        });
    }

    var saveBtn = elem(by.id('saveButton'));
    expect(associateBtn.isDisplayed()).toBe(true);
    expect(associateBtn.isEnabled()).toBe(true);
    saveBtn.click();
});

This is attempt #2:

element.all(by.repeater('row in datarows')).then(function(rows) {
    for (var i = 1; i <= rows.length; ++i) {
        if (element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]//select[matches(@ng-change,'listChange()')]")).isDisplayed()) {

            var varOne = element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[4]/div/span/span")).getText();

            if (currentType != "MoreText" && varOne.Length < 6) {
                element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[6]/div/span/div/select")).element(by.cssContainingText('option', 'This is option A')).click();
            }
            else {
                element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[6]/div/span/div/select")).element(by.cssContainingText('option', 'This is option B')).click();
            }
        }
        else if (element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[1]/div/span/span")).isDisplayed()) {
            currentType = element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[1]/div/span/span")).getText();
        }
    }
});

This is the latest attempt:

var varOne = "";
var varTwo = "";

element.all(by.xpath("//table[@id='tableID']/tbody/tr")).then(function (rows) {
    for (var i = 1; i < (rows.length); i++) {

        console.log('rowcount = ' + i);

        element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]")).isDisplayed().then(function (visible) {
            if (visible) {
                element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]//select[@ng-change='listChange()']")).isDisplayed().then(function (visible) {
                    if (visible) {
                        element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[4]/div/span/span")).getText().then(function (monthText) {
                            varTwo = monthText;

                            console.log(varTwo);
                        });

                        if (varOne != "Revolving" || varTwo.length < 6) {
                            element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[6]/div/span/div/select")).element(by.cssContainingText('option', 'Exclude: Duplicate Account')).click();
                        }
                        else {
                            element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[6]/div/span/div/select")).element(by.cssContainingText('option', 'Include in Ratios')).click();
                        }
                    }
                    else {
                        element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[1]/div/span/span")).isDisplayed().then(function (visible) {
                            if (visible) {
                                element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[1]/div/span/span")).getText().then(function (currText) {
                                    varOne = currText;
                                    console.log(varOne);
                                });
                            }
                        });
                    }
                });
            }
        });
    }
});

Upvotes: 2

Views: 4346

Answers (3)

Abubaker Siddiq
Abubaker Siddiq

Reputation: 29

//below code working for me to traverse to the particular rows and cells in the table

async colRowIterate() {
    this.rowsTblValue.each(async (rowsValues: any) => {
        let cells = rowsValues.$$('td');
        cells.get(0).getText().then(async (cellvalues: any) => {
            await browser.sleep(10000);
            if (cellvalues == 'Harry') {
                cells.get(4).$('button').click();
            }

        });
    });

Upvotes: 0

Nacho
Nacho

Reputation: 33

here's what I used to finally get it to work. I put a call to a function inside of a for loop, and inside of the function is the code that does the heavy lifting.

it('should loop through table and select an option from each listbox available', function() {
    var varOne = "";
    var varTwo = "";

    element.all(by.xpath("//table[@id='tableID']/tbody/tr")).then(function (rows) {
        for (var i = 1; i < (rows.length); i++) {
            console.log('count = ' + i);
            selectWithinTable(i);
        }

        function selectWithinTable(i) {
            element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]")).isDisplayed().then(function(visible) {
                if (visible) {
                    element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]//select[@ng-change='listChange()']")).isDisplayed().then(function(visible) {
                        if (visible) {
                            element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[4]/div/span/span")).getText().then(function(someText) {
                                varTwo = someText;
                                console.log(varTwo);
                                console.log(varTwo.length);
                            });

                            if (varOne != "Revolving" || varTwo === "") {
                                element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[6]/div/span/div/select")).element(by.cssContainingText('option', 'This is option A')).click();
                            }
                            else {
                                element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[6]/div/span/div/select")).element(by.cssContainingText('option', 'This is option B')).click();
                            }
                        }
                        else {
                            element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[1]/div/span/span")).isDisplayed().then(function(visible) {
                                if (visible) {
                                    element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]/td[1]/div/span/span")).getText().then(function (moreText) {
                                        varOne = moreText;
                                        console.log(varOne);
                                    });
                                }
                            });
                        }
                    });
                }
            });
        }
    });

    element(by.id('buttonID')).isDisplayed().then(function(visible) {
        if(visible) {
            element(by.id('buttonID')).isEnabled().then(function(enabled) {
                if (enabled) {
                    element(by.id('buttonID')).click();
                }
            });
        }
    });
});

Upvotes: 0

Leo Gallucci
Leo Gallucci

Reputation: 16722

Code like

if (element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]")).isDisplayed()) {

Won't work because that always evaluate to true since the promise Object is truthy per Javascript booleans.

You need to follow the promise:

var elm = element(by.xpath("//table[@id='tableID']/tbody/tr[" + i + "]"));
elm.isDisplayed().then(function(visible) {
  if (visible) {
    // logic here
  }
});

Assuming the element is Present, if not present then isDisplayed will fail at webdriver level, so you may test for isPresent instead of isDisplayed

Upvotes: 2

Related Questions