3

In my UI, I have a project tree that contains a list of components that are in a project. Once my current spec is done running I'm calling a page object function to delete all the components to clean up the workspace before moving on to the next spec. I'd say about 50% of the time I'm noticing a stale element reference error on the line with my .filter() function. I added some log statements to see if I could figure out what's happening and noticed some behavior I didn't understand. It seems like for every component in my list, the filter function is running four times. Anyone know if this is expected behavior?

This is my delete function:

public async deleteAllComponents(): Promise<void> {
    await this.componentsTab.click();

    // get list of all current components
    const components = element.all(this.projectComponentsLocator);
    const componentNames = await components.getText();

    // delete each component
    for (const name of componentNames) {
        await this.deleteComponentFromProjTree(name);
    }
}

This is the function that is throwing the stale element reference error:

public async deleteComponentFromProjTree(componentName: string): Promise<void> {
    await this.componentsTab.click();
    // get new list each time because list goes stale after a component is deleted
    const components = element.all(this.projectComponentsLocator);        

    log('components found:', await components.count());
    log('deleting component:', componentName);

    const relevantComponent = await components.filter((component: ElementFinder) => {
        return component.getText().then((text: string) => {
            log('current component:', text);
            log('relevant component found:', text.includes(componentName));
            return text.includes(componentName);
        });
    })
    .first();

    await relevantComponent.click();

    const componentMenu = relevantComponent.$(this.componentMenuLocator);
    await componentMenu.click();

    if (await this.deleteOption.isPresent()) {
        await this.deleteOption.click();
        await this.confirmDeleteBtn.click();
    } else {
        // component cannot be deleted so just exit menu
        browser.actions().sendKeys(protractor.Key.ESCAPE).perform();
    }
};

When I turn on the debug logging here is what I see in the console. Why does it seem like each component is running through the filter function 4 times? When there were 2 components found the function ran 8 times, when there was only 1 it still ran 4 times. What's this all about?

enter image description here

1 Answer 1

1

First of all, I don't think that your usage of getting text is correct.We need to get the text individually from each element, something like this:

element.all(by.css('something')).map(function(elm) {
 return elm.getText();
 }).then(function(texts) { 
texts.forEach(...); 
});
1
  • Thanks for the suggestion but I've already found a workaround. The problem was that there was too many elements in the list and protractor was having issues looping over them all. I found a different way to make it work with a smaller list of elements. Oct 15, 2018 at 18:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.