When my test run using a webdriver for Firefox I'll get modal exception after reaching an accept on an alert:
[Exception]: Modal dialog present
The tests however work fine when using IE webdriver. The problem seems to be that test scenario proceeds before the alert is completely closed. In other words it tried to do the following:
List<WebElement> l = driver.findElements(By.linkText("link"));
and a result I'll get modal exception.
Now wait.until(ExpectedConditions) as mentioned wait.until(ExpectedConditions.visibilityOf Element1 OR Element2) is good candidate. However I am not able to create a condition that returns true when alart disappears. How can I do that?
Edit: to clarify further, the problem is not waiting for the alert to appear (my implicit wait is working fine for that purpose). I do get the alert and apply the test on that however after I click accept on the alert, test goes on fast and tried to proceed with the next step while alert still present and throws the modal present exception. I have also tried the following to prevent that with out success.
driver.switchTo().defaultContent();
There is now default mechanism to wait for alert to appear/disappear but, we can write our own logic something like below instead of waiting for static amount of time (Thread.sleep(10000)).
waitForAlert(WebDriver driver)
{
int i=0;
while(i++<5)
{
try
{
Alert alert = driver.switchTo().alert();
alert.accept();
break;
}
catch(NoAlertPresentException e)
{
Thread.sleep(1000);
continue;
}
}
}
even I faced this problem in FF and I came over this by using a AUI. Try to use the below code to get your alert > accept it and then continue with rest of your code/test.
Actions action = new Actions (driver);
action.click(driver.findElement(By.id("locator"))).build().perform();
driver.switchTo().alert().accept();
// Continue with your test
List<WebElement> l = driver.findElements(By.linkText("link"));
Related
I have developed selenium automation framework using JAVA and I facing a problem.
When I click on any button say Filter or clear filter application display a loading window and after that, we are able to perform next action.
i have added following code to wait until loading window visible false but its not working.
wait.until(ExpectedConditions.invisibilityOf(webElement));
System.out.println("Wait Untill Loading Window Closed");
existFlag=true;
in web element i passing that loading window XPATH. Every time code not wait for window to be closed start clicking on button and throw exception
unknown error: Element ... is not clickable at point (178, 391). Other element would receive the click:
I also added code for click
wait.until(ExpectedConditions.elementToBeClickable(webElement));
webElement.click();
return true;
Please help how i can wait till loading window close.
You should use implicit wait for this purpose. Add this statement for setting Implicit wait on driver object , after initialising the driver instance.
driver.manage().timeouts().implicitlyWait(Integer.parseInt("30"),TimeUnit.SECONDS);
You can use this :
wait.until(ExpectedConditions.visibilityOfElementLocated(webElement));
webElement.click();
You can write you personal waiter. I guess, you will got a few cases when you will see this scroller. For example you can try use next approach:
public void waitIfScrollerStillVisibe(int seconds, By locator) {
int counter = 0;
while (!isElemenyVisible(locator)) {
if (counter == seconds) {
new throw ElementIsNotVisibleException();
}
else {
Thread.sleep(seconds);
counter++;
}
}
}
Overview : I have already prepared the automation script in Selenium Web driver script in Java which will login into a website and make the selections automatically and once the selections are completed it will run the report.
What I want : I am facing issue while optimizing my automation script.
Brief Explanation : Actually I am familiar with different kinds of wait we are using in Selenium but all those wait i.e implicit,explicit or fluent wait didn't able to help me out in making the code more optimized.Currently I am using Thread.sleep() method everywhere in order to run the script completely without any fail but I know this should not be best practice to be get followed because sometime Elements loads fast and sometime slow because of that either my Script execution took long time or failed based on Element availability.I created one separate method for Webdriver wait and Which I can call for various webelements whenever I needed in my main script but this approach also sometime works or sometime not even though I am passing 800 Second as Time period to wait but if I use Thread.sleep(5000) it will work without any issue not sure why ??
What I want to be have a separate method for wait which can be called in main script whenever required and I want my script to be worked flawless the moment webeelment visible just like what we human do when we interacting with any web.
Note : I have tried ExpectedCondition methods like elementtobeclickable, visibilityOfElementLocated,presenceofElementLocated all of them sometime these work but sometime won't.
Separate Method of wait I have created
public static WebElement waiting(WebDriver driver,String path){
WebDriverWait wait = new WebDriverWait(driver,800);
WebElement element=wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(path)));
return element;
}
Piece of main code where I am calling this Method.
if(nam.equals("Some name"))
{
WebElement e=driver.findElement(By.xpath("1st Webelement path"));
e.click();
System.out.println("Value clicked under First Drop Down is:"+e);
Listing.waiting(driver,"2nd WebElement xpath").click();
//Thread.sleep(5000);
//driver.findElement(By.xpath("2nd WebElement xpath")).click();
System.out.println("Second Dropdown clicked");
}
When I commenting the Thread.sleep() then it will throw the ElementNotFound exception even though I have used 800 Seconds in Webdriver wait method but the moment I removed the comment from Thread.sleep() method it will work.
Kindly Help me in getting the reusable and useful wait method which I can call several times in my main code.
Thanks in Advance !!
This usually works for me (not FluentWait though):
WebDriverWait wait = new WebDriverWait(driver, TIMEOUT);
ExpectedCondition elementIsDisplayed = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver arg0) {
try {
webElement.isDisplayed();
return true;
}
catch (NoSuchElementException e ) {
return false;
}
catch (StaleElementReferenceException f) {
return false;
}
}
};
wait.until(elementIsDisplayed);
Of course, setup TIMEOUT with the amount of time you want to wait for the element to be found (that is in seconds).
I'm clicking on OK button. Clicks successfully. After that Selenium is not responding. It is not throwing any exception also. When I close the browser window manually then it tries to continue the execution.
I had the same effect, and so I wrote myself a custom Click() method that I call in such cases.
For Internet Explorer, it does a double-click instead of a click, which seems to be necessary sometimes for Selenium to work.
In Firefox, I occasionally got an exception ("Cannot press more then one button or an already pressed button"), so I wrote the following C# code that explicitly releases the button before pressing it (should look similar in Java):
public static void Click(this IWebElement element, TestParams testParams)
{
if (testParams.Target.IsFirefox)
{
var actions = new Actions(driver);
actions.MoveToElement(element);
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.Zero);
actions.Release().Build().TryPerform();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(testParams.DefaultTimeoutInSeconds));
actions.MoveToElement(element);
actions.Click().Build().Perform();
}
else if (testParams.Target.IsInternetExplorer)
{
element.DoubleClick(driver);
}
else
{
element.Click();
}
}
This doesn't always work, so I only call my custom Click() method when really necessary. This produces stable results on the sites I usually test.
I am using Webdriver in Java and I encountered an issue repeatedly that I can't find a proper solution yet.
It is to do with doing actions on a page that will cause this page DOM to change (for example, Javascript lightbox), then my JUnit test is expecting new elements after the DOM change but my test is getting the old DOM element.
To give you an example, I have a scenario as below.
First of all click “Add item” button in the below image and the light box appears:
Then fill in all the item details and click "Add & Close". You will see the screen below:
Notice that now there is an info message Your item ... has been added.
Now I put keywords in the Search text box and hit enter and the info message will be changed to below:
In my JUnit test, the flow is like below:
....
itemDetailsPage.clickAddAndClose();
itemDetailsPage.searchItemBy("Electricity");
assertEquals("Your search for 'electricity' returned 2 results.",
itemDetailsPage.getInfoMsg());
....
Now this test is not very robust, because if the network is slow, most of the times, getInfoMsg() will return the previous info message Your item ... has been added instead of the latest info message, which causes the test to fail. Just a side note that these two info message have share the same html element id.
The solution I am trying to implement here are:
add explicit wait in clickAddAndClose()
So it looks something like:
public void clickAddAndClose() {
...
clickWhenReady(driver, By.id(addAndCloseButtonId));
...
waitForElementByLocator(driver,By.id(itemInfoMsgId),10);
}
The second wait proves to be useless because, itemInfoMsgId already exist when the user added the item from the add item lightbox.
add waitForPageLoaded() method at the end of clickAddAndClose() to try to wait for the page to finish reloading. The generic method for waitForPageLoaded() below:
public void waitForPageLoaded(WebDriver driver) {
ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript(
"return document.readyState").equals("complete");
}
};
Wait<WebDriver> wait = new WebDriverWait(driver, 30);
try {
wait.until(expectation);
} catch (Throwable error) {
assertFalse("Timeout waiting for Page Load Request to complete.",
true);
}
}
I am expect at the end of clickAddAndClose(), it will see this page is still being updated so it will wait until the info message has been updated. But this does not seem to work either.
That leaves me to the last choice will is to add a thread sleep at the end of clickAddAndClose(). I want to avoid using it.
Is there a generic way of solving this kind of problem? How do I detect that the page DOM is still changing and tell Webdriver to wait until it finishes refreshing?
Waiting for the page to be loaded won't work if (as it seems to be the case) your page is being modified by AJAX operations.
Instead of waiting for the page to load, wait for the condition you are testing to become true. This way, you give the AJAX operation time to execute and if your there is a problem you will get an error when the time out occurs.
I usually use the Python bindings for Selenium and it has been quite a while since I wrote Java code but I believe it would look something like this, with X being replaced with a type appropriate for the itemDetailsPage object:
new FluentWait<X>(itemDetailsPage)
.until(new Function<X, Boolean>() {
public Boolean apply(X itemDetailsPage) {
return "Your search for 'electricity' returned 2 results." == itemDetailsPage.getInfoMsg();
};
});
Seems like you need to wait until ajax has finished its job. In a similar situation I've used a method similar to waitForJQueryProcessing described here. Take a look, it might help.
Let's say
I have a window 1. I have performed an event on the window 1 that makes window 2 to appear.
Now I switched to the window 2 and clicked a button on it which closes window 2.
If I use driver.close() after I performed an event which caused the window to close, sometimes it throws NoSuchWindowException.
If I don't use the driver.close() then sometimes driver.getWindowHandles().size() returns 2 even when there is only one window and I have waited enough time to number of windows become 1.
I refresh driver.getWindowHandles() and check for the driver.getWindowHandles().size() to become 1 but it doesn't sometimes.
My question is, do I need to use the method driver.close() after I clicked the button that caused the window to close? How to use the driver.close() correctly.
EDIT: Yes, it is a problem. If selenium doesn't realize window2 has been closed, it keeps returning the handles to be 2. Suppose that I closed window2 and switched back to window1 and performed an event which opens window3. Now I want to switch to window3. Here is the problem because Selenium still think windows2 exists and now there are three windows according to the Selenium.
String window1Handle = driver.getWindowHandle();
//Now I have oepend window3
//According to the Selenium there are 3 windows
// So driver.getWindowHandles().size() returns 3
for (String window : driver.getWindowHandles() {
if (!window.equals(window1Handle)) {
driver.switchTo().window();
The above line may throw exception because driver is trying to switch to a window which has already been closed"
No you don't need to perform a driver.close(), if anything is left open, when you perform a driver.quit() at the end of your test WebDriver will clean up and make sure that everything is shut down correctly.
Selenium can track how many windows are open, if you are seeing window handles for windows that are closed that sounds like a potential bug. Bear in mind that it may take some time for Selenium to realise that the window has been closed, you could try using an explicit wait to wait for the count of window handles to drop back down to 1, you'll need to add the following ExpectedCondition:
public static ExpectedCondition<Boolean> numberOfWindowsToBe(final int numberOfWindows) {
return new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver driver) {
return driver.getWindowHandles().size() == numberOfWindows;
}
};
}
Then you can use it by doing:
WebDriverWait wait = new WebDriverWait(driver, 15, 100);
wait.until(numberOfWindowsToBe(1));
or you could just try closing the window by performing a driver.close() and catching the NoSuchWindowException e.g.
try{
driver.close();
} catch(NoSuchWindowException ignored){
System.out.println("Window already closed");
}
This should give Selenium the kick it needs to realise that the window has been closed (Although to be honest I wouldn't bother).
*EDIT*
So it sounds like the problem is that you have multiple window handles and you don't know which one is the window that has been closed, and which one is your newly opened window. One workaround would be to track the window handles in a Map. Every time you open a new window store the window handle in the map like this:
Map<String, String> openedWindows = new HashMap<String, String>();
openedWindows.put("Window 1", driver.getWindowHandle());
You will then know which window handle is associated with your window, you can then remove windows from the map as they are closed. You will know which handles that are still being reported are actually closed and which are being reported in error.
Really this sounds like a bug in Selenium window handling and I would suggest you raise an issue on the issue tracker with a minimal test script that reproduces the problem. Of course the other option above is still valid, try and close the window but catch the exception and see if that gives Selenium the kick it needs to remove it from the list of window handles.
I had the same exact issue You are facing.
Before i perform an action which pops up second window, i intiated
String window = driver.getWindowHandle();
Later i clicked link 1 which populates window 2 and i switch to that window
driver.switchTo().window(window name);
i performed my action in Window 2 and when i click the link in Window 2 my window closes automatically and if i use driver.close() it wont happen as webdriver will throw error as u said
so instead of trying to close the second window, i try to switch back to window 1 with
driver.switchTo().window(window);
This is because since window 2 is closed automatically and since the control does not pass to window 1 the error will happen.. So there is no necessity to close window 2. instead we can switch back to our default window and continue or close the default window..
I know that this is a bit of a hack...but I've never seen something like what you are describing, so I think its worth a try. Change this code:
driver.switchTo().window();
to something like this:
try{
driver.switchTo().window();
perform action that will throw error
return; //will return if error wasn't thrown
catch(Error thrown if on bad window){
//continue in your for loop to switch to the next window;
}
I wrote a method that is working pretty good for me.
public static boolean letWebDriverRealizeThisWindowHasBeenClosed(WebDriver driver,
String closedWindowHandle) {
/**
* to avoid infinite loop, do write a break when definite time has been passed
*/
/**
* Generally, this method returns true given that window is closed
*/
boolean isWebDriverRealized = false;
long start = System.currentTimeMillis();
long end = start + (30 * 1000); //30 seconds
while (!isWebDriverRealized
&& System.currentTimeMillis() < end) {
try {
driver.switchTo().window(closedWindowHandle);
} catch (NoSuchWindowException nswe) {
isWebDriverRealized = true;
}
}
return isWebDriverRealized;
}
If this method returns true, then it means WebDriver has realized that window has been closed. driver.getWindowHandles.size() returns the correct number of windows once the above method returns true.
No, you don't need to do that. Because second window is already close, and if you will use method driver.close() it will close your first window and the browser itself(because there is only one tab left in browser window).
Its depends upon the Window,
some Window close while click on outside Window content, in that case no need of driver.close() method.
but for some Window, click on outside the Window content, Window unable to close (i.e. Window gets close after click on close button), in that case need to close such Window using thedriver.close() method.