firefoxdriver - Cambiar pestañas usando Selenium WebDriver con Java
selenium webdriver python (19)
Usando Selenium WebDriver con JAVA, estoy tratando de automatizar una funcionalidad donde tengo que abrir una nueva pestaña para hacer algunas operaciones allí y volver a la pestaña anterior (Parent). Usé la palanca del interruptor pero no funciona. Y una cosa extraña es que las dos pestañas tienen el mismo identificador de ventana, por lo que no puedo cambiar entre las pestañas.
Sin embargo, cuando intento con diferentes ventanas de Firefox funciona, pero para la pestaña no funciona.
Por favor, ayúdame, ¿cómo puedo cambiar las pestañas? O, ¿cómo puedo cambiar las pestañas sin usar el identificador de ventana, ya que el identificador de ventana es el mismo de ambas pestañas en mi caso?
(He observado que cuando abre pestañas diferentes en la misma ventana, el identificador de ventana permanece igual).
Como driver.window_handles
no está en orden, una mejor solución es esta.
primero cambie a la primera pestaña usando el atajo
Control + X
para cambiar a la pestaña "x" en la ventana del navegador.
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "1");
# goes to 1st tab
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "4");
# goes to 4th tab if its exists or goes to last tab.
Con Selenium 2.53.1 usando firefox 47.0.1 como WebDriver en Java: no importa cuántas pestañas abriera, "driver.getWindowHandles ()" solo devolvería un identificador por lo que era imposible cambiar entre pestañas.
Una vez que comencé a usar Chrome 51.0, pude obtener todos los identificadores. El siguiente código muestra cómo acceder a múltiples controladores y múltiples pestañas dentro de cada controlador.
// INITIALIZE TWO DRIVERS (THESE REPRESENT SEPARATE CHROME WINDOWS)
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> (driver1.getWindowHandles());
// NOW PERFORM DESIRED TASKS WITH FIRST BROWSER IN ANY TAB
for(int ii = 0; ii <= TAB_NUMBER; ii++) {
driver1.switchTo().window(tabs1.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
}
Con suerte, eso le da una buena idea de cómo manipular varias pestañas en varias ventanas del navegador.
El error con la respuesta seleccionada es que asume innecesariamente el orden en webDriver.getWindowHandles()
. El método getWindowHandles()
devuelve un Set
, que no garantiza el orden.
Usé el siguiente código para cambiar las pestañas, lo que no supone ninguna orden.
String currentTabHandle = driver.getWindowHandle();
String newTabHandle = driver.getWindowHandles()
.stream()
.filter(handle -> !handle.equals(currentTabHandle ))
.findFirst()
.get();
driver.switchTo().window(newTabHandle);
Es un proceso muy simple: supongamos que tiene dos pestañas, por lo que primero debe cerrar la pestaña actual utilizando client.window(callback)
porque el comando de cambio "cambia al primero disponible". Luego puede cambiar fácilmente la pestaña usando client.switchTab
.
Esta es una solución simple para abrir una pestaña nueva, cambiar el foco hacia ella, cerrar la pestaña y regresar el foco a la pestaña anterior / original:
@Test
public void testTabs() {
driver.get("https://business.twitter.com/start-advertising");
assertStartAdvertising();
// considering that there is only one tab opened in that point.
String oldTab = driver.getWindowHandle();
driver.findElement(By.linkText("Twitter Advertising Blog")).click();
ArrayList<String> newTab = new ArrayList<String>(driver.getWindowHandles());
newTab.remove(oldTab);
// change focus to new tab
driver.switchTo().window(newTab.get(0));
assertAdvertisingBlog();
// Do what you want here, you are in the new tab
driver.close();
// change focus back to old tab
driver.switchTo().window(oldTab);
assertStartAdvertising();
// Do what you want here, you are in the old tab
}
private void assertStartAdvertising() {
assertEquals("Start Advertising | Twitter for Business", driver.getTitle());
}
private void assertAdvertisingBlog() {
assertEquals("Twitter Advertising", driver.getTitle());
}
Esto funcionará para MacOS para Firefox y Chrome:
// opens the default browser tab with the first webpage
driver.get("the url 1");
thread.sleep(2000);
// opens the second tab
driver.findElement(By.cssSelector("Body")).sendKeys(Keys.COMMAND + "t");
driver.get("the url 2");
Thread.sleep(2000);
// comes back to the first tab
driver.findElement(By.cssSelector("Body")).sendKeys(Keys.COMMAND, Keys.SHIFT, "{");
Existe una diferencia en cómo el controlador web maneja diferentes ventanas y cómo maneja diferentes pestañas.
Caso 1:
En caso de que haya varias ventanas, entonces el siguiente código puede ayudar:
//Get the current window handle
String windowHandle = driver.getWindowHandle();
//Get the list of window handles
ArrayList tabs = new ArrayList (driver.getWindowHandles());
System.out.println(tabs.size());
//Use the list of window handles to switch between windows
driver.switchTo().window(tabs.get(0));
//Switch back to original window
driver.switchTo().window(mainWindowHandle);
Caso 2
En caso de que haya varias pestañas en la misma ventana, solo hay un identificador de ventana. Por lo tanto, el cambio entre manejadores de ventana mantiene el control en la misma pestaña.
En este caso, usar Ctrl + / t (Ctrl + Tab) para cambiar entre pestañas es más útil.
//Open a new tab using Ctrl + t
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"t");
//Switch between tabs using Ctrl + /t
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"/t");
El código de ejemplo detallado se puede encontrar aquí:
http://design-interviews.blogspot.com/2014/11/switching-between-tabs-in-same-browser-window.html
Lo primero que debe hacer es abrir una nueva pestaña y guardar su nombre de manejador. Lo mejor será hacerlo utilizando claves javascript y no (ctrl + t) ya que las claves no siempre están disponibles en los servidores de automatización. ejemplo:
public static String openNewTab(String url) {
executeJavaScript("window.parent = window.open(''parent'');");
ArrayList<String> tabs = new ArrayList<String>(bot.driver.getWindowHandles());
String handleName = tabs.get(1);
bot.driver.switchTo().window(handleName);
System.setProperty("current.window.handle", handleName);
bot.driver.get(url);
return handleName;
}
Lo segundo que debe hacer es cambiar entre las pestañas. Hacerlo solo con los manejadores de la ventana de cambio, no siempre funcionará, ya que la pestaña en la que trabajará no siempre estará enfocada y Selenium fallará de vez en cuando. Como dije, es un poco problemático usar claves, y javascript no es compatible con las pestañas de conmutación, así que utilicé alertas para cambiar pestañas y funcionó a las mil maravillas:
public static void switchTab(int tabNumber, String handleName) {
driver.switchTo().window(handleName);
System.setProperty("current.window.handle", handleName);
if (tabNumber==1)
executeJavaScript("alert(/"alert/");");
else
executeJavaScript("parent.alert(/"alert/");");
bot.wait(1000);
driver.switchTo().alert().accept();
}
Para obtener controladores de ventana principal.
String parentHandle = driverObj.getWindowHandle();
public String switchTab(String parentHandle){
String currentHandle ="";
Set<String> win = ts.getDriver().getWindowHandles();
Iterator<String> it = win.iterator();
if(win.size() > 1){
while(it.hasNext()){
String handle = it.next();
if (!handle.equalsIgnoreCase(parentHandle)){
ts.getDriver().switchTo().window(handle);
currentHandle = handle;
}
}
}
else{
System.out.println("Unable to switch");
}
return currentHandle;
}
Por favor ver más abajo:
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("https://www.irctc.co.in/");
String oldTab = driver.getWindowHandle();
//For opening window in New Tab
String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL,Keys.RETURN);
driver.findElement(By.linkText("Hotels & Lounge")).sendKeys(selectLinkOpeninNewTab);
// Perform Ctrl + Tab to focus on new Tab window
new Actions(driver).sendKeys(Keys.chord(Keys.CONTROL, Keys.TAB)).perform();
// Switch driver control to focused tab window
driver.switchTo().window(oldTab);
driver.findElement(By.id("textfield")).sendKeys("bangalore");
Espero que esto sea útil!
Recientemente tuve un problema, el enlace se abrió en una nueva pestaña, pero el selenio se centró aún en la pestaña inicial.
Estoy usando Chromedriver y la única forma de enfocarme en una pestaña era usar switch_to_window()
.
Aquí está el código de Python:
driver.switch_to_window(driver.window_handles[-1])
Así que la sugerencia es averiguar el nombre del identificador de ventana que necesita, se almacenan como una lista en
driver.window_handles
Respuesta simple que funcionó para mí:
for (String handle1 : driver1.getWindowHandles()) {
System.out.println(handle1);
driver1.switchTo().window(handle1);
}
Un breve ejemplo de cómo cambiar entre pestañas en un navegador (en el caso de una ventana):
// open the first tab
driver.get("https://www.google.com");
Thread.sleep(2000);
// open the second tab
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
driver.get("https://www.google.com");
Thread.sleep(2000);
// switch to the previous tab
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "" + Keys.SHIFT + "" + Keys.TAB);
Thread.sleep(2000);
Escribo Thread.sleep(2000)
solo para tener un tiempo de espera para ver el cambio entre las pestañas.
Puede usar CTRL + TAB para pasar a la siguiente pestaña y CTRL + MAYÚS + TAB para cambiar a la pestaña anterior.
clase pública TabBrowserDemo {
public static void main(String[] args) throws InterruptedException {
System.out.println("Main Started");
System.setProperty("webdriver.gecko.driver", "driver//geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://www.irctc.co.in/eticketing/userSignUp.jsf");
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.findElement(By.xpath("//a[text()=''Flights'']")).click();
waitForLoad(driver);
Set<String> ids = driver.getWindowHandles();
Iterator<String> iterator = ids.iterator();
String parentID = iterator.next();
System.out.println("Parent WIn id " + parentID);
String childID = iterator.next();
System.out.println("child win id " + childID);
driver.switchTo().window(childID);
List<WebElement> hyperlinks = driver.findElements(By.xpath("//a"));
System.out.println("Total links in tabbed browser " + hyperlinks.size());
Thread.sleep(3000);
// driver.close();
driver.switchTo().window(parentID);
List<WebElement> hyperlinksOfParent = driver.findElements(By.xpath("//a"));
System.out.println("Total links " + hyperlinksOfParent.size());
}
public static void waitForLoad(WebDriver driver) {
ExpectedCondition<Boolean> pageLoadCondition = new
ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
}
};
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(pageLoadCondition);
}
Trabajar alrededor
Suposición : Al hacer clic en algo en su página web, se abre una nueva pestaña.
Use la lógica de abajo para cambiar a la segunda pestaña.
new Actions(driver).sendKeys(driver.findElement(By.tagName("html")), Keys.CONTROL).sendKeys(driver.findElement(By.tagName("html")),Keys.NUMPAD2).build().perform();
De la misma manera, puedes volver a la primera pestaña de nuevo.
new Actions(driver).sendKeys(driver.findElement(By.tagName("html")), Keys.CONTROL).sendKeys(driver.findElement(By.tagName("html")),Keys.NUMPAD1).build().perform();
psdbComponent.clickDocumentLink();
ArrayList<String> tabs2 = new ArrayList<String> (driver.getWindowHandles());
driver.switchTo().window(tabs2.get(1));
driver.close();
driver.switchTo().window(tabs2.get(0));
Este código funcionó perfectamente para mí. Pruébalo. Siempre debe cambiar su controlador a una nueva pestaña, antes de que desee hacer algo en la nueva pestaña.
String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL, Keys.RETURN);
WebElement e = driver.findElement(By
.xpath("html/body/header/div/div[1]/nav/a"));
e.sendKeys(selectLinkOpeninNewTab);//to open the link in a current page in to the browsers new tab
e.sendKeys(Keys.CONTROL + "/t");//to move focus to next tab in same browser
try {
Thread.sleep(8000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//to wait some time in that tab
e.sendKeys(Keys.CONTROL + "/t");//to switch the focus to old tab again
Espero que te ayude ..
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL,Keys.SHIFT,Keys.TAB);
Este método ayuda a cambiar entre varias ventanas. El problema de restricción con este método es que solo se puede usar tantas veces hasta que se llegue a la ventana requerida. Espero eso ayude.
protected void switchTabsUsingPartOfUrl(String platform) {
String currentHandle = null;
try {
final Set<String> handles = driver.getWindowHandles();
if (handles.size() > 1) {
currentHandle = driver.getWindowHandle();
}
if (currentHandle != null) {
for (final String handle : handles) {
driver.switchTo().window(handle);
if (currentUrl().contains(platform) && !currentHandle.equals(handle)) {
break;
}
}
} else {
for (final String handle : handles) {
driver.switchTo().window(handle);
if (currentUrl().contains(platform)) {
break;
}
}
}
} catch (Exception e) {
System.out.println("Switching tabs failed");
}
}
Llame a este método y pase el parámetro una subcadena de la URL de la pestaña a la que desea cambiar