Reputation: 177
I am verifying the filter options in a page. Every time I select an option I submit the filters then the page refreshes with the new result. Again I click on the filter button and need to select next radio button. But I am getting stale element reference error.
filterButton.click().then(function () {
filteroptions.count().then(function (totalradios) {
console.log("before start" + totalradios);
filteroptions.each(function (radiooption, index) {
radiooption.getText() //getting error at this place on the second iteration
.then(function (radioName) {
console.log(radioName, index);
})
radiooption.click().then(() => {
filterSubmit.click().then(function () {
console.log(totalradios, ' ', index)
if (index <= totalradios) {
filterButton.click();
}
})
})
})
})
})
Updated from each(function) to For loop
var filteroptions = element.all(by.css("md-radio-group.ng-pristine.ng-untouched.ng-valid._md.layout-row.ng-not-empty md-radio-button"));
filterButton.click().then(function () {
filteroptions.count().then(function (totalradios, async) {
console.log("before start" + totalradios);
for (var i = 0; i < totalradios; i++) {
console.log("recalulated true " + totalradios);
(function (index) {
console.log("select filter option");
filteroptions.get(index).click();
console.log("click submit button");
filterSubmit.click();
console.log("click filter button");
filterButton.click();
console.log("get new totalcounts");
let setradios = filteroptions.count().then((value) => {
return value;
})
console.log("recalulated totalradios" + setradios);
totalradios = setradios;
})(i);
}
})
})
Tried to read the list in a separate function
var getfiltercount = function () {
filteroptions = element.all(by.css("md-radio-group.ng-pristine.ng-untouched.ng-valid._md.layout-row.ng-not-empty md-radio-button")); // filtertext
return filteroptions.count().then(function (addradios) {
console.log("addradios is " + addradios);
})
return addradios;
}
Upvotes: 0
Views: 360
Reputation: 13712
Because selenium will also treat below situation as entering new page:
Once selenium detect entering new page, the reference of elements found on previous page are invalid, if you still use them in script, selenium will report StaleReferenceException.
To resolve this problem is simple to find the element again on new page to get the new reference for later using.
// function to test when choose yes
radio button
function testYesRaidoButton() {
// click `yes` radio button
element(<locator of `yes` raido button>).click();
// find how many new radio buttons will appear after choose `yes`
element.all(<locator of sub radio buttons of `yes`>).count()
.then(function (totalradios) {
console.log("before start " + totalradios);
for(var i=0;i<totalradios;i++) {
(function(index) {
// click one of new radio button of `yes`
element.all(<locator of sub radio buttons of `yes`>).get(index).click();
// click `submit` button
element(<locator of filterSubmit>).click();
// click `yes` radio button on `new page` again
element(<locator of `yes` raido button>).click();
})(i);
}
});
}
// function to test when choose no
radio button
function testNoRadioButton() {
// click `no` radio button
element(<locator of `no` raido button>).click();
// find how many new radio buttons will appear after choose `no`
element.all(<locator of sub radio buttons of `yes`>).count()
.then(function (totalradios) {
console.log("before start " + totalradios);
for(var i=0;i<totalradios;i++) {
(function(index) {
// click one of new radio button of `no`
element.all(<locator of sub radio buttons of `no`>).get(index).click();
// click `submit` button
element(<locator of filterSubmit>).click();
// click `no` radio button on `new page` again
element(<locator of `no` raido button>).click();
})(i);
}
});
}
Actually, the two function has many similar code lines, you can optimize and merge into one function to accept different parameter value to archive same purpose.
Alternative solution to archive some goal by using two loop, but not recommend to do as that, because code is hard to read and understand, pretty not friendly.
// iterate `yes` and 'no'
for (var j = 0; j < 2; j++) {
(function(__index) {
element.all(<locator of `yes` and `no` radio button>).get(__index).click();
element.all(<locator of new radio buttons>).count()
.then(function(totalradios) {
console.log("before start " + totalradios);
// iterate new radio buttons
for (var i = 0; i < totalradios; i++) {
(function(index) {
// click one of new radio buttons
element.all(<locator of new radio buttons>).get(index).click();
// click `submit` button
element(<locator of filterSubmit> ).click();
// click `yes` or `no` radio button on `new page` again
element.all(<locator of `yes` and `no` radio button>).get(__index).click();
})(i);
}
});
})(j)
}
Upvotes: 1