1

Scenario 1) Stale Element Reference error

it("should have all elements", function (done) {
    var def = protractor.promise.defer();
    var prm = browser.findElements(by.css("jive")).then((elements) => {           
        elements.forEach((ele) => {
            var id = ele.getId();
            var loc = ele.getLocation();
            var inner = ele.getInnerHtml();
            var text = ele.getText();
            var tag = ele.getTagName();
        }); 
        def.then((wtf) => {
            debugger;
        });      
    });      
    done();
});

I thought that the code above would have a ton of promises on the queue after running through the iteration on all elements. But when the def.then statement runs Selenium is telling me I have Stale Elements. The iteration is running through the elements for that css.

I was hoping to get an array of resolved promises for everything the iteration requested...

Scenario 2) Gives Stale Element Reference

var promises = Array<webdriver.promise.Promise<any>>();
var allElements: webdriver.IWebElement[] = [];
it("should have all elements", function (done) {
    var alllinks: webdriver.WebElement[];
    browser.controlFlow().execute(() => {
        browser.findElements(by.tagName("a")).then((works) => {
            alllinks = works;
            alllinks.forEach((ele) => {
                promises.push(ele.getAttribute("href"));
                promises.push(ele.getId());
                promises.push(ele.getInnerHtml());
                promises.push(ele.getLocation());
            });
            //getting stale reference here...
            protractor.promise.all(promises).then((wtf) => {
                debugger;
            });

            debugger;
        });
    });

Please advise.

Community
  • 1
  • 1
JWP
  • 6,318
  • 3
  • 45
  • 70

2 Answers2

0

I think you need the map():

var links = element.all(by.tagName("a")).map(function (link) {
    return {
        href: link.getAttribute("href"),
        id: link.getId(),
        innerHTML: link.getInnerHtml(),
        location: link.getLocation()
    }
});

Now the links would contain a promise resolving into an array of objects.

alecxe
  • 441,113
  • 110
  • 1,021
  • 1,148
-1

My tiny example might be helpful for you:

viewBookingDetailsPage.roomtypeAttributeForParticularDay = function (day, roomTypeNumber, selector) {
    var deferred = protractor.promise.defer();
    element.all(by.repeater(viewBookingDetailsPage.guestroomInfo.allDays)).then(function (days) {
        days[day].all(by.repeater(viewBookingDetailsPage.guestroomInfo.roomTypesInDay)).then(function (roomTypes) {
            deferred.fulfill(roomTypes[roomTypeNumber].$(selector));
        });
    });
    return deferred.promise;
};

You need to use fulFill to return result after promise will be successfully resolved.

Sergey Teplyakov
  • 603
  • 7
  • 18