This function receives a WebElement and uses it to locate other elements. But when I switch to an iframe and back, the WebElement seems to be invalidated. The error I get is “stale element reference: element is not attached to the page document”.
def map_vid(vid): vid_name = vid.find_element(By.XPATH, "./*[1]").text frame = driver.find_element(By.XPATH, FRAME_XPATH) driver.switch_to.frame(frame) quality_button = driver.find_element(By.CLASS_NAME, 'icon-cog') quality_button.click() driver.switch_to.default_content() close_button = vid.find_element(By.XPATH, CLOSE_BUTTON_XPATH) close_button.click()
Relocating the WebElement is not an option, since it’s passed as an argument. Any help would be greatly appriciated :)
Advertisement
Answer
You need to pass a By
locator as a parameter instead of passing a WebElement
parameter.
You can not make this your code working with passing a WebElement
parameter since Selenium WebElement
is a reference to physical web element on the page.
As you can see, switching to/from an iframe causes previously found WebElements
to become Stale.
Passing a By
locator will allow you to find the passed parent element inside the method each time you will need to use it.
Something like the following:
def map_vid(vid_by): vid = driver.find_element(vid_by) vid_name = vid.find_element(By.XPATH, "./*[1]").text frame = driver.find_element(By.XPATH, FRAME_XPATH) driver.switch_to.frame(frame) quality_button = driver.find_element(By.CLASS_NAME, 'icon-cog') quality_button.click() driver.switch_to.default_content() vid = driver.find_element(vid_by) close_button = vid.find_element(By.XPATH, CLOSE_BUTTON_XPATH) close_button.click()