I keep geting a StaleElementReferenceException when I'm trying to test a webpage that contains a table. The table has points [as well as some other info] and the status of two separate Blocking points, each of which has a toggle state button for 'Yes' and 'No'.
In this particular code, the process is:
- Click the checkbox to reveal only the blocking points.
- If there are no blocking point in the table, you're DONE. Otherwise...
- Save the name of the point in the first row & check the first blocking status. If set to 'Yes', change it to 'No.'
- Check to see if the point still remains. if so, change the second blocking status to 'No' and confirm the point has been deleted.
I added comments in the code to help follow my process:
# << Setup >>
driver.get(url("/PointsTable/"))
assertExpectedConditionTrue(driver, "By.XPATH", "//td")
# < Confirm that the points blocking checkbox is enabled >
if not driver.find_element_by_id("BlockedPoints").is_selected():
assertExpectedConditionTrue(driver, "By.ID", "BlockedPoints")
driver.find_element_by_id("BlockedPoints").click()
assertCheckBoxEnabled(driver, "BlockedPoints")
# < First check if any points have a blocking state >
try:
assertExpectedConditionTrue(driver, "By.XPATH", "//td[contains(text(), 'No data available in table')]", None, 3)
except (NoSuchElementException):
# < Until all the points are out of blocking state, begin changing blocking statuses
# to all the points >
while True:
# < Check if all the points are set to have no blocking statuses set to Yes >
try:
assertExpectedConditionFalse(driver, "By.XPATH", "//td[contains(text(), 'No data available in table')]", None, 2)
except (NoSuchElementException, TimeoutException):
break
# < Save the name of the point
# Check the first blocking status. If it is blocking, set the block to No >
assertExpectedConditionTrue(driver, "By.XPATH", "//td")
myPointVal = driver.find_element_by_xpath("//td").text
try:
assertExpectedConditionTrue(driver, "By.XPATH", "//tbody/tr[1]/td[5]/div/button[@class='btn active btn-success btn-small point-button']", None, 2)
except (NoSuchElementException):
assertExpectedConditionTrue(driver, "By.XPATH", "//tbody/tr[1]/td[5]/div/button[@class='btn btn-small point-button']")
driver.find_element_by_xpath("//tbody/tr[1]/td[5]/div/button[@class='btn btn-small point-button']").click()
# < Save the name of the point again. Compare it to the original saved point
# If the name is the same, then the second blocking status needs to be set to No
# If the name is different, that means the point in question is no longer blocked >
assertExpectedConditionTrue(driver, "By.XPATH", "//td")
if myPointVal == driver.find_element_by_xpath("//td").text:
assertExpectedConditionTrue(driver, "By.XPATH", "//tbody/tr[1]/td[6]/div/button[@class='btn btn-small point-button']")
driver.find_element_by_xpath("//tbody/tr[1]/td[6]/div/button[@class='btn btn-small point-button']").click()
assertExpectedConditionFalse(driver, "By.XPATH", "//td", myPointVal)
When a point has had all its Blocking states removed, it literally disappears from the table, which is the cause of my exception. The code doesn't always fail on the same line, but when it fails, it's ALWAYS on a line where I attempt to click on the 'Yes' or 'No' button, more than likely due to the table changing after a point has been successfully removed from the table.
i.e. driver.find_element_by_xpath("//tbody/tr[1]/td[6]/div/button[@class='btn btn-small point-button']").click()
It sometimes makes it past this portion of the code & fails in a different portion where I'm attempting to click on a button either after I've.. (1) refreshed the page, or (2) have navigated to page two, where the XPATH addresses are the same, but the objects in the XPATH address have changed. I do understand the reason I'm having this issue for the reasons listed here. My issue seems to be consistent with, "The element is no longer attached to the DOM."
Up to this point, I've tried using both time.sleep() and driver.implicitly_wait() in locations that could cause change to the table, but the issue still remains. How can I resolve this issue?