selenium element is not attached to the page document in selenium Java
You wrote "I'm trying to get data instantly..." Well, this could be a problem.
StaleElementReferenceException
are thrown when a web element is obtained before the contents of the webpage refreshes or during the refresh process. In other words, it is obtained prematurely. The solution is to wait until the page finishes loading completely.
"Element is not attached to the page document" means that the web element is probably no longer in the HTML document.
There are two ways of obtaining a web element:
WebDriver driver = new ChromeDriver();
driver.findElement(...);
Assuming that you are on the correct page, findElement
will attempt to locate the element without delay. If the page is in the process of loading, it will most likely result in the error mentioned in the OP's post. The correct way to fix this is to add an implicit wait.
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); // Time amount and time units are arbitrary.
// get to the page...
driver.findElement(...);
In the above snippet, from the moment implicitlyWait
is called until the end of the test session, before any attempt to obtain a web element, the application will wait the minimum amount of time passed to the function; in my example that's 10 seconds.
A better way to do this is to use WebDriverWait
class.
WebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, 10); // max. wait time set to 10 seconds with default 500 ms polling interval
WebDriverWait
has a three-argument variant where the third argument is the polling interval in milliseconds. For example, WebDriverWait(driver, 10, 100)
will wait a maximum of 10 seconds, polling every 100 ms. Once the wait
object is obtained, it will be used to obtain a WebElement
object passing the correct expected condition provided by the ExpectedConditions
class. For example, to wait until a button becomes "clickable" (both visible and enabled)
WebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.xpath(XPATH EXPRESSION HERE)));
button.click();
This approach, assuming you are already on the correct page, will attempt to locate the desired component the maximum amount of time passed to the WebDriverWait
constructor before it times out. But, if the component is located AND the expected condition is reached before timing out, it will return the requested component. This is a better way to avoid stale element (although not completely).
Probably the best approach is to combine both of the approaches.
To start, set the implicit wait time as soon as the web driver instance is obtained
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Then, navigate to the page
driver.navigate().to("https:.........");
Lastly, use the second approach to obtain the web element
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("...")));
button.click();
When implicit and explicit waits are used together, the chances of stale element issues is reduced to almost zero. You just have to be smart and always obtain the web element just before you are going to use it.... And DEFINITELY DO NOT put code like this in an endless loop.
Basically, this code works.... sort of.
public class TickerPageTest {
@Test
public void printTickerValueEndlessLoop() {
System.setProperty("webdriver.chrome.driver", "F:\\Users\\Hector\\webdriver\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("https://coincheck.com/exchange/tradeview");
while (true) {
WebDriverWait wait = new WebDriverWait(driver, 10, 10);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("/html/body/div[2]/div[1]/div/div[2]/div[2]/div[2]/div[2]/div[1]/div[1]/span[3]")));
System.out.println(element.getTagName() + ":" + element.getText());
}
}
}
The above code outputs the following (most of the time)
span:5898999
...
span:5900895
...
span:5898999
The best bet is to wrap the interaction with the web element in a try/catch where you will catch the StaleElementReferenceException
to ignore it and continue. In a real Selenium Test, you can you this strategy to retry obtaining the missed element, but in this case you don't need to.
try {
System.out.println(element.getTagName() + ":" + element.getText());
} catch (StaleElementReferenceException e) {
System.err.println("Test lost sync... this will be ignored.");
}
When I did this, after a few hundred lines (or more) I was able to catch a loss in synchronization:
span:5906025
Test lost sync... this will be ignored.
span:5906249
But, as you can see, I just ignored it and moved on to the next update.
Again Stale element reference: element is not attached to the page document
When you are doing
driver.findElement(completeButtonByXpath);
then at this time selenium is looking for *//button[text()='Complete']
xPath.
And probably at this time, it is not attached to HTML-DOM
causing staleness
.
Solution:
A very simple solution is to put hardcoded sleep like this:
Thread.sleep(5000);
and now look for WebElement completeButton = driver.findElement(completeButtonByXpath);
Modify
completeSession
to Just have explicit waits.public void completeSession() {
By completeButtonByXpath = By.xpath("*//button[text()='Complete']");
//WebElement completeButton = driver.findElement(completeButtonByXpath);
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(completeButtonByXpath)).click();
}Retry
clicking
.
Code:
public void completeSession() {
By completeButtonByXpath = By.xpath("*//button[text()='Complete']");
WebElement completeButton = driver.findElement(completeButtonByXpath);
int attempts = 0;
while(attempts < 5) {
try {
completeButton.click();
break;
}
catch(StaleElementReferenceException staleException) {
staleException.printStackTrace();
}
attempts++;
}
}
Python Selenium Error: Message: stale element reference: element is not attached to the page document
You can use the normal click method, store the element in the list, get the element index and click on the index.
you can update your code with the below one
video_text = driver.find_elements_by_class_name("entry-thumbnails-link")
WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'entry-thumbnails-link')))
video_text[0].click()
The complete code will look like this
Vids = WebDriverWait(driver, 10).until(EC.visibility_of_any_elements_located((By.CLASS_NAME, 'entry-thumbnails-link')))
for title in Vids:
time.sleep(3)
actions = ActionChains(driver)
video_text = driver.find_elements_by_class_name("entry-thumbnails-link")
WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'entry-thumbnails-link')))
video_text[0].click()
time.sleep(5)
VidUrl = driver.current_url
VidTitle = driver.find_element_by_xpath('//*[@id="post-69331"]/h1/a').text
try:
VidTags = driver.find_elements_by_class_name('tags')
for tag in VidTags:
VidTag = tag.find_element_by_tag_name('a').text
except NoSuchElementException or StaleElementReferenceException:
pass
with open('data.csv', 'w', newline='', encoding="utf-8") as f:
fieldnames = ['Title', 'Tags', 'URL']
thewriter = csv.DictWriter(f, fieldnames=fieldnames)
thewriter.writeheader()
thewriter.writerow({'Title': VidTitle, 'Tags': VidTag, 'URL': VidUrl})
driver.get(URL)
print('done')
Also try not to use these many sleep().
Python Selenium StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
Since I have no credentials to enter that site I can only guess.
So my guess is: that site uses dynamic DOM.
It means that after the initial appearance the web elements continue re-build, so even after Selenium caught some specific element to be clickable or visible this element may instantly continue changing so that the initial element reference becomes stale.
You can try treat this problem by 2 ways:
- Set first
wait
condition, after that set a delay and after that anotherwait
condition. Something like this:
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver,60)
wait.until(EC.element_to_be_clickable((By.XPATH,"//input[@id='ContentPlaceHolder1_rcmbCapacityTranch_Input']")))
time.sleep(2)
wait.until(EC.element_to_be_clickable((By.XPATH,"//input[@id='ContentPlaceHolder1_rcmbCapacityTranch_Input']"))).click()
- After you caught the element try clicking it. In case Stale element exception is raised wait until the element is clickable again and try clicking it again until click is succeed. With such loop you will normally make a click during 2-3 iterations.
So please try this:
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver,60)
succeed = False
while !succeed:
try:
wait.until(EC.element_to_be_clickable((By.XPATH,"//input[@id='ContentPlaceHolder1_rcmbCapacityTranch_Input']"))).click()
succeed = True
except:
pass
ElementReferenceException: stale element reference: element is not attached to the page document
StaleElementReferenceException will be occurs only when your element is not present(vanished or not constructed till) in your website. please add wait conditions to check the visiblity of the element.
By optionXpath = By.xpath("your xpath fp goes here !");
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.elementToBeClickable(optionXpath));
wait.until(ExpectedConditions.visibilityOfElementLocated(optionXpath));
driver.findElement(optionXpath).click();
In case of not constructed :
you need to add wait conditions
In case of vanished :
yours actions on element is wrong. add screenshot just before your failure code and
recheck your code.
Selenium - stale element reference: element is not attached to the page
I haven't worked in c# but have worked on java/selenium. But,I can give you the idea to overcome staleness.
Generally we will be getting the Stale Exception if the element attributes or something is changed after initiating the webelement. For example, in some cases if user tries to click on the same element on the same page but after page refresh, gets staleelement exception.
To overcome this, we can create the fresh webelement in case if the page is changed or refreshed. Below code can give you some idea.(It's in java but the concept will be same)
Example:
webElement element = driver.findElement(by.xpath("//*[@id='StackOverflow']"));
element.click();
//page is refreshed
element.click();//This will obviously throw stale exception
To overcome this, we can store the xpath in some string and use it create a fresh webelement as we go.
String xpath = "//*[@id='StackOverflow']";
driver.findElement(by.xpath(xpath)).click();
//page has been refreshed. Now create a new element and work on it
driver.findElement(by.xpath(xpath)).click(); //This works
In this case, we are collecting a group of webelements and iterating to get the text. But it seems there is some changes in the webelement after collecting the webelements and gettext throws staleness. We can use a loop and create the element on the go and get text.
for(int i = 0; i<5; i++)
{
String value = driver.findElement(by.xpath("//.....["+i+"]")).getText);
System.out.println(value);
}
Hope this helps you. Thanks.
Related Topics
Handling Passwords Used for Auth in Source Code
How to Specify the Schema When Connecting to Postgres with Jdbc
Any Way to Invoke a Private Method
Differencebetween Method Overloading and Overriding
Can Java 8 Code Be Compiled to Run on Java 7 Jvm
Hibernate Opensession() VS Getcurrentsession()
What's the Difference Between Primitive and Reference Types
How to Convert a String with Unicode Encoding to a String of Letters
How to Get the SQL of a Preparedstatement
How to Parse Date String to Date
Selenium Webdriver How to Resolve Stale Element Reference Exception
Java Random Always Returns the Same Number When I Set the Seed
Effective Gif/Image Color Quantization
How to Sort List of Objects by Some Property
Useful Example of a Shutdown Hook in Java