Selenium -- How to wait until page is completely loaded [duplicate] - java

This question already has answers here:
Wait for page load in Selenium
(48 answers)
Closed 6 years ago.
I am trying to automate some test cases using Java and Selenium WebDriver. I have the following scenario:
There is a page named 'Products'. When I click on 'View Details' link
in the 'Product' page, a popup (modal-dialog) containing the details of the item appears.
When I click on the 'Close' button in the popup the popup closes and
the page automatically refreshes (the page is just reloading, the contents remain unchanged).
After closing the popup I need to click on 'Add Item' button in the
same page. But when WebDriver trying to find the 'Add Item' button,
if the internet speed is too fast, WebDriver can find and click the
element.
But if the internet is slow, WebDriver finds the button before the
page refresh, but as soon as the WebDriver click on the button, the page refreshes and StaleElementReferenceException occurs.
Even if different waits are used, all the wait conditions become true
(since the contents in the page are same before and after reload)
even before the page is reloaded and StaleElementReferenceException
occurs.
The test case works fine if Thread.sleep(3000); is used before clicking on the 'Add Item' button. Is there any other workaround for this problem?

3 answers, which you can combine:
Set implicit wait immediately after creating the web driver instance:
_ = driver.Manage().Timeouts().ImplicitWait;
This will try to wait until the page is fully loaded on every page navigation or page reload.
After page navigation, call JavaScript return document.readyState until "complete" is returned. The web driver instance can serve as JavaScript executor. Sample code:
C#
new WebDriverWait(driver, MyDefaultTimeout).Until(
d => ((IJavaScriptExecutor) d).ExecuteScript("return document.readyState").Equals("complete"));
Java
new WebDriverWait(firefoxDriver, pageLoadTimeout).until(
webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
Check if the URL matches the pattern you expect.

It seems that you need to wait for the page to be reloaded before clicking on the "Add" button.
In this case you could wait for the "Add Item" element to become stale before clicking on the reloaded element:
WebDriverWait wait = new WebDriverWait(driver, 20);
By addItem = By.xpath("//input[.='Add Item']");
// get the "Add Item" element
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(addItem));
//trigger the reaload of the page
driver.findElement(By.id("...")).click();
// wait the element "Add Item" to become stale
wait.until(ExpectedConditions.stalenessOf(element));
// click on "Add Item" once the page is reloaded
wait.until(ExpectedConditions.presenceOfElementLocated(addItem)).click();

You can do this in many ways before clicking on add items:
WebDriverWait wait = new WebDriverWait(driver, 40);
wait.until(ExpectedConditions.elementToBeClickable(By.id("urelementid"))); // instead of id you can use cssSelector or xpath of your element.
or:
wait.until(ExpectedConditions.visibilityOfElementLocated("urelement"));
You can also wait like this. If you want to wait until invisible of previous page element:
wait.until(ExpectedConditions.invisibilityOfElementLocated("urelement"));
Here is the link where you can find all the Selenium WebDriver APIs that can be used for wait and its documentation.

yes stale element error is thrown when (taking your scenario) you have defined locator strategy to click on 'Add Item' first and then when you close the pop up the page gets refreshed hence the reference defined for 'Add Item' is lost in the memory so to overcome this you have to redefine the locator strategy for 'Add Item' again
understand it with a dummy code
// clicking on view details
driver.findElement(By.id("")).click();
// closing the pop up
driver.findElement(By.id("")).click();
// and when you try to click on Add Item
driver.findElement(By.id("")).click();
// you get stale element exception as reference to add item is lost
// so to overcome this you have to re identify the locator strategy for add item
// Please note : this is one of the way to overcome stale element exception
// Step 1 please add a universal wait in your script like below
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS); // just after you have initiated browser

There are two different ways to use delay in selenium one which is most commonly in use. Please try this:
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
second one which you can use that is simply try catch method by using that method
you can get your desire result.if you want example code feel free to contact me defiantly I will provide related code

Related

Page is unclickable after closing a window

My flow is as follows in selenium:
Access a webpage
Click a tab
Click on add button in a tab where a window would open
Close that window
Click on that same tab again
I'm able to go through steps 1 to 4 without issues however at step 5 i'm not able to click the tab element knowing that i've clicked that same tab at step2, I did check from console and the same xpath I used in step2 did not return any element however when i clicked on that element to inspect it in console it started returning some values in console but still didn't work from selenium when i continued the run (in debug)
My page is in an Iframe which i was successfully able to access and print page title after step 4 but my issue remains, why aren't i able to click that tab from selenium after i close the window and the screen refreshes, why are the elements unresponsive anymore?
After doing some research i also tried the below script:
WebElement element=driver.findElement(By.xpath(the_path));
JavascriptExecutor ex=(JavascriptExecutor)driver;
ex.executeScript("arguments[0].click()", element);
but it would fail at the first line since the element is not fount, tried to initialize it earlier in the code but then it would fail at line 3.
How do i fix this issue?
Try to click on the element using Selenium code, not by injecting JavaScript to the pages. This should solve your problem.
WebElement element = driver.findElement(By.xpath(the_path));
element.click();
The issue was due to having multiple Iframes in the main page, so when closing switching windows I was not redirected to the proper Iframe in which i was in step 3 when clicking the tab.

Unable to click on webelement button

Unable to click on webelement button
I tried to click on button by mouse movement but no success
my outer html is as below :
<button class="btn btn-alt btn-small" type="button" ng-click="ecdapp.uploadBlueprintModalPopup();">
Create
</button>
button xpath is:
//*[#id="page-content"]/div[3]/button
Not seeing the full page source it's hard to tell where your XPath expression is good or not, you can try locating the button using its text instead
//button[normalize-space(text())='Create']
the normalize-space() function is used to discard heading/trailing whitespaces
It might also be the case the button is not immediately available, I would recommend considering using Explicit Wait approach via WebDriverWait class
WebElement myButton = new WebDriverWait(driver, 10)
.until(ExpectedConditions
.elementToBeClickable(By.xpath("//button[normalize-space(text())='Create']")));
myButton.click();
the above code will try to locate the aforementioned button for 10 seconds and click it as soon as it will be present/visible/clickable. Otherwise it will fail with NoSuchElementException
May be the Xpath is wrong. Try the below xpath:
//button[contains(text(),'Create')]
As you can see on the screenshot this Xpath 100% works, if you still won't be able to click on that button, then problem is not with xpath. Let me know if its still fails.
By.xpath("//button[#class = 'btn btn-alt btn-small' and #type = 'button']")
Based on your comment:
I tried this code , but unable to click . element click intercepted: Element ... is not clickable at point (293, 97). Other element would receive the click: ... (Session info: chrome=74.0.3729.169)
I pretty sure I know whats your problem, before u click on this element, something going on the page:
It says - Other element would receive the click, means there is other element above(overlapping) your button(pop up window, page is greyed out(disabled while loading, Some JS running)), so when Selenium trying to click on your button its actually clicking on that blocking element.
Try to click after Thread.Sleep(); wait 5-10 sec.
If this is the case then u need to add condition before find your button to check that element that prevent from clicking on button is disappeared then u click on it.
Try JavaScript executors as below,
WebElement element = driver.findElement(By.xpath("<xpath of button>"));
JavascriptExecutor js= (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();", element);

Cant select option of dropdown in selenium

I am displaying a dropdown for user to select after i click signup tab. But using selenium i am not able to select any option.
driver.findElement(By.id("signup")).click();
WebDriverWait wait = new WebDriverWait(driver,15);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Select drop = new Select(driver.findElement(By.id("user_type_select")));
drop.selectByIndex(2);
The signup tab appears but the dropdown is not selected. Any ideas?
can you sure the select is ready after 10s?
try this:
waiter.until(ExpectedConditions.presenceOfElementLocated(By.id("user_type_select")));
It is always better to wait for the elements to load and javascript to execute. At the end point javascript is the last action completed by a webpage, so check for the wait time of it. Sample code below.
wait.equals((((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete")));

Timed out after 10 seconds waiting for presence of element located using Selenium Wedriver

Locator for this is correct, but when running it in Selenium Webdriver, I am getting the same error .
I have used different kinds of waits like Implicit wait, Explicit wait, and Wait for Presence of element
WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.xp‌​ath("//div[#id = 'bs-example-navbar-collapse-1']/ul[2]/li[1]")));
driver.findElement(By.xpath("//div[#id = 'bs-example-navbar-collapse-1']/ul[2]/li[1]")).click();
Instead of using 'presenceOfElementLocated(By locator)', use 'visibilityOfElementLocated(By locator)'.
'presenceOfElementLocated(By locator)' only confirms the presence of element in DOM, it does not mean that element is visible or enable. But if you use 'visibilityOfElementLocated(By locator)', then it confirms the element is present in DOM as well as visible. If you are clicking the element you can also use 'elementToBeClickable(By locator)';
Its Shine.com , clicking on Login Link at top right hand side
You should try using By.linkText() to click on Login button as below :-
driver.get("http://www.shine.com/");
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Login"))).click();

How to Manipulate Search Bar That's Not Present in HTML Source Using Selenium?

I'm trying to use Selenium (Java) to automate some searches.
When I go to the page and click Inspect Element on the search bar, I see that it has the id searchBox and name q, both of which are potentially useful. Nevertheless, these properties are nowhere to be found in the HTML when I go to View Source.
When I try to use
WebElement search = driver.findElement(By.id("searchBox"));
or
WebElement search = driver.findElement(By.name("q"));
both come back as unable to be found.
How do I proceed with populating the search field then hitting submit (the submit button also is missing in the source page) if I can't find either of these elements?
EDIT:
As requested, here's a more detailed picture of what's wrong:
The URL of the page accessed by WebDriver is http://www.ycharts.com using the line
driver.get("http://www.ycharts.com/login");
If you go to this page with your actual web browser, right click on the search bar and choose Inspect Element, you'll see that its ID is "searchBox" and its name is "q". However, if you go to view the same page's source, you'll see that there's no such element in the HTML. Clearly, this is why WebDriver can't find it.
driver was initiated as follows:
WebDriver driver = new HtmlUnitDriver();
When I try something like
WebElement search = driver.findElement(By.id("searchBox"));`
The exception returned is:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate element with ID: searchBox
So, back to the original question: clearly, the element is there, but it's not in the HTML – how do you interact with it?
The problem is being caused by the fact that the search box is added to the html post page load by javascript.
The HTML returned by http://ycharts.com/ does not contain the searchbox, therefore when Selenium thinks the page has finished loading (i.e DOM ready state), there is no search box.
In order to interact with the search box, you need to tell Selenium to wait until the box appears in the DOM.
The easiest way to achieve this is with WebDriverWait;
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>));

Categories