Random "Element Is No Longer Attached to the Dom" Staleelementreferenceexception

Random Element is no longer attached to the DOM StaleElementReferenceException

Yes, if you're having problems with StaleElementReferenceExceptions it's because there is a race condition. Consider the following scenario:

WebElement element = driver.findElement(By.id("foo"));
// DOM changes - page is refreshed, or element is removed and re-added
element.click();

Now at the point where you're clicking the element, the element reference is no longer valid. It's close to impossible for WebDriver to make a good guess about all the cases where this might happen - so it throws up its hands and gives control to you, who as the test/app author should know exactly what may or may not happen. What you want to do is explicitly wait until the DOM is in a state where you know things won't change. For example, using a WebDriverWait to wait for a specific element to exist:

// times out after 5 seconds
WebDriverWait wait = new WebDriverWait(driver, 5);

// while the following loop runs, the DOM changes -
// page is refreshed, or element is removed and re-added
wait.until(presenceOfElementLocated(By.id("container-element")));

// now we're good - let's click the element
driver.findElement(By.id("foo")).click();

The presenceOfElementLocated() method would look something like this:

private static Function<WebDriver,WebElement> presenceOfElementLocated(final By locator) {
return new Function<WebDriver, WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
};
}

You're quite right about the current Chrome driver being quite unstable, and you'll be happy to hear that the Selenium trunk has a rewritten Chrome driver, where most of the implementation was done by the Chromium developers as part of their tree.

PS. Alternatively, instead of waiting explicitly like in the example above, you can enable implicit waits - this way WebDriver will always loop up until the specified timeout waiting for the element to become present:

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS)

In my experience though, explicitly waiting is always more reliable.

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

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

StaleElementReferenceException: Element is no longer attached to the DOM: Selenium

StaleElementException is there to tell you that a DOM element that you've referenced in your client code (by a findElement) doesn't exist anymore. In your case, the row1 element doesn't exist anymore. It is certainly a timing issue, as your click to sort is just above, and no care is taken to ensure the sort has finished. Without more insight in how the sort is implemented, or how long it takes, it'd be my best guess. If the sort ends while you iterate through your DOM objects, these will be rearranged in the DOM and lost in your client code

Selenium element is no longer attached to the DOM Error While Scraping dynamic table

Abit laggy ans but I did this way.

total_length = (driver.find_element(By.XPATH, "//span[@id='ctl00_ContentPlaceHolder1_PagerControl2_litRecords']").text)
z = int((total_length.split()[-1]).replace(']', ''))
for data in range(1, z + 1):
driver.find_element(By.XPATH, "(//a[@title='Page {}'])[2]".format(data)).click()
for value in driver.find_elements(By.XPATH, '//tbody/tr'):
table_data = value.find_elements_by_tag_name('td')
print([td.text for td in table_data])


time.sleep(2)

Element is no longer attached to the DOM selenium webdriver

You may use a 'hack'. To avoid StaleElementReferenceException you have to relocate an element before some action with it. If I understand your logic, you want to uncheck all checkboxes but the 'DE'. You locate li's with the XPATH //div[@id='filters-airlines']//ul[@class='clearfix']/li. So you can relocate it every time with given index

ul = driver.findElements( By.xpath( "//div[@id='filters-airlines']//ul[@class='clearfix']/li" ) );

for( int i = 1; i <= ul.size(); i++ ){

WebElement li = driver.findElement( By.xpath( "(//div[@id='filters-airlines']//ul[@class='clearfix']/li)[" + i + "]" ) );

String countryCode = li.getAttribute( "data-airline-id" );

System.out.println( countryCode );

if( !"DE".equals( countryCode ) ){

li.findElement( By.id( "airline_" + countryCode ) ).click();

}

try{
Thread.sleep( 1000 );
}
catch( InterruptedException e ){
// TODO Auto-generated catch block
e.printStackTrace();
}
}

PS I don't use Java so syntax may be broken a little

Test throws StaleElementReferenceException: either the element is no longer attached to the DOM or the page has been refreshed

I was able to solve the problem by rearranging the code in this order:

        WebElement searchbutton = driver.findElement(By.name("btnK"));
driver.findElement(By.name("btnK")).click();
WebDriverWait wait = new WebDriverWait(driver,10);
WebElement text2 = wait.until(visibilityOfElementLocated(By.id("lst-ib")));
text2.clear();

It looks like I was trying to wait before the click() but should have waited for the element to load after the click() but before the clear()
Now it does not throw that error

Thank you all for your suggestions and solutions. I am sure they would be useful in future in a more complicated code problems.

I am getting StaleElementReferenceException: element is not attached to the page document

Because clicking the found cell lead some HTML changes on the current page , due to this changes selenium will treat the page(after click) is an "new" page (even though not redirect to another page actually).

In the next iteration of the loop, the loop still refer to element belongs to "previous" page, this is the root cause of "StateElementReference" exception.

So you need to find those elements again on the "new" page to change the reference of element comes from "new" page.

WebElement table2 = driver.findElement(By.cssSelector("body > div:nth-child(74) > div.sp-palette-container"));
List<WebElement> allrows2 = table2.findElements(By.tagName("div"));

int rowSize, cellSize = 0;
rowSize = allrows2.sie();

for(int rowIndex=0;rowIndex<rowSize;rowIndex++){
WebElement row2 = allrows2.get(rowIndex);
List<WebElement> cells = row2.findElements(By.tagName("span"));
cellSize = cells.size();

for(int cellIndex=0;cellIndex<cellSize;cellIndex++){
WebElement cell = cells.get(cellIndex);

if (cell.getAttribute("title").equals("rgb(0, 158, 236)")) {
cell.click();
// find cells again on "new" page
cells = row2.findElements(By.tagName("span"));
// find rows again on "new" page
allrows2 = table2.findElements(By.tagName("div"));
}
}
}


Related Topics



Leave a reply



Submit