TypeSource
TypeSource

Reputation: 63

Protractor Looping Not Able to Click Correct Item

Looping through and trying to print out to the console my choice and clicking is not working properly. Each of my list items have text and the list item itself is clickable. I'm trying to iterate through the list to match text (choice_item), if it matches it prints to console and clicks that item.

But when I check my output, it clicks the next item after it. For example, it will print:

Item 1

Item 2

choice found: Item 2

Item 3

And then clicks Item 3 instead of Item 2 (The choice_item that I want to find in the list). Any explanation on how to fix this and/or control flow mistakes I am making will be greatly appreciated!

this.getListItems = function(choice_item){
    var choice = "";
    this.getSelectionsList().filter(function(elem, index) {
        return elem.element(by.css('.choicename')).getText().then(function(text) {
            if(text === choice_item){
                console.log("choice found:"+ choice_item);
                choice = text;
                elem.click();
                return true;
            }
        });
    }).then(function(items) {
        expect(choice).toBe(choice_item);
    });
};

Upvotes: 1

Views: 52

Answers (2)

alecxe
alecxe

Reputation: 473833

Filter the element by the choice_item text and click it:

this.getListItems = function(choice_item) {
    var listItems = this.getSelectionsList().filter(function(elem) {
        return elem.element(by.css('.choicename')).getText().then(function(text) {
            return text === choice_item;
        });
    });

    listItems.first().click();
};

Note that there is no need to expect() here since you are already applying the choice_item check while filtering the list item.

Upvotes: 2

ktom
ktom

Reputation: 228

I think it is a control flow mistake. Try this way:

this.getListItems = function(choice_item){
    var choice = "";
    this.getSelectionsList().filter(function(elem, index) {
        return elem.element(by.css('.choicename')).getText(); //it returns promise

    }).then(function(text) {
        //getText() Promise fulfill
        if(text === choice_item){
            console.log("choice found:"+ choice_item);
            choice = text;
            elem.click();
            browser.sleep(2000);
            expect(choice).toBe(choice_item);
        }

    });
};

The best way for click methods. Do factory function, for example:

var click1 = function (element){
    element.click();
    return new Promise (function (fulfill, reject){
      setTimeout(function(){
      fulfill();
      },2000);
    }    
});

And You can use this:

click1(elem).then(function (){
 //the code
});

But in your code the click() event influence nothing, because the getText() is earlier than click().

Upvotes: 1

Related Questions