Arsen
Arsen

Reputation: 65

StaleElementReferenceException error on Python Selenium

Can you please help solve this problem?

When I run this code:

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
import time
from selenium.common.exceptions import StaleElementReferenceException

class ActionsMy():
def test(self):
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get("https://demoqa.com/")
    driver.implicitly_wait(3)

    action = ActionChains(driver)

    # Sortable
    driver.find_element(By.XPATH, "//a[contains(text(),'Sortable')]").click()
    item1 = driver.find_element_by_xpath("//li[contains(text(),'Item 1')]")
    action.drag_and_drop_by_offset(item1, 0, 150).perform()
    time.sleep(1)

    # Resizable
    driver.find_element_by_link_text("Resizable").click()
    resizableElement = driver.find_element_by_xpath(
            "//div[@class='ui-resizable-handle ui-resizable-se ui-icon ui-icon-gripsmall-diagonal-se']")
    action.drag_and_drop_by_offset(resizableElement, 200, 200).perform()

 dd = ActionsMy()
 dd.test()

I get this error:

selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document

My research showed this problem related to the fact that the element is no longer in the DOM, or it changed.

I have used this solution:

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
import time
from selenium.common.exceptions import StaleElementReferenceException

class ActionsMy():
def test(self):
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get("https://demoqa.com/")
    driver.implicitly_wait(3)

    action = ActionChains(driver)

    # Sortable
    driver.find_element(By.XPATH, "//a[contains(text(),'Sortable')]").click()
    item1 = driver.find_element_by_xpath("//li[contains(text(),'Item 1')]")
    action.drag_and_drop_by_offset(item1, 0, 150).perform()
    time.sleep(1)

    # Resizable
    driver.find_element_by_link_text("Resizable").click()
    try:
        resizableElement = driver.find_element_by_xpath(
            "//div[@class='ui-resizable-handle ui-resizable-se ui-icon ui-icon-gripsmall-diagonal-se']")
    except StaleElementReferenceException:
        action.drag_and_drop_by_offset(resizableElement, 200, 200).perform()


 dd = ActionsMy()
 dd.test()

In this case, there are no errors, but the operation is not performed.

I have also used WebDriverWait, but it did not help either.

Upvotes: 1

Views: 255

Answers (1)

Guy
Guy

Reputation: 50949

The problem is in ActionChains, it retains all the previous actions, including the drag_and_drop_by_offset with item1 so when perform() is called it tries to do this action again, but item1 is stale.

There is reset_actions() function to clear those actions, but it doesn't work. There is a bug report that indicates it will be fixed in Selenium 4.

In the meantime, create new ActionChains instance and use it

resizable_element = driver.find_element_by_xpath("//div[@class='ui-resizable-handle ui-resizable-se ui-icon ui-icon-gripsmall-diagonal-se']")
action = ActionChains(driver)
action.drag_and_drop_by_offset(resizable_element, 200, 200).perform()

Upvotes: 1

Related Questions