Selenium Webdriver cannot click on modal dialog when the window is not in focus - selenium

I have 2 browsers open and Selenium Webdriver can switch between these two. One window is in foreground and other is in background. And in the workflow, a modal dialog opens up in the background window and thus webdriver cannot perform any actions on it. Is there any possible solution apart from getting the background window into foreground?
I am using C#.

Loop through your window handles and check for you modal dialog to appear.
string current_window = driver.CurrentWindowHandle;
foreach (string window in driver.WindowHandles)
{
driver.SwitchTo().Window(window);
if (GetModal())
{
//do actions here
break;
}
}
driver.SwitchTo().Window(current_window); //To put you back where you started.
private bool GetModal()
{
Try
{
IWebElement modal = driver.FindElementByXPath("");
return true;
}
catch
{
return false;
}
}
Based on what you put this should work. If you can't find the modal then there is probably a different issue than just the window not being in focus. If you are worried about other errors then I would say catch only the specific error in the catch and let everything else float up ElementNotFound exception.

I am using below code
try{
//your code which will generate Modal Dialog
} catch (Exception e) {
if (e.getMessage().contains("Modal dialog present")) {//For Handling modal dialog in firefox
(new Robot()).keyPress(java.awt.event.KeyEvent.VK_ESCAPE);
(new Robot()).keyRelease(java.awt.event.KeyEvent.VK_ESCAPE);
}else if(e.getMessage().contains("unexpected alert open")){//For Handling modal dialog in chrome
driver.switchTo().alert().accept();
}
}

Related

Switch focus to reopened tab in Chrome - selenium

I am trying to achieve the below flow in selenium ,
click on a link to open new tab(child1) from parent window
close the driver (child1) after performing certain actions
Open the same link(child1) again to perform another set of actions
I am able to achieve the first two steps successfully by switching focus. But I am stuck at the third step where I am not able to focus on the same reopened tab. I get the below error,
org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
public class abc {
String currentWindow = driver.getWindowHandle();
public void action1() {
//Click on main menu that open a new tab
for (String handle : driver.getWindowHandles()) {
if (!handle.equals(currentWindow)) {
driver.switchTo().window(handle);
}
//Perform the actions
driver.close();
driver.switchTo().window(currentWindow);
}
public void action2(){
//Click on main menu which reopen the same tab
for (String handle : driver.getWindowHandles()) {
if (!handle.equalsIgnoreCase(currentWindow)) {
System.out.println("Port Response : switch focus");
driver.switchTo().window(handle);
break;
}
}
//perform a set of actions
driver.close();
driver.switchTo().window(currentWindow);
}
}//end of abc
I want to create the actions more like a reusable independent action so I would like to close all tabs and reopen them again for other set of action. Please let me know if you need any more details on this.

Issue on Windows Authentication pop up

Currently i am working on a project, where i am facing Windows Authentication Pop up. To handle this pop up I am using Robot class.It is working fine also. But my main problem is that, the same pop up comes again and again dynamically. How can i control this? Can anyone please help me in this regards? I have written below code to control one Windows Pop up.
StringSelection username = new StringSelection("Username");
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(username, null);
rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_CONTROL);
//tab to password entry field
rb.keyPress(KeyEvent.VK_TAB);
rb.keyRelease(KeyEvent.VK_TAB);
Thread.sleep(2000);
//Enter password by ctrl-v
StringSelection pwd = new StringSelection("Password");
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(pwd, null);
rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_CONTROL);
//press enter
rb.keyPress(KeyEvent.VK_ENTER);
rb.keyRelease(KeyEvent.VK_ENTER);
}
You can create/modify the method isAlertPresent as given below and try it. It may help you.
First confirm with below method if the alert present
public boolean isAlertPresent() {
try{
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.alertIsPresent());
return true;
}
catch (NoAlertPresentException noAlert) {
return false;
}
catch (TimeoutException timeOutEx){
return false;
}
}
It's an authentication pop-up. You can handle it like below :-
WebDriverWait wait = new WebDriverWait(driver, 10);
Alert alert = wait.until(ExpectedConditions.alertIsPresent());
alert.authenticateUsing(new UserAndPassword(username, password));
OR
driver.get("http://UserName:Password#Example.com");
OR
If above not work then JavascriptExecutor worked for you. Just take care that you should execute it before clicking the event which invoke alert.
((JavascriptExecutor) driver).executeScript("window.confirm = function(msg) { return true; }");
Note :- do not use it after clicking on event which invoke alert confirmation box. Above code by default set the confirmation box as true means you are accepting/click on ok on all confirmation box on that page if invoked
Hope it will help you :)

Selenium : Handle a window that popups up randomly

We have a feature that collects customer feedback. For this , when the user logs out , a window pops up up randomly - not every time for every customer.
I want to handle this in my automation code.
Currently, at the log out, I'm expecting a window and switching to it and that code is failing when the popup window doesn't show up.
What's the best way to handle this .
This is what I have so far ...
public static void waitForNumberOfWindowsToEqual(final int numberOfWindows) {
ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return (driver.getWindowHandles().size() == numberOfWindows);
}
};
WebDriverWait wait = new WebDriverWait(driver, BrowserFactory.explicitWait);
wait.until(expectation);
}
I would handle the absence of popup window with a try/catch. Here is an example:
try {
WebDriverWait winwait = new WebDriverWait(driver, 3);
String mainWindow = driver.getWindowHandle();
// wait for 2 windows and get the handles
Set<String> handles = winwait.until((WebDriver drv) -> {
Set<String> items = drv.getWindowHandles();
return items.size() == 2 ? items : null;
});
// set the context on the last opened window
handles.remove(mainWindow);
driver.switchTo().window(handles.iterator().next());
// close the window
driver.close();
// set the context back to the main window
driver.switchTo().window(mainWindow);
} catch (TimeoutException ex) {
System.out.println("No window present within 3 seconds");
}
If possible, the ideal thing to do would be to have a look through the source to work out whether the popup window will appear, however if this isn't achievable you could take the following approach:
// Get the number of windows open before clicking the log out button.
int numberOfWindowsBeforeLogOut = driver.getWindowHandles().size();
// Click the log out button.
logOutButton.click();
// Check how many windows are open after clicking the log out button.
int numberOfWindowsAfterLogOut = driver.getWindowHandles().size();
// Now compare the number of windows before and after clicking the log out
// button in a condition statement.
if (numberOfWindowsBeforeLogOut < numberOfWindowsAfterLogOut) {
// If there is a new window available, switch to it.
driver.switchTo().window(titleOrWindowHandle);
}
In case you don't get the required window, the code will throw a TimeoutException. So, put wait.until(expectation) inside a try block and catch the exception. In code,
try {
wait.until(expectation);
} catch (TimeoutException ex) {
System.out.println("Nowindow This Time");
}

selenium remote driver: cannot accept alert on window close- Window not found exception

I have a window popup , as soon as i click on the submit button the popup window closes and a javascript alert appears.
I have been getting : window not found exception in the logs.
If the window would not closed ,selenium is able to identify the alert but since the popup has closed I get the above exception.
I have tried using $driver->switch_to_window after clicking the submit button but that doesn't handle the alert.
Any thoughts is greatly appreciated.
Are you using the alert functionality with Selenium?
public void checkAlert() {
try {
WebDriverWait wait = new WebDriverWait(driver, 2);
wait.until(ExpectedConditions.alertIsPresent());
Alert alert = driver.switchTo().alert();
alert.accept();
} catch (Exception e) {
//exception handling
}
}

How can selenium web driver get to know when the new window has opened and then resume its execution

I am facing an issue in automating a web application using selenium web driver.
The webpage has a button which when clicked opens a new window. When I use the following code, it throws OpenQA.Selenium.NoSuchWindowException: No window found
WebDriver.FindElement(By.Id("id of the button that opens new window")).Click();
//Switch to new window
_WebDriver.SwitchTo().Window("new window name");
//Click on button present on the newly opened window
_WebDriver.FindElement(By.Id("id of button present on newly opened window")).Click();
To solve the above issue I add Thread.Sleep(50000); between the button click and SwitchTo statements.
WebDriver.FindElement(By.Id("id of the button that opens new window")).Click();
Thread.Sleep(50000); //wait
//Switch to new window
_WebDriver.SwitchTo().Window("new window name");
//Click on button present on the newly opened window
_WebDriver.FindElement(By.Id("id of button present on newly opened window")).Click();
It solved the issue, but I do not want to use the Thread.Sleep(50000); statement because if the window takes more time to open, code can fail and if window opens quickly then it makes the test slow unnecessarily.
Is there any way to know when the window has opened and then the test can resume its execution?
You need to switch the control to pop-up window before doing any operations in it. By using this you can solve your problem.
Before opening the popup window get the handle of main window and save it.
String mwh=driver.getWindowHandle();
Now try to open the popup window by performing some action:
driver.findElement(By.xpath("")).click();
Set s=driver.getWindowHandles(); //this method will gives you the handles of all opened windows
Iterator ite=s.iterator();
while(ite.hasNext())
{
String popupHandle=ite.next().toString();
if(!popupHandle.contains(mwh))
{
driver.switchTo().window(popupHandle);
/**/here you can perform operation in pop-up window**
//After finished your operation in pop-up just select the main window again
driver.switchTo().window(mwh);
}
}
You could wait until the operation succeeds e.g., in Python:
from selenium.common.exceptions import NoSuchWindowException
from selenium.webdriver.support.ui import WebDriverWait
def found_window(name):
def predicate(driver):
try: driver.switch_to_window(name)
except NoSuchWindowException:
return False
else:
return True # found window
return predicate
driver.find_element_by_id("id of the button that opens new window").click()
WebDriverWait(driver, timeout=50).until(found_window("new window name"))
WebDriverWait(driver, timeout=10).until( # wait until the button is available
lambda x: x.find_element_by_id("id of button present on newly opened window"))\
.click()
I finally found the answer,
I used the below method to switch to the new window,
public String switchwindow(String object, String data){
try {
String winHandleBefore = driver.getWindowHandle();
for(String winHandle : driver.getWindowHandles()){
driver.switchTo().window(winHandle);
}
}catch(Exception e){
return Constants.KEYWORD_FAIL+ "Unable to Switch Window" + e.getMessage();
}
return Constants.KEYWORD_PASS;
}
To move to parent window, i used the following code,
public String switchwindowback(String object, String data){
try {
String winHandleBefore = driver.getWindowHandle();
driver.close();
//Switch back to original browser (first window)
driver.switchTo().window(winHandleBefore);
//continue with original browser (first window)
}catch(Exception e){
return Constants.KEYWORD_FAIL+ "Unable to Switch to main window" + e.getMessage();
}
return Constants.KEYWORD_PASS;
}
I think this will help u to switch between the windows.
I use this to wait for window to be opened and it works for me.
C# code:
public static void WaitUntilNewWindowIsOpened(this RemoteWebDriver driver, int expectedNumberOfWindows, int maxRetryCount = 100)
{
int returnValue;
bool boolReturnValue;
for (var i = 0; i < maxRetryCount; Thread.Sleep(100), i++)
{
returnValue = driver.WindowHandles.Count;
boolReturnValue = (returnValue == expectedNumberOfWindows ? true : false);
if (boolReturnValue)
{
return;
}
}
//try one last time to check for window
returnValue = driver.WindowHandles.Count;
boolReturnValue = (returnValue == expectedNumberOfWindows ? true : false);
if (!boolReturnValue)
{
throw new ApplicationException("New window did not open.");
}
}
And then i call this method in the code
Extensions.WaitUntilNewWindowIsOpened(driver, 2);
You can wait for another window to pop using WebDriverWait.
First you have to save current handles of all opened windows:
private Set<String> windowHandlersSet = driver.getWindowHandles();
Then you click a button to open a new window and wait for it to pop with:
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(driver -> !driver.getWindowHandles().equals(windowHandlersSet));
Which checks if there is a change to current window handles set comparing to saved one. I used this solutnion writing tests under Internet Explorer where it always takes few seconds to open new window.
WebDriverWait wait = new WebDriverWait(driver,Duration.ofSeconds(max duration you want it to check for new window));
wait.until(ExpectedConditions.numberOfWindowsToBe(2));//here 2 represents the current window and the new window to be opened
Although this question already has answers, none of them was useful to me really since I can't rely on getting any new window, I needed to filter even more, so I started using Dadoh's solution but tweaked it until I came up with this solution, hope it will be of some use to someone.
public async Task<string> WaitUntilNewWindowIsOpen(string expectedWindowTitle, bool switchToWindow, int maxRetryCount = 100)
{
string newWindowHandle = await Task.Run(() =>
{
string previousWindowHandle = _driver.CurrentWindowHandle;
int retries = 0;
while (retries < maxRetryCount)
{
foreach (string handle in _driver.WindowHandles)
{
_driver.SwitchTo().Window(handle);
string title = _driver.Title;
if (title.Equals(expectedWindowTitle))
{
if(!switchToWindow)
_driver.SwitchTo().Window(previousWindowHandle);
return handle;
}
}
retries++;
Thread.Sleep(100);
}
return string.Empty;
});
return newWindowHandle;
}
So in this solution I opted to pass the expected window title as an argument for the function to loop all windows and compare the new window title, this way, it's guaranteed to return the correct window. Here is an example call to this method:
await WaitUntilNewWindowIsOpen("newWindowTitle", true);
Below function can wait for given max time until your new window is open
public static void waitForWindow(int max_sec_toWait, int noOfExpectedWindow) {
FluentWait<WebDriver> wait = new FluentWait<WebDriver>(driver);
wait.pollingEvery(Duration.ofMillis(200));
wait.withTimeout(Duration.ofSeconds(max_sec_toWait));
wait.ignoring(NoSuchWindowException.class);
Function<WebDriver, Boolean> function = new Function<WebDriver, Boolean>(){
#Override
public Boolean apply(WebDriver driver) {
Set<String> handel = driver.getWindowHandles();
if(handel.size() == noOfExpectedWindow)
return true;
else
return false;
}
};
wait.until(function);
}
Js code
await firstPage.clickOnLink();
let tabs = await driver.getAllWindowHandles();
await driver.switchTo().window(tabs[1]);
await driver.wait(await until.titleContains('myString'), 2000);