I am clicking on the text box displayed on first page
WebElement txtBox = driver.findElement(By.xpath("---xpath---"));
txtBox.click();
Then after some block of execution I am getting the same textbox in new page on same window.
Here also I want to click on the text box.
I used JavascriptExecutor to do this scripting.
((JavascriptExecutor)driver).executeScript("arguments[0].click();", txtBox );
But while running the script I am getting an error message saying:
org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
You need to execute driver.findElement() every time you reload the page.
This method returns WebElement which is integral part of current page. If you refresh browser or navigate to some other URL or even if element is deleted and attached again by some javascript on same page, previously found element cannot be used anymore.
Here you have official explanation of this exception: http://www.seleniumhq.org/exceptions/stale_element_reference.jsp
Stale Element exception comes after you want to interact with an element loaded previously. If you get webelement and then reload the page it gives this exception because it is not in a newly created page. It is better to click the web element without assigning it to a variable like:
driver.findElement(By.xpath("---xpath---")).click();
Related
I am trying to go to the below URL
https://twitter.com/explore
Enter HBO Max in the text box which I locate using
By.cssSelector("input[placeholder='Search Twitter']")
and then I want to select the HBO Max option that appears in the dropdown. My locator for the element to be selected is
By.xpath("//div[#role='option']//li/div/div[2]")
Sometimes the element gets clicked and I go to the new page, sometimes not. I have in my framework waited for the element to be clickable using WebDriverWait. The element is both visible and enabled because I print these values before I click the element.
Additional debugging steps performed -
Click using JavaScript seems to have the same behavior.
I believe I am using the right locator because the mouse event gets generated for this element.
Thread.Sleep seems to work suggesting that perhaps a timing issue
Any inputs would be great.
try:
myElem = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, 'ID')))
print("Page is ready!")
except TimeoutException:
print("Loading took too much time!")
Try this !
what it does : It wait until the specific element of the site is loaded. If it takes more time than specified will just give you an output as "loading took too.........."
You can modify the time required to wait.
I'm getting Selenium exception stale element reference: element is not attached to the page document after the first iteration of the for loop. My code is :
for gc in grpCommune:
self.driver.execute_script("return arguments[0].scrollIntoView(true);", gc)
self.driver.execute_script("window.scrollTo(0, 0);")
e=gc.find_element_by_xpath('//a[2]')
e.click()
sleep(1)
...
genertaeCSV()
self.driver.back()
how can I resolve it?
Stale Element exception occurs when the selenium reference bound to the element is no more valid, generally, this happens when you either navigate away from the page or refresh the page or the contents on the page is reloaded. In your case, you are trying to refer to the gc element which was captured with a reference before clicking the e element. The moment you clicked on e element using e.click() button, all the references in grpCommune is no longer valid. So, you will be able to run only the first iteration successfully with your code.
How do I fix this code:
Get the gc element within the for loop. Rather than using for each use for loop with the index.
Stale element exception occuring when element in on page but selenium driver instance could not interect with that element.
Following actions can be resolve stale element exception
1.Refresh page by using "navigate(). refresh()" method in selenium
2.using loop try to click or check visible of that element if that element visible or already clicked exit from loop.
I am using selenium 3.9.1 and java to automate testing of a web application. The web application has some dynamic content based on pressing of a button for example. The page refreshes whenever this button is clicked. A java script runs on button click and updates the DOM I think. At this time, when I try to access the button (which is visible on the page), I get a staleElementReferenceException.
Does Selenium automatically reload the DOM once it is changed? I am relatively new to selenium. I have researched into this and I have tried to refresh the page using driver.navigate().Refresh() to try to see whether this will solve the problem. It does not solve the issue.
Any pointers will be deeply appreciated.
Since the page has been refreshed, the button reference you have is to the button on the old page that no longer exists.
I'd say you need to get a new reference to the button on the refreshed page (eg call FindElementById).
If the page is refreshed all the items in the DOM are now stale. What this means is that all items found before the button press will have to be found again. Any attempts to use those items will more than likely be treated with a stale element exception.
However, if the button click mearilly affects items on the page without having to ask the webserver to give you a new page you could interact with the old items.
You could do something like this:
public void SaveAndAgainClick() throws Exception{
try{
clicksaveButton(); //method to click save button
WebElement someValue = driver.findElement(By.xpath("(//input[#name='someValue'])[1]"));
someValue.click();
}catch (StaleElementException e){
WebElement someValue = driver.findElement(By.xpath("(//input[#name='someValue'])[1]");
someValue.click();
}
}
If findElement gets staleElementError while looking for (//input[#name='someValue'])[1] then it will again try one more time in the catch block and most certainly find the element and clicks on it. Your test will pass if you follow this approach.
Here are the answers to your questions :
A java script runs on button click and updates the DOM I think : If you inspect the HTML of the element through Development Tools / Inspect Element the element attributes will reveal it all.
Consider the following HTML :
<input value="Click me" onclick="alert('Click!')" type="button">
In the given HTML as per the onclick attribute of this element, if you invoke click() method on the WebElement, an alert would be generated. Similarly the onclick attribute may invoke a JavaScript or Ajax which may bring-in/phase-out new/old elements from the HTML DOM
At this time, when I try to access the button I get a staleElementReferenceException : In this case you should induce WebDriverWait for the WebElement to be interactive before attempting to interact with the element. Else you may face either of the following exceptions :
StaleElementReferenceException
WebDriverException
ElementNotInteractableException
InvalidElementStateException
Does Selenium automatically reload the DOM once it is changed? Short answer, Yes it does.
Refresh the page using driver.navigate().refresh() : No invoking driver.navigate().refresh() wouldn't be a optimum solution as it may not invoke the intended JavaScript or Ajax properly. Hence the intended WebElement may not be interactive in a optimum way.
I used 3 different waits purposely to locate the element (a checkbox) on the page as shown below and they get passed. After that I click on that same element which also gets passed.
Now my question is if the click element method gets passed then why does Checkbox should be selected fails because in click element method I am clicking on that checkbox only!!
HTML screenshot.
I have tried this clicking on checkbox multiple times using various strategies but it fails every time. Please help and suggest some solution!!
Code I wrote:
` sleep 2
wait until page contains element id_service_levels_0
wait until element is enabled id=id_service_levels_0
wait until element is enabled id=id_service_levels_0
page should contain element id=id_service_levels_0
click element id=id_service_levels_0
checkbox should be selected id=id_service_levels_0
`
You can try with JavaScript executor as given below.
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("document.getElementById('id_service_levels_0').click()");
I'm trying to access a screen in an application, which appears when I do a mouse-hover over a tab and click on one of the options. I used Actions method to execute this using selenium. Here's my code:
element=driver.findElement(By.id("tab"));
Actions hoverover=new Actions(driver);
hoverover.moveToElement(element).moveToElement(driver.findElement(By.id("menu"))).click().build().perform();
When I login to the application and directly call this tab, I'm able to access this without any issue. But the problem occurs when I access this tab from a different screen in the application.
Whenever I access the hover-over page from a different page in the application, sometimes the page loads correctly but most of the time it fails and I recieve 'no such element' or 'stale element reference' error.
I'm really not sure how it is able to access the tab without any issue sometimes and how sometimes it is throwing errors. Please guide me here and let me know if there is anything else(any additional functions/or an alternative to Actions?) I can do so that the mouse-over click works all the time.
EDIT: I tried using both Explicit and Implicit waits and even thread.sleep as well, but in vain. In Chrome(only in chrome) when i do a manual screen refresh while it tries to access the tab, it works. But when I do the same in my code [driver.navigate().refresh()], it's not working!!
The stale element exception is probably occurring between when you set element and when you hoverover. Selenium does something like:
WebElement element = driver.findElement(By.id("tab"));
// "element" has been set
Actions hoverover=new Actions(driver);
// Between here and hoverover, "element" has changed on the DOM
hoverover.moveToElement(element).moveToElement(
driver.findElement(By.id("menu"))).click().build().perform();
// Uh-oh, what's "element?" Better throw an exception!
Try eliminating the element= line and moving driver.findElement to the inside of moveToElement().
Actions hoverover = new Actions(driver);
hoverover.moveToElement(driver.findElement(By.id("tab")))
.moveToElement(driver.findElement(By.id("menu"))).click().build().perform();
You could also try throwing in a WebDriverWait between hovering over tab and menu.
hoverover.moveToElement(driver.findElement(By.id("tab"))).build().perform();
new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.id("menu")));
hoverover.moveToElement(driver.findElement(By.id("menu"))).click().build().perform();