Home > Blockchain >  Selenium - StaleElementReferenceException - element is not attached to the page document (C#)
Selenium - StaleElementReferenceException - element is not attached to the page document (C#)

Time:05-13

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: Table

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&amp;crn=50493&amp;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&amp;crn=50493&amp;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&amp;crn=50493&amp;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

  • Related