This question already has an answer here:
Best way to keep track and iterate through tabs and windows using WindowHandles using Selenium
(1 answer)
Closed 2 years ago.
Im wokring on a tool development that tests various services on Chrome browser. For each service I would need to launch a new tab on Chrome. I use the below code,
The first 2 new tabs works fine, when the 3rd tab is launched, the 1st tab's url is navigated to the one used for 3rd tab.
Not sure what's messing up. Need assistance!
I believe when your loop enters second iteration, your if statement executes to true.
You can just do following:
for(String actual: handles){
driver.switchTo().window(actual);
}
After execution of the above loop, your script will always point to last window opened.
Then you can do:
driver.get(URL + service + URL_);
outside the loop.
P.S.: If required, for more enhancement you can use below script:
private void switchToLatestBrowserWindow(WebDriver driver, Set<String> priorHandles)
{
new WebDriverWait(driver, 60).until( // keep trying to switch for 60 seconds
d -> {
Set<String> newHandles = d.getWindowHandles();
if (newHandles.size() != priorHandles.size()) {
log.Info("NewHandles Size not equal to PriorHandles size.");
String lastWindowHandle = "";
for (String windowHandle : newHandles) {
lastWindowHandle = windowHandle;
}
log.Info("LastWindowHandle Id: " + lastWindowHandle);
d.switchTo().window(lastWindowHandle);
log.Info("Switched window to " + lastWindowHandle);
return true;
} else {
return false;
}
});
}
priorHandles is set of window handles retrieved before opening new window. (the first line of code, in your case). So complete snippet would look like:
Set<String> priorHandles = driver.getWindowHandles();
((JavasriptExecutor) driver).executeScript( script: "window.open()");
switchToLatestBrowserWindow(driver, priorHandles);
driver.get(URL + service + URL_);
Related
I have automated some actions in JMeter webdriver sampler, in a scenario I am moving to new window, but I am not able to close the newly opened window in that.
WDS.browser.close() does not work there. How can I close only the new window and work with parent?
Thanks in advance.
You could do something like:
var handles = WDS.browser.getWindowHandles()
var iterator = handles.iterator()
var currentHandle = WDS.browser.getWindowHandle()
while(iterator.hasNext()) {
var handle = iterator.next()
if (handle != currentHandle) {
WDS.browser.switchTo().window(handle)
WDS.browser.close()
}
}
WDS.browser.switchTo().defaultContent()
References:
How To Work with Multiple Windows
The WebDriver Sampler: Your Top 10 Questions Answered
What I do (in python though) is switch handles, close the current window, then switch back. Perhaps it can serve as inspiration for you problem :
def close_additional_tabs(self):
self.cfg.logger.info("[TEARDOWN] Close open tabs and switch to original frame.")
while len(self.webdriver.window_handles) > 1:
self.webdriver.switch_to_window(self.webdriver.window_handles[-1])
self.webdriver.close()
time.sleep(1)
self.webdriver.switch_to_window(self.webdriver.window_handles[-1])
This is for tabs but it works with windows as well.
I have the following in my code:
withWindow({ title == 'Google' }) {
report "08"
}
And report is leading me to the exception NoSuchWindowException. I've checked if that was a problem of the Window selector and it isn't,After some research I guessed that the problem was that the driver got messed in the way so I stored and switched my driver:
String mainHandle= driver.getWindowHandle();
driver.switchTo().window('Google');
But I kept getting the same error. So I tried:
driver.get("http://www.google.com");
And it is working but I need to do this dinamycally and automatically because the windows and popups that we are working with are hundreds and with different titles.
How can I achieve that in every windows that opens? We are generating the code with a external tool so I don't need to do "magic", only a driver.get.windowUrl or something like this will work for me, I will add the concurrence later.
If you want to get the last window handle that is opened, you can do something like this:
public String getLastWindowHandle() {
Set<String> windows = webDriver.getWindowHandles();
Iterator<String> itera = windows.iterator();
String window = null;
while (itera.hasNext()) {
window = itera.next();
}
return window;
}
with this handle, you can switch to the new window:
webDriver.switchTo().window(getLastWindowHandle());
I'm using driver.getWindowHandle() for switching between windows. This is working fine in Chrome but in Firefox after clicking on the button that opens the new window, the execution doesn't continue, neither stops. How can I resolve it?
Edit :- Code shared in comment -
String parentWindow = driver.getWindowHandle();
driver.findElement(By.id("mybutton")).click();
Set<String> handles = driver.getWindowHandles();
Code:
String parentWindow = driver.getWindowHandle();
driver.findElement(By.id("myButton")).click();
Set<String> handles = driver.getWindowHandles();
for (String windowHandle : handles) {
if (!windowHandle.equals(parentWindow)) {
driver.switchTo().window(windowHandle);
//call methods
}
}
driver.switchTo().window(parentWindow); // cntrl to parent window
With Selenium 2.53.1 using firefox 47.0.1 as the WebDriver in Java: You need to open the separate windows/browsers in it's own driver. I have having the same problem. No matter how many windows or tabs I opened, "driver.getWindowHandles()" would only return one handle so it was impossible to switch between tabs. I found Chrome worked way better for me.
Once I started using Chrome 51.0, I could get all handles. The following code show how to access multiple drivers and multiple tabs within each driver.
// INITIALIZE TWO DRIVERS (THESE REPRESENT SEPARATE CHROME WINDOWS/BROWSERS)
driver1 = new ChromeDriver();
driver2 = new ChromeDriver();
// LOOP TO OPEN AS MANY TABS AS YOU WISH
for(int i = 0; i < TAB_NUMBER; i++) {
driver1.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
// SLEEP FOR SPLIT SECOND TO ALLOW DRIVER TIME TO OPEN TAB
Thread.sleep(100);
// STORE TAB HANDLES IN ARRAY LIST FOR EASY ACCESS
ArrayList tabs1 = new ArrayList<String> (driver1.getWindowHandles());
// REPEAT FOR THE SECOND DRIVER (SECOND CHROME BROWSER WINDOW)
// LOOP TO OPEN AS MANY TABS AS YOU WISH
for(int i = 0; i < TAB_NUMBER; i++) {
driver2.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
// SLEEP FOR SPLIT SECOND TO ALLOW DRIVER TIME TO OPEN TAB
Thread.sleep(100);
// STORE TAB HANDLES IN ARRAY LIST FOR EASY ACCESS
ArrayList tabs2 = new ArrayList<String> (driver2.getWindowHandles());
// NOW PERFORM DESIRED TASKS WITH FIRST BROWSER IN ANY TAB
for(int ii = 0; ii <= TAB_NUMBER; ii++) {
driver2.switchTo().window(tabs2.get(ii));
// LOGIC FOR THAT DRIVER'S CURRENT TAB
}
// PERFORM DESIRED TASKS WITH SECOND BROWSER IN ANY TAB
for(int ii = 0; ii <= TAB_NUMBER; ii++) {
drvier2.switchTo().window(tabs2.get(ii));
// LOGIC FOR THAT DRIVER'S CURRENT TAB
}
Hopefully that gives you a good idea of how to manipulate multiple tabs in multiple browser windows.
Trying to switch to new window tab and then selecting a item from dropdown list is not working..
public static void handleNewTabWindow() {
driver.findElement(By.xpath(".//img[#src='/images/buttons/gl_upload.gif']")).click();
String Parent_Window = driver.getWindowHandle();
for (String Child_Window : driver.getWindowHandles()) {
driver.switchTo().window(Child_Window);
WebElement dropdown = getWhenVisible(By.xpath(".//select[#name='UPLOAD_ORG_ID']"));
dropdown.click();
getWhenVisible(By.xpath(".//option[contains(text(), 'CI Borrower')]")).click();
}
driver.switchTo().window(Parent_Window);
driver.close();
}
You must wait until a new window will appear on the screen before switching to it. Your code is trying to switch immediately after clicking on the button, in a couple of miliseconds - the browser is not so quick, you must wait a couple of seconds or so.
A not very elegant, but a quick solution is to introduce a fixed Thread.sleep( 2000 ); here:
driver.findElement(By.xpath(".//img[#src='/images/buttons/gl_upload.gif']")).click();
Thread.sleep( 2000 );
String Parent_Window = driver.getWindowHandle();
but this doesn't work very well.
A better solution is to implement a method that will wait until a new window appears on the screen (but no longer than some fixed timeout - for example 30-60 seconds). For example one of the most used method in our project is a method that waits for a window with a given title, something like this (code skeleton):
void waitForWindowWithTitleAndSwitchToIt( String windowTitle, int timeoutInSeconds ){
....
while( timeout-not-expired ){
handles = driver.getWindowHandles():
for( String handle: handles ){
driver.switchTo.window( handle );
if( driver.getTitle().contains( windowTitle ) ){
// found a window with a given title
return;
}
}
sleep( for a 1-2 seconds );
// and try again
}
throw new TimeoutException(
String.format("A browser window named %s doesn't appear on the screen", windowTitle )
);
}
We have implemented a couple of such methods in our project, which wait for a new window using different criteria: wait for window with a given exact title, for a window which a title that contains a given substring, for a window with a given string in the page source, for a window with a given (sub)string in the url, etc. etc.
I'm facing this issue since some days now but didn't manage to overcome it trying different ideas.
Problem description: I wanna select a line in a table (GWT CellTable), perform some actions (which are my application specific) on it and then unselect back the line.
The line never gets unselected.
I'm quite new to selenium And I don't know if someone else has run into same problem and if there is a workaround to it. Thanks in advance
Code:
#Test
#SuppressWarnings("serial")
public void testClearEventCodes(){
refreshBrowser();
testWEHSearch();
WebContext faresContext = rootContext.gotoId(Strings.WEH_FARES_TABLE);
//INITIALLY HOT AND EVENT FARE
assertTrue("Y N N N N".equals(faresContext.gotoTableCell(1, 15).getText()));
assertTrue("CHINAYEAR".equals(faresContext.gotoTableCell(1, 16).getText()));
checkColorCodes(new HashMap<String, String[]>(){
{
put(getFareKey("GMP", "PAR", "KE", "0004", "K001", "OW", "Public"), new String[]{"1", COLOR_CODE_HOT_AND_EVENT_FARE});
}
});
faresContext.gotoTableRow(1).getElementWebContext(1).click();
rootContext.gotoId(Strings.WEH_CLEAR_EVENT_CODES_BUTTON).click();
faresContext.gotoTableRow(1).getElementWebContext(1).ctrlClick();
//ENSURE ALL EVENT CODES ARE CLEARED
assertTrue("".equals(faresContext.gotoTableCell(1, 16).getText()));
checkColorCodes(new HashMap<String, String[]>(){
{
put(getFareKey("GMP", "PAR", "KE", "0004", "K001", "OW", "Public"), new String[]{"1", COLOR_CODE_HOT_FARE});
}
});
}
And bellow is the method to CTRL CLICK the line:
/**
* Holds Control key and Clicks on current element.
*/
public void ctrlClick() {
Actions actionBuilder = new Actions(driver);
actionBuilder.keyDown(Keys.CONTROL).click(getSingleElement()).keyUp(Keys.CONTROL);
org.openqa.selenium.interactions.Action action = actionBuilder.build();
action.perform();
}
Your problem might be related to the new Firefox feature in which display settings are now taken into account. You can try changing the display settings for your computer to 100% and try again.
https://code.google.com/p/selenium/issues/detail?id=6774