I find my question to be different than everything that I've searched for because I need to open a new window in my code (not from clicking a link in a UI). So i already have a driver handling my only window, and then I do this:
//save the handle of the current (only) window open right now
String MainWindowHandle = driver.getWindowHandle();
//open a new firefox window
driver = new FirefoxDriver();
//in the new window, go to the intended page
driver.navigate().to(foo);
//do some stuff in the pop up window..
//close the popup window now
driver.close();
//switch back to the main window. This is where the error is thrown
driver.switchTo().window(MainWindowHandle);
The error is: "org.openqa.selenium.remote.UnreachableBrowserException: Error communicating with the remote browser. It may have died"
What do I need to do to regain control of the initial window?
Thanks in advance.
You don't. If you need to launch a new instance of the browser (which is what this sounds like), then do that.
// "url" is an unused variable, simply included here to demonstrate
// that the driver variable is valid and capable of being used.
String url = driver.getCurrentUrl();
// Open a new Firefox window
// Note that here, in your original code, you've set the
// driver variable to another instance of Firefox, which
// means you've orphaned the original browser.
WebDriver driver2 = new FirefoxDriver();
// In the new window, go to the intended page
driver2.navigate().to(foo);
// Do some stuff in the pop up window..
// Close the popup window now
driver2.quit();
// No need to switch back to the main window; driver is still valid.
// Remember that "url" is simply a dummy variable used here to
// demonstrate that the initial driver is still valid.
url = driver.getCurrentUrl();
Related
Hi all I am learning Selenium & I am not really clear about how the above two functions work:
Problem Statement:
I have a practice assignment say: Go to http://the-internet.herokuapp.com/
Click on a link> Multiple Windows A Window opens> Click on>> Click Here Another Window opens>> from this window grab text and print it After that go back to this http://the-internet.herokuapp.com/windows and print text.
Flow: http://the-internet.herokuapp.com/>>>http://the-internet.herokuapp.com/windows>>>http://the-internet.herokuapp.com/windows/new
Que1) If I use driver.getWindowHandle() and print it for each window its value remains constant so does this method always returns the parent window or it works differently.
Ques2) When I use driver.getWindowHandles() it is returning 2 values in the set. Does driver.getWindowHandles() return the parent window as well. (I am not sure if there should be 2 or 3 values as I have 3 URLS I thought the set should have 3)
Ques3) Can someone share the most effective way to work with multiple child window id's:
Set with iterator method
People also convert Set to Arraylist and then use get method. [which is a better way]
Code:
driver.get("http://the-internet.herokuapp.com/");
String p1=driver.getWindowHandle();
System.out.println(p1);
text1=driver.findElement(By.xpath("//a[#href='/windows']"));
text1.click();
WebElement
text2=driver.findElement(By.xpath("//a[#href='/windows/new']"));
text2.click();
Set<String> child=driver.getWindowHandles();
System.out.println(child.size());
ArrayList<String> children=new ArrayList<String>(child);
System.out.println(children);
driver.switchTo().window(children.get(1));
System.out.println(driver.findElement(By.xpath("//div[#class='example']/h3")).getText());
driver.close();
driver.switchTo().window(children.get(0));
System.out.println(driver.findElement(By.xpath("//div[#class='example']/h3")).getText());
driver.switchTo().window("");
System.out.println(driver.getCurrentUrl());
driver.close();
driver.get("http://the-internet.herokuapp.com/");
String p1=driver.getWindowHandle(); //Gets the newly opened and the only window handle
System.out.println("This is parent window handle " + p1);
text1=driver.findElement(By.xpath("//a[#href='/windows']"));
text1.click(); //Navigates, no new window opened. Handle remains the same
//WebElement 'Unnecessary code
text2=driver.findElement(By.xpath("//a[#href='/windows/new']"));
text2.click(); //opens second window/tab as per the settings. there are 2 window handles here for current driver instance
Set<String> child=driver.getWindowHandles(); //set of 2
System.out.println(child.size());
// ArrayList<String> children=new ArrayList<String>(child);' modifying this
String strSecondWindowHandle = "";
for(String str : s) // as set is not an ordered collection we need to loop through it to know which position holds which handle.
{
if(str.equalsIgnoreCase(p1) == false) //to check if the window handle is not equal to parent window handle
{
driver.switchTo().window(str) // this is how you switch to second window
strSecondWindowHandle = str;
break;
}
}
// System.out.println(children);
// driver.switchTo().window(children.get(1)); //not required
System.out.println(driver.findElement(By.xpath("//div[#class='example']/h3")).getText());
driver.close(); // now this will close the second window
driver.switchTo().window(p1); // switches to main window
System.out.println(driver.findElement(By.xpath("//div[#class='example']/h3")).getText());
// driver.switchTo().window(""); //not required as it is the same window
System.out.println(driver.getCurrentUrl());
driver.close(); //closes the main window
So to answer your questions
Window handle is automatically and uniquely assigned by the operating system (Windows) to each newly opened window
Q1 --> Until and unless you explicityly switch the windows, the window handle remains the same. switching is the key here.
Q2 --> Navigating does not change the handles. it is not page specific rather it is window specific. getWindowHandles will return all the open browser windows opened by WebDriver instances that is currently running. Already open windows are not included.
Q3 --> Using the for loop demonstrated above, you open the window, find the ID which is not your parent window handle, store it in a variable. Repeat the procedure for more windows.
You can see in the documentation what are the main differences between getWindowHandle() and getWindowHandles() methods:
getWindowHandle(): Return an opaque handle to this window that uniquely identifies it within this driver instance.
getWindowHandles(): Return a set of window handles which can be used to iterate over all open windows of this WebDriver instance by passing them to switchTo().WebDriver.Options.window()
In simpler terms, driver.getWindowHandles() stores the set of handles for all the pages opened simultaneously, but driver.getWindowHandle() fetches the handle of the web page which is in focus. It gets the address of the active browser and it has a return type of String.
I am checking whether or not a page appears using Selenium. When I click the page, however, a printer print prompt appears (like the window that says select printer and such). How can I have Selenium close this window by hitting cancel?
I tried looking to alerts, but it seems like those will not work since the print window is a system prompt. It does not recognize any alerts appearing.
The most recent I tried using is by just sending keys like tab and enter in order to have the cancel button selected, however, it doesn't recognize any keys as being pressed.
How can I handle this case?
public static boolean printButton() throws Exception {
WebDriver driver = new FirefoxDriver();
driver.get("website");
try {
Thread.sleep(3000);
WebElement temp = driver.findElement(By.xpath("//*[#id='block-print-ui-print-links']/div/span/a"));
temp.click();
Actions action = new Actions(driver);
action.sendKeys(Keys.TAB).sendKeys(Keys.ENTER);
Thread.sleep(6000);
}
catch (Exception e) {
System.out.println("No button.");
driver.close();
return false;
}
I would simply disable the print dialog by overriding the print method :
((JavascriptExecutor)driver).executeScript("window.print=function(){};");
But if you goal is to test that the printing is called then :
// get the print button
WebElement print_button = driver.findElement(By.cssSelector("..."));
// click on the print button and wait for print to be called
driver.manage().timeouts().setScriptTimeout(20, TimeUnit.SECONDS);
((JavascriptExecutor)driver).executeAsyncScript(
"var callback = arguments[1];" +
"window.print = function(){callback();};" +
"arguments[0].click();"
, print_button);
If you are going for testing only Chrome browser here is mine solution. Because of 'Robot' class or disabling print didn't work for my case.
// Choosing the second window which is the print dialog.
// Switching to opened window of print dialog.
driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
// Runs javascript code for cancelling print operation.
// This code only executes for Chrome browsers.
JavascriptExecutor executor = (JavascriptExecutor) driver.getWebDriver();
executor.executeScript("document.getElementsByClassName('cancel')[0].click();");
// Switches to main window after print dialog operation.
driver.switchTo().window(driver.getWindowHandles().toArray()[0].toString());
Edit: In Chrome 71 this doesn't seem to work anymore since the script can't find the Cancel button. I could make it work by changing the line to:
executor.executeScript("document.querySelector(\"print-preview-app\").shadowRoot.querySelector(\"print-preview-header\").shadowRoot.querySelector(\"paper-button.cancel-button\").click();");
Actually you can't handle windows (OS) dialogs inside Selenium WebDriver.
This what the selenium team answers here
The current team position is that the print dialog is out of scope for
the project. WebDriver/Selenium is focused on emulating a user's
interaction with the rendered content of a web page. Other aspects of
the browser including, but not limited to print dialogs, save dialogs,
and browser chrome, are all out of scope.
You can try different approach like AutoIt
we can also use key for handling the print or press the cancel button operation. and it works for me.
driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
WebElement webElement = driver.findElement(By.tagName("body"));
webElement.sendKeys(Keys.TAB);
webElement.sendKeys(Keys.ENTER);
driver.switchTo().window(driver.getWindowHandles().toArray()[0].toString());
Native window based dialog can be handled by AutoItX as described in the following code
File file = new File("lib", jacobDllVersionToUse);
System.setProperty(LibraryLoader.JACOB_DLL_PATH, file.getAbsolutePath());
WebDriver driver = new FirefoxDriver();
driver.get("http://www.joecolantonio.com/SeleniumTestPage.html");
WebElement printButton = driver.findElement(By.id("printButton"));
printButton.click();
AutoItX x = new AutoItX();
x.winActivate("Print");
x.winWaitActive("Print");
x.controlClick("Print", "", "1058");
x.ControlSetText("Print", "", "1153", "50");
Thread.sleep(3000); //This was added just so you could see that the values did change.
x.controlClick("Print", "", "2");
Reference : http://www.joecolantonio.com/2014/07/21/selenium-how-to-handle-windows-based-dialogs-and-pop-ups/
Sometimes 2 different statements as above (webElement.sendKeys(Keys.TAB)
webElement.sendKeys(Keys.ENTER)) will not work, you can use with combination of Tab and Enter keys as below, This will close the Print preview window.
Using C# :
Driver.SwitchTo().Window(Driver.WindowHandles[1]);
IWebElement element = Driver.FindElement(By.TagName("body"));
element.SendKeys(Keys.Tab + Keys.Enter);
Driver.SwitchTo().Window(Driver.WindowHandles[0]);
Erçin Akçay answer updated.
// Choosing the second window which is the print dialog.
// Switching to opened window of print dialog.
driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
// Runs javascript code for cancelling print operation.
// This code only executes for Chrome browsers.
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("document.querySelector(\"body > print-preview-app\").shadowRoot.querySelector(\"#sidebar\").shadowRoot.querySelector(\"print-preview-button-strip\").shadowRoot.querySelector(\"div > cr-button.cancel-button\").click();");
// Switches to main window after print dialog operation.
driver.switchTo().window(driver.getWindowHandles().toArray()[0].toString());
I need some help for the following issue using Webdriver, Java, and Firefox.
In the testing, when clicking on a link,
1) it will often open a new window with a normal web page. OR
2) occasionally, it will open a new window with “about:blank” in address bar; after 20 to 60 seconds the new window will disappear and a file download window will appear.
Because the URL is rewritten for SEO, there is no way to check the URL before or after clicking on the link to determine whether the link connects to a normal web page or a downloadable file.
In both cases,
driver.getWindowHandles().size() == 2,
so I can switch to the new window successfully using the following statements in order to check whether a certain WebElement exists in new window.
for (String winHandle : driver.getWindowHandles()) {
driver.switchTo().window(winHandle);
}
But if the link connects to a downloadable file, the execution will hang for any of the following methods:
findElement(By.xpath(“//html”));
findElements(By.tagName(“body”));
getCurrentUrl();
getPageSource();
getTitle();
getWindowHandle();
getWindowHandles() always returns 2 while new window with “about:blank” in address bar presents before it is replaced by the file download dialog. It occasionally throws a NoSuchWindowException exception; but most of the time, it just hangs. I tried the Explicit and Implicit Waits to no avail.
Many thanks
Sam
Have you tried setting the following preference? (This will get rid of the download dialog all together)
FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("browser.download.manager.showWhenStarting",false);
FirefoxDriver driver = new FirefoxDriver(profile);
I run my selenium rc test in Eclipse with TestNG. I have a link which tries to open a new browser page. How can I select this new page to operate in? I use this code:
selenium.selectWindow("name=NewPage");
however it says page not found. I also try to define page ids or titles with this code:
String[] wins = selenium.getAllWindowIds();
for (String s : wins)
System.out.println("win: " + s);
It does not define my new opened window:
win: MainPage
win:
If use selenium.getAllWindowNames() I get win: selenium_main_app_window
win: selenium_blank65815.
I write this code selenium.selectWindow("name=blank99157"); but get the error - ERROR: Window does not exist. If this looks like a Selenium bug, make sure to read http://seleniumhq.org/docs/02_selenium_ide.html#alerts-popups-and-multiple-windows for potential workarounds.
The window obviously has no name, so you can't select it by name.
If the window is opened via JavaScript and you can change the script, try changing window.open("someUrl"); to window.open("someUrl", "someName");, you'll be then able to select the window by the set name. More information on the MDN doc for window.open().
Selenium RC doesn't support <a href="someUrl" target="_blank"> links (which open the link in a new window). Therefore, if the window is opened by a link of this type, you have to find this <a> element, get the href attribute and call
selenium.openWindow(theFoundUrl, "theNewWindow");
selenium.selectWindow("id=theNewWindow");
If it is opened via JavaScript before or during the onload event, you'll need to call
selenium.openWindow("", "theNewWindow");
selenium.selectWindow("id=theNewWindow");
More information on this in the bug SEL-339 or in the openWindow() and selectWindow() JavaDocs.
If you have only two windows / want to open the newest one, you can try
selenium.selectPopup()
That is, obviously, the easiest way, because it selects the first non-top window. Therefore, it's only useful when you want to select the newest popup.
If the new window has a unique title, you can do
selenium.selectPopup("Title of the window");
or selenium.selectWindow("title=Title of the window");
Otherwise, you must iterate over selenium.getAllWindowNames() to get the right name (Selenium creates names for windows without one). However, you can't hardcode that name into your testcase, because it will change every time, so you'll need to work out some dynamic logic for this.
You won't like this: Go for WebDriver. It should be far more resistant to such problems.
WebDriver driver = new FirefoxDriver();
WebElement inputhandler = driver.findelement(By.linktext("whatever here"));
inputhandler.click();
String parentHandle = driver.getWindowHandle();
Set<String> PopHandle = driver.getWindowHandles();
Iterator<String> it = PopHandle.iterator();
String ChildHandle = "";
while(it.hasNext())
{
if (it.next() != parentHandle)
{
ChildHandle = it.next().toString();
// because the new window will be the last one opened
}
}
driver.switchTo().window(ChildHandle);
WebDriverWait wait1 = new WebDriverWait(driver,30);
wait1.until(ExpectedConditions.visibilityOfElementLocated(By.id("something on page")));
// do whatever you want to do in the page here
driver.close();
driver.switchTo().window(parentHandle);
You might not be using the correct window ID.
Check out this link. You might find your answer here.
Let me know you this helps.
Try selenium.getAllWindowNames(), selenium.getAllWindowTitles()..one of them will work for sure.
Using Selenium Webdriver 2. java.
I would like to switch back in forth between two firefox browser windows. When I do I get: org.openqa.selenium.NoSuchWindoException: Unable to loacate window"{accb1cc2-74c9-3b4e-8f71-c0b184a037c4}"; duration or timeout:
Here is the java:
driver = new FirefoxDriver();
driver.get("http://mail.google.com");
String firstWindowHandle = driver.getWindowHandle();
System.out.println("handle of first window ="+firstWindowHandle);
Thread.sleep(1000);
driver = new FirefoxDriver();
driver.get("http://www.google.com");
// Get names of currently open windows
String secondWindowHandle = driver.getWindowHandle();
System.out.println("handle of first window ="+secondWindowHandle);
Thread.sleep(1000);
// It fails right here!
driver.switchTo().window(firstWindowHandle );
driver.get("http://www.lifehacker.com");
It prints the following to the console:
- handle of first window = {accb1cc2-74c9-3b4e-8f71-c0b184a037c4}
- handle of the second window = {f5256619-a36e-a441-9979-937da0abacd1}
All help is appreciated.
Unfortunately, you cannot switch between windows the way you are currently trying to do it - WebDriver lost the first window as soon as you instantiated a new instance.
You could try opening the second window via javascript and then switching back and forth from it:
window.open('http://www.bing.com','Bing','modal=yes,alwaysRaised=yes')
This is a bit of a hack, and could have the following problems:
Popup blockers may prevent the action
The browser must have javascript enabled
Future browser versions may break the hack
Complaining and murmuring from peers (and perhaps rightly so) because even though it might work, it's still a hack ;)
Some final thoughts:
Is there any particular reason it has to be the same driver instance?
If not, just switch between two driver instances:
FirefoxDriver driver = new FirefoxDriver();
driver.get("http://mail.google.com");
FirefoxDriver driver2 = new FirefoxDriver();
driver2.get("http://www.google.com");
Swtiching between 2 active Windows:
FirefoxDriver wd=new FirefoxDriver();
wd.get("https://irctc.co.in/");
wd.manage().timeouts().implicitlyWait(5000,TimeUnit.SECONDS);
WebElement wb=wd.findElement(By.linkText("Cabs"));
wb.click(); //Now 2 Windows are open
wd.manage().timeouts().implicitlyWait(5000,TimeUnit.SECONDS); //Wait for the complete page to load
Set<String> sid=wd.getWindowHandles(); //getWindowHandles() method returns the ids of all active Windows and its return type will be a Collection Set.
Iterator<String> it=sid.iterator(); //Using iterator we can fetch the values from Set.
String parentId=it.next();
System.out.println(parentId);
String childId=it.next();
System.out.println(childId);
wd.switchTo().window(childId); //swtiching control to child Window
wd.close(); //control returns to the parent Window.