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,672
  • 3
  • 50
  • 74

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
  • 462,703
  • 120
  • 1,088
  • 1,195
-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
  • 8
  • 18