Lia
Lia

Reputation: 11982

promise keep working when i resolve it and change page (protractor test)

i have a table rows and i want to click on edit button in a row with specific label(test server label), a row that i want to click it

this is my code :

public selectOnRow( textSelector:string , clickableSelector : string , value:string) {
    let promise = new Promise(resolve => {
        element.all(by.css(textSelector)).each((elem, i) => {
            elem.getText().then(function (text) {
                if (text === value) {
                    resolve(i);
                }
            });
        });
    });
    promise.then(i => {
        element.all(by.css(clickableSelector)).get(i).click();

    })
}

and i call it like this:

beforeAll(async () => {
            page = new AppPage;
            page.navigateTo('/asset/server');
            page.selectOnRow('.column-label div', '.edit-action-btn', 'test server label')
            baseUrl = page.baseUrl;
        });

the problem is it clicks on a correct row but when page is changed still selectOnRow is working and looping on rows those are not in new page! i get this error:

Failed: stale element reference: element is not attached to the page document

Upvotes: 3

Views: 228

Answers (1)

craig
craig

Reputation: 5016

ElementFinderArray filter function

This might be a good use of the filter function for element.all. When we call the filter function, elements that return truthy with a boolean or promise to a boolean get added to the ElementFinderArray. The ElementFinderArray is also the same type of object that element.all will return.

Clicking on one of the elements

When the text matches, we set a variable index when the text matches. Only set the index value if the index is empty. Next we will wait for the filter function to complete. We then click on the clickableSelector with the index value.

Awaiting async methods

Last thing to do is return the entire promise on selectOnRow. So you can call await selectOnRow(textSeector, clickableSelector, value);

Code snippet

public selectOnRow(textSelector:string, clickableSelector: string, value: string) {
    let index: number;
    return element.all(by.css(textSelector)).filter((elem, i) => {
      return elem.getText().then(text => {
        // test if index is not set
        // also, if the text matches, update the index
        if (!index && text === value) {
          index = i;
        }
        return text === value;
      });
    }).then(() => {
      // wait for the filter function to complete
      // at this point, the index should be set.
      return element.all(by.css(clickableSelector)).get(index).click();
    });
}

Upvotes: 3

Related Questions