I appreciate this has been asked many times before, but when you feel like you have tried every solution ever posted on stack overflow, then its time to ask a question...
I am receiving a StaleElementReferenceException
whilst looping over a table and clicking the links within the particular row. For the first time round it works fine, its just when the first iteration has finished it bugs out. I completely understand what this error is trying to say to me, I just do not know how to fix it :/
The table in question is below:
With it's corresponding HTML source:
<table CLASS="datadisplaytable" SUMMARY="This table displays the components of the course." WIDTH = "100%"><caption >Components</caption>
<tr>
<td CLASS="ntheader" scope="col" >Description</td>
<td CLASS="ntheader" scope="col" >Weight </td>
<td CLASS="ntheader" scope="col" >Grade<br />Scale</td>
<td CLASS="ntheader" scope="col" >Must<br />Pass</td>
<td CLASS="ntheader" scope="col" style="display:NONE;" >Include in<br />Midterm or Final</td>
<td CLASS="ntheader" scope="col" >Incomplete<br />Scores</td>
<td CLASS="ntheader" scope="col" >Subcomponents</td>
</tr>
<tr>
<td CLASS="ntdefault">COURSEWORK - <a href="/pls/ubano1/BYLKEGRB.P_FacDispShrmrks?term=202210&crn=50493&gcom_id=322913">Portfolio of clinical learning - 2000 words</a></td>
<td CLASS="ntdefault">70/100</td>
<td CLASS="ntdefault">0-100 PG</td>
<td CLASS="ntdefault"><SPAN >Yes</SPAN></td>
<td CLASS="ntdefault" style="display:NONE;" >F</td>
<td CLASS="ntdefault">12</td>
<TD CLASS="ntdefault">
None
</TD>
<tr>
<td CLASS="ntdefault">PRACTICAL - <a href="/pls/ubano1/BYLKEGRB.P_FacDispShrmrks?term=202210&crn=50493&gcom_id=322914">Online Objective Structured Clinical Examination (OSCE) - 1 hour</a></td>
<td CLASS="ntdefault">30/100</td>
<td CLASS="ntdefault">0-100 PG</td>
<td CLASS="ntdefault"><SPAN >Yes</SPAN></td>
<td CLASS="ntdefault" style="display:NONE;" >F</td>
<td CLASS="ntdefault">13</td>
<TD CLASS="ntdefault">
None
</TD>
</tr>
</table>
<br />
<table CLASS="plaintable" SUMMARY="This table displays the links for composite information if applicable.">
<tr>
<td CLASS="pldefault"><a href="/pls/ubano1/BYLKEGRB.P_FacDispShrcmrk?term=202210&crn=50493&rectype_ind=F">View Final Composite Grades</a></td>
</table>
The code in question is below:
** Edit **
IWebElement dataDisplayTable = driver.FindElement(By.XPath("/html/body/div[4]/table[2]"));
List<IWebElement> dataDisplayTableRows = dataDisplayTable.FindElements(By.TagName("tr")).ToList();
foreach (IWebElement row in dataDisplayTableRows.Skip(1)) {
// Works first time round but then erros on 2nd iteration of loop
IWebElement assessmentTypeLink = row.FindElement(By.TagName("a"));
assessmentTypeLink.Click();
List<IWebElement> studentComponentListView =
GradebookCommon.getStudentComponentListView(row, driver);
foreach (IWebElement tr in studentComponentListView.Skip(2))
{
List<IWebElement> tableDataList = tr.FindElements(By.TagName("td")).ToList();
String studentId = tableDataList.ElementAt(1).Text;
if (Common.studentIdsMatch(studentIdToMatch, tableDataList, studentId))
{
driver.Manage().Window.Maximize();
IWebElement scoreColumnDiv = tableDataList.ElementAt(4);
IWebElement scoreColumnTextField = scoreColumnDiv.FindElement(By.TagName("input"));
scoreColumnTextField.SendKeys("60");
IWebElement submitBtn = driver.FindElement(By.XPath("/html/body/div[4]/form/input[8]"));
submitBtn.Click();
IWebElement selectComponentButton = driver.FindElement(By.LinkText("Select Component"));
selectComponentButton.Click();
break;
}
}
}
The line of code which is causing this issue is:
IWebElement assessmentTypeLink = row.FindElement(By.TagName("a"));
I have tried several other solutions, with each one giving me no luck. Some of these solutions are as follows:
The solution below just loops around x number of times and then fails.
public static bool clickAssessmentLink(By by, IWebDriver driver)
{
bool result = false;
int attempts = 0;
while (attempts == 0)
{
try
{
driver.FindElement(by).Click();
result = true;
break;
}
catch (StaleElementReferenceException e)
{
Console.WriteLine("Caught exception.. Retrying.");
}
attempts ;
}
return result;
}
I have also tried the following (Creating a copy of the WebElement): From here: StaleReference
WebElement link = driver.findElement(By.TagName("a"));
link.click();
WebElement link1 = driver.findElement(By.TagName("a"));
link1.click();
I have also tried the WebDriverWait
solution from Here
public static void WaitAndClick(this IWebDriver driver, IWebElement webelement)
{
WebDriverWait fluentWait = new WebDriverWait(driver,TimeSpan.fromSeconds(20));
//No need to set PollingInterval, default is already 500ms
fluentWait.IgnoreExceptionTypes(typeof(NoSuchElementException));
fluentWait.Until(ExpectedConditions.ElementToBeClickable(webelement));
webelement.Click();
}
Which ever solution I turn to, I get no further. Has anyone else ever experienced something like this before? I must have spent 15-16 hours trying to figure this one out!
Thanks in advance, and any more information, please let me know.
Thanks!
CodePudding user response:
I have resolved this in the following ways. Whether this is best practice or not, I'm not too sure, but this is honestly the only solution that has worked for me. I have tried everything else with no luck.
List<IWebElement> aHrefs = driver.FindElements(By.XPath("/html/body/div[4]/table[2]//a")).ToList();
List<String> links = new List<String>();
aHrefs.ForEach(link => { links.Add(link.GetAttribute("href")); });
foreach (String link in links) {
driver.Url = link;
Thread.Sleep(3000);
List<IWebElement> studentComponentListView = GradebookCommon.getStudentComponentListView(driver);
A basic explanation of what I have done:
Get all <a>
tags and save them in a list (via XPATH)
List<IWebElement> aHrefs = driver.FindElements(By.XPath("/html/body/div[4]/table[2]//a")).ToList();
Declare new List<String>
that will save the <a hrefs>
Loop over each <a>
tag and get the <href>
attribute and store in the list
Can then loop over each link within the <href>
and open it via driver.Url = link