Unclear about driver.getWindowHandles() & driver.getWindowHandle() - java

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.

Related

How to change window selenium java?

I'm trying to access iframe inside html tag.xpath is not working.How to change my window to iframe in selenium(java/maven)?
First you need to create driver object and after you can switch windows by id, name and WebElement.Then driver object has functions for switch back to default window.like this example.
// create driver object
WebDriver driver = DriverManager.getDriver();
// change window using iframe id or iframe name
driver.switchTo().frame("frame id or frame name");
// change window using WebElement object
driver.switchTo().frame(webElement);
Switch back window
// switch back to main frame
driver.switchTo().parentFrame();
// switch back one frame
driver.switchTo().defaultContent();
Content copy from (read this article) selenium window change article.Impotent information's here.
Right Click on HTML Page the search there for iframe.
Get the frame ID, Name or index.
pass one of the above parameters into following command
driver.switchTo.Frame(" ID or Name Or index");
then try to use your xpath.
You can use: deiver.switchTo Method with the element locator, you can find more with the following: https://www.guru99.com/handling-iframes-selenium.html
Basically, the question is to change window we have java inbuild methods.
1. get.windowhandle(): This method helps to get the window handle of the current window
2. get.windowhandles():This method helps to get the handles of all the windows opened. It stores all the current active windows into set..
so if you get all the window handle you can do is example:
code:
Set<String> setLink = driver.get.windowhandles();
now you can simply do the indexing and switch.
ex.
driver.get(setLink[2]);
3. Another method to switch is using keyBoardkeys
String clickl = Keys.chord(Keys.CONTROL,Keys.TAB);
String clickl = Keys.chord(Keys.CONTROL,Keys.(Index of window you like 1,2,3));
// open the link in new tab, Keys.Chord string passed to sendKeys
driver.findElement(
By.xpath("any xpath")).sendKeys(clickl);

Unable to switch back to parent window from child window which is closed automatically

I have problems when switching between two windows. The scenario looks like that:
I open the landing page of the application, then I click on login link, a pop-up window opens, I type the credentials then I click on login button (here the pop-up is automatically closed). After that I have to come back to original window, and proceed with other actions, since I have logged-in into the application.
The problem is that, it happens very often that I am not able to switch back to parent window, after pop-up is automatically closed, and the webdriver it just hanging, without doing anything, no error is thrown.
I have tried all kind of solutions found on google, but nothing really worked all the time.
Last piece of code that I tried is the one below:
getLandingPageObject().performClickOnEmailLink();
getDriver().manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
Iterator<String> it = handles.iterator();
// iterate through your windows
while (it.hasNext()) {
String parent = it.next();
String newwin = it.next();
getDriver().switchTo().window(newwin);
typeLoginCredentials(username, password);
performClickOnLoginButton();
Thread.sleep(5000);
getDriver().switchTo().window(parent);
}
}
loginShouldBeSuccessful();
I use Firefox 47.0.1 and Selenium 2.53.1
Any idea how could I fix this problem?
Thank you!
Before clicking on login link get the parent window
String parentWindowHandle = driver.getWindowHandle();
Switch to your new window after clicking the login link (this is just one of the approaches)
for (String handle : driver.getWindowHandles()) {
driver.switchTo().window(handle);
}
After finishing login, go back to your parent window
driver.switchTo().window(secondWinHandle);
There seems to be an issue with the logic used in the code. When you use:
Iterator it = handles.iterator();
the number of windows open is 2, so the conditional loop will be executed twice regardless of the the action performed within (I.e login and window closing automatically.
In the second iteration the parent window handle will be overwritten and the driver can't switch to it anymore.
In order to avoid this, you'll have to fetch and store your parent window handle either outside the loop or only once within. Code snippet with modification for the first solution is pasted below. Moving
String parent = it.next();
Outside the loop captures the parent window handle and retains the value.
Iterator<String> it = handles.iterator();
String parent = it.next();
// iterate through your windows
while (it.hasNext()) {
String newwin = it.next();
getDriver().switchTo().window(newwin);
typeLoginCredentials
(username,password);
performClickOnLoginButton();
Thread.sleep(5000);
}
getDriver().switchTo().window(newwin);
loginShouldBeSuccessful();

Selenium Java open new window, close it, and control main window again

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();

How to open two separate pop-up windows on click of two separate links?

I have below a javascript function which gets called on click of two separate links provided on a jsp file.
In brief, this functions opens a new popup window. What I want is when I click these two links two new pop up window should open.
But whats happening is this; I click on one link, it opens a new popup window but now I click on second link, it does not open the new popup window instead it is refreshing the old pop-up window (which opened on click of link1) with this link details.
I am not getting how to open two separate pop ups?
function showHelp(orgType) {
var pageLoc = '<%=helpURL%>bin/view/Main/?appSession=<%=request.getSession().getId()% >&securityToken=<%=appUtility.getSecurityToken(session
.getId(), login, custId)%>&appurl=<%=java.net.URLEncoder.encode((new java.net.URL(request.getScheme(),ip,request.getServerPort(), "")).toString() + request.getContextPath(), "ISO-8859-1")%>&custType='+custType+'&custName=<%=hostName%>';
self.open (pageLoc,'ServicePopUp','height=600,width=800,resizable=yes,scrollbars=yes,toolbar=yes,menubar=yes,location=yes');
}
You would need to provide a different name for each of the windows to differentiate them from each other:
function showHelp(orgType, windowName) {
...
self.open (pageLoc, windowName,'height=600,width=800,resizable=yes,scrollbars=yes,toolbar=yes,menubar=yes,location=yes');
}
See the extra parameter and where it fits into the open function? You'd need to provide 2 different names for the two links. Hope this helps!

Webdriver showModalDialog

We are using webdriver for our functional tests. But our application uses the showModalDialog JS function a lot to open a popup. When we try to test this functionality with webdriver it hangs from the moment the popup is opened.
We tried several things to test this:
Using the workaround explained here. But this seems to be a fix for selenium and not for webdriver. We tried it but it didn't work.
Searching for a good alternative, HtmlUnit opened the modal dialog and could interact with it, but it has it's drawbacks like no visual help to fix certain tests and it stopped execution when it detected a JS error in a JS library we have to use but have no control over.
How can we test this or work around this problem?
From my experiences with various automation tools interaction with "webpage dialog" windows opened from IE using window.showModalDialog() or window.showModelessDialog() is not available.
Since the window is not a "true" window (look at the taskbar, it doesn't even show up) most tools can't "inspect" it and/or interact with it.
However if you do find a tool that will, please advise - there are many people looking for such a beast.
That all said, if you can possibly avoid using either of these 2 proprietary methods you'll have much more luck.
(and yes, for the picky ones, Firefox and Chrome have adopted these kind of dialogs but they don't work quite the same)
None of the answers answer the question. If the driver hangs, then you can't call any methods on it. The question is NOT about finding the pop up, it is about how to stop the driver hanging. The only way I have found is to not use showModalDialog. This can be done by adding the folowing to your test code :
((JavascriptExecutor) driver).executeScript("window.showModalDialog = window.open;");
which calls window.open each time your JavaScript calls window.showModalDialog.
I am using webdriver.SwitchTo().Window() method but my concern is my popup window does not have "Name"
When I use webdriver.WindowHandles it return only one handle, I am using this statement after popup window open.
As I don't have name / handle I cannot switch from parent window to child window.
Any other solution to do the same functionality
First we have to switch to the active element:
driver.switchTo().activeElement();
To check whether we have actually switched to the correct active element:
driver.switchTo().activeElement().getText();
Even if the window doesn't have name u can use
driver.switchTo.defaultcontent();
and perform the operation you want to execute
or else you can get the window handle name using the below command
for (String handle : driver.getWindowHandles()) {
driver.switchTo().window(handle); }
hope this should work for you.
Issue 284 is for WebDriver. It seems that it will be implemented only after Issue 27 will be implemented, so the fix should be in Beta 1 or 2 of WebDriver.
Set<String> beforePopup = driver.getWindowHandles();
Set<String> afterPopup = driver.getWindowHandles();
afterPopup.removeAll(beforePopup);
if(afterPopup.size()==1){
System.out.println(afterPopup.toArray()[0]);
}
driver.switchTo().window((String) afterPopup.toArray()[0]);
What I have been using and it works great for us on with IE and Firefox is to go through popups
and look for a a unique text on the popup you are trying to interact with. Here is the method, let me know if it works for you. Please note the line driver = driver.switchTo().window(windowHandle);
public void switchWindow(String containingText, WebDriver driver) throws Exception {
if ( StringUtils.isEmpty(containingText))
return;
int counter = 1;
int numOfpopups = driver.getWindowHandles().size();
System.out.println("Waiting for popup to load..... # handles:" + numOfpopups);
while ( numOfpopups < 2 && ((counter%10) != 0) ) {
counter++;
try{Thread.sleep(1000);}catch (Exception e) {}
}
System.out.println("Done waiting for..... " + counter + " seconds");
if (driver.getWindowHandles().size() < 2)
throw new BrowserException("Timeout after " + counter + " secs. No popup present. ");
System.out.println("Going through window handles...");
for (String windowHandle : driver.getWindowHandles()) {
driver = driver.switchTo().window(windowHandle);
if ( driver.getPageSource().contains(containingText)
return;
else
continue;
}
throw new Exception("Window containing text '" + containingText + "' not found");
}
To my knowledge, webdriver has no built-in functionality to handle modal windows as of now. Webdriver will hang once you click button which opens modal window. This happens due to JS on parent window halts until child window is closed.
To handle modal windows such as this one, see below for possible workaround written in Java. The main idea is to perform action that opens modal window (click on the button) in new thread.
/**
* Click button to open modal window and switch to it
* #param we webElement handle of a button
*/
public void clickToOpenModal(final WebElement we) {
//Get handles of all opened windows before opening modal window
Set<String> initWindowHandles = getDriverInstance().getWindowHandles();
//Create new thread and click button to open window
Thread thread1 = new Thread() {
#Override
public void run() {
//Click button
click(we);
}
};
thread1.start();
//Wait for window to appear
waitForWindow(initWindowHandles, pauseL);
thread1.interrupt();
thread1 = null;
//Get handles of all opened windows after opening modal window
Iterator<String> it = getDriverInstance().getWindowHandles().iterator();
//Select handle of modal window
String windowHandle = "";
while(it.hasNext()){
windowHandle = it.next();
}
//Switch focus and work on the modal window
getDriverInstance().switchTo().window(windowHandle);
}
The solution by Hugh Foster works, i tried this and succeeded
((JavascriptExecutor) driver).executeScript("window.showModalDialog = window.open;");
You can find the url of modal dialog then open it on another tab, it will work as normal.
In case you want to deal with open modal dialog, you can try to send "tab" key for move around objects and "send keys... enter" for setText or click.
Note: Below is some information why you cannot use selenium webdriver for work with that modal.
Modal pop-up - This is very specific to IE, Microsoft defined it as
When Windows Internet Explorer opens a window from a modal or modeless HTML dialog box by using the showModalDialog method or by using the showModelessDialog method, Internet Explorer uses Component Object Model (COM) to create a new instance of the window. Typically, the window is opened by using the first instance of an existing Internet Explorer process. When Internet Explorer opens the window in a new process, all the memory cookies are no longer available, including the session ID. This process is different from the process that Internet Explorer uses to open a new window by using the open method.
http://msdn.microsoft.com/en-us/library/ms536759(VS.85).aspx
MSDN blog on Modal dialog
When user select Model popup, parent window is blocked waiting for the return value from the popup window. You will be not able to see the view source of the page, need to close the popup then only the parent window is activated.

Categories

Resources