¿Cómo cambiar a la nueva ventana del navegador, que se abre después de hacer clic en el botón?

86

Tengo una situación, al hacer clic en el botón se abre la nueva ventana del navegador con los resultados de la búsqueda.

¿Hay alguna forma de conectarse y enfocarse en la nueva ventana del navegador abierta?

Y trabaje con él, luego regrese a la (primera) ventana original.

Volodymyr Prysiazhniuk
fuente
Podemos hacer el cambio automáticamente - verifique aquí el uso avanzado - testautomationguru.com/…
vins

Respuestas:

117

Puede cambiar entre ventanas de la siguiente manera:

// Store the current window handle
String winHandleBefore = driver.getWindowHandle();

// Perform the click operation that opens new window

// Switch to new window opened
for(String winHandle : driver.getWindowHandles()){
    driver.switchTo().window(winHandle);
}

// Perform the actions on new window

// Close the new window, if that window no more required
driver.close();

// Switch back to original browser (first window)
driver.switchTo().window(winHandleBefore);

// Continue with original browser (first window)
Surya
fuente
3
Puedo confirmar que la solución aceptada funciona constantemente en Chrome pero no en IE. El nuevo identificador de ventana no se reconoce en IE. @Elmue es incorrecto porque getWindowHandles()devuelve un conjunto y un conjunto no garantiza el pedido . El último elemento no siempre es la última ventana. Me sorprende que su comentario reciba muchos votos a favor.
plata
@silver: No tengo idea de qué estás hablando. En mi código, WindowHandles devuelve una ReadOnlyCollection <string> para la cual puedo garantizar que la última entrada es siempre la última ventana abierta. Probé eso. Si esto funciona perfectamente en C #, pero está implementado incorrectamente en Java, debe informarlo como un error.
Elmue
@Elmue Este es un hilo de Java. Lea la respuesta de Luke (desarrollador de Selenium) al respecto getWindowHandles(). Es un comportamiento conocido (no un error) del método y del Java Set <T> en particular. Por lo tanto, switchTo().window(handles[handles.length-1])no está garantizado en Java. No se puede afirmar que la solución AC # sea correcta.
plata
5
@Elmue Por tercera (y última) vez, su respuesta es falsa para Java, ya que es compatible con documentos y desarrolladores que pueden ENGAÑAR a las personas. Publique una respuesta donde diga que es para C #, no hay problema. Levante una tarjeta de problema en GitHub para Java, adelante. Simplemente su respuesta no es aplicable para el idioma TAGGED en el hilo y la gente puede pensar lo contrario. Si no puede hacer la distinción, falta su comprensión.
plateado
3
@Elmue Por cierto, también te equivocas al decir que driver.close () cierra ambas ventanas. Solo cierra la corriente. driver.quit () mata todas las instancias. Veo que alguien ya te ha señalado esto. Tu comentario está lleno de errores. Tenga un buen día.
plateado
12

Solo para agregar al contenido ...

Para volver a la ventana principal (ventana predeterminada).

utilizar driver.switchTo().defaultContent();

Amarnath Rayudu
fuente
11

Este script le ayuda a cambiar de una ventana principal a una ventana secundaria y volver cntrl a la ventana principal

String parentWindow = driver.getWindowHandle();
Set<String> handles =  driver.getWindowHandles();
   for(String windowHandle  : handles)
       {
       if(!windowHandle.equals(parentWindow))
          {
          driver.switchTo().window(windowHandle);
         <!--Perform your operation here for new window-->
         driver.close(); //closing child window
         driver.switchTo().window(parentWindow); //cntrl to parent window
          }
       }
Prashanth Sams
fuente
1
driver.close () funcionará para una nueva ventana. Si es una pestaña nueva, use el código para cerrar la pestaña nueva: driver.findElement (By.cssSelector ("cuerpo")). SendKeys (Keys.CONTROL + "w");
Ripon Al Wasim
4

Surya, tu camino no funcionará por dos razones:

  1. no puede cerrar el controlador durante la evaluación de la prueba, ya que perderá el enfoque , antes de cambiar al elemento activo, y obtendrá NoSuchWindowException.
  2. Si la prueba se ejecuta en ChromeDriver, no obtendrá una ventana, sino una pestaña al hacer clic en su aplicación. Como SeleniumDriver no puede actuar con pestañas , solo cambia entre ventanas, se cuelga al hacer clic donde se abre la nueva pestaña y se bloquea en el tiempo de espera.
Invy
fuente
1
De hecho, puede usar la llamada a driver.close () ya que está cambiando las manijas de las ventanas en el controlador y solicitando que se cierre la ventana en la que está actualmente. Lo uso regularmente en mi código cuando trato con múltiples ventanas. driver.Quit () es la llamada que terminará la prueba. En Chromedriver aún puede llamar a getWindowHandles () para obtener su lista de ventanas disponibles. No puedo pensar en una razón para usar una pestaña en una prueba web.
Ben
@Elmue La pregunta original decía que un clic abre una segunda ventana creando múltiples identificadores de ventana. Puedo hacer la llamada driver.close (); y cerrar mi ventana que actualmente tiene el foco. Luego puedo cambiar a cualquier otra ventana activa de mi elección. driver.close () y driver.quit () no comparten la misma funcionalidad. Una llamada a driver.quit () matará la instancia del controlador activo, mientras que cerrar solo matará el identificador de ventana actual. Además, todavía no he visto ninguna llamada que solo abra una pestaña después de que se llame a un clic cuando el javascript en el sitio web crea una nueva ventana.
Ben
Me equivoqué y borré mi comentario. También puedes borrar tu respuesta.
Elmue
3

Modificar el registro para IE:

ie_x64_tabprocgrowth.png

  1. HKEY_CURRENT_USER \ Software \ Microsoft \ Internet Explorer \ Main
  2. Haga clic derecho → Nuevo → Valor de cadena → Nombre del valor: TabProcGrowth (crear si no existe)
  3. TabProcGrowth (clic derecho) → Modificar ... → Información del valor: 0

Fuente: Problema de cambio de ventanas de Selenium WebDriver en Internet Explorer 8-10

En mi caso, IE comenzó a detectar nuevos identificadores de ventana después de la edición del registro.

Tomado del blog de MSDN:

Crecimiento del proceso de pestaña: establece la velocidad a la que IE crea procesos de pestaña nueva.

El algoritmo "Número máximo": Especifica el número máximo de procesos de tabulación que se pueden ejecutar para una sola sesión de aislamiento para un proceso de una sola trama en un nivel de integridad obligatorio específico (MIC). Los valores relativos son:

  • TabProcGrowth = 0: las pestañas y los marcos se ejecutan dentro del mismo proceso; los fotogramas no están unificados en todos los niveles de MIC.
  • TabProcGrowth = 1: todas las pestañas de un proceso de marco determinado se ejecutan en un proceso de pestaña única para un nivel MIC determinado.

Fuente: Abrir una pestaña nueva puede iniciar un proceso nuevo con Internet Explorer 8.0


Opciones de Internet:

  • Seguridad → Desmarque Habilitar modo protegido para todas las zonas (Internet, Intranet local, Sitios de confianza, Sitios restringidos)
  • Avanzado → Seguridad → Desmarque Habilitar modo protegido mejorado

Código:

Navegador: IE11 x64 (Zoom: 100%)
SO: Windows 7 x64
Selenium: 3.5.1
WebDriver: IEDriverServer x64 3.5.1

public static String openWindow(WebDriver driver, By by) throws IOException {
String parentHandle = driver.getWindowHandle(); // Save parent window
WebElement clickableElement = driver.findElement(by);
clickableElement.click(); // Open child window
WebDriverWait wait = new WebDriverWait(driver, 10); // Timeout in 10s
boolean isChildWindowOpen = wait.until(ExpectedConditions.numberOfWindowsToBe(2));
if (isChildWindowOpen) {
    Set<String> handles = driver.getWindowHandles();
    // Switch to child window
    for (String handle : handles) {
        driver.switchTo().window(handle);
        if (!parentHandle.equals(handle)) {
            break;
        }
    }
    driver.manage().window().maximize();
}
return parentHandle; // Returns parent window if need to switch back
}



/* How to use method */
String parentHandle = Selenium.openWindow(driver, by);

// Do things in child window
driver.close();

// Return to parent window
driver.switchTo().window(parentHandle);

El código anterior incluye un if-check para asegurarse de que no está cambiando a la ventana principal, ya que Set<T>no tiene un orden garantizado en Java .WebDriverWaitparece aumentar las posibilidades de éxito según lo respaldado por la siguiente declaración.

Citado de Luke Inman-Semerau : (Desarrollador de Selenium)

Es posible que el navegador tarde un poco en reconocer la nueva ventana y es posible que usted esté cayendo en el bucle switchTo () antes de que aparezca la ventana emergente.

Automáticamente asume que la última ventana devuelta por getWindowHandles () será la última abierta. Eso no es necesariamente cierto, ya que no se garantiza que se devuelvan en ningún orden.

Fuente: No se puede manejar una ventana emergente en IE, el control no se transfiere a la ventana emergente


Artículos Relacionados:

plata
fuente
2

Podrías usar:

driver.SwitchTo().Window(WindowName);

Donde WindowName es una cadena que representa el nombre de la ventana a la que desea cambiar el enfoque. Vuelva a llamar a esta función con el nombre de la ventana original para volver a ella cuando haya terminado.

Breeze91
fuente
1
gracias por la sugerencia, ¿hay alguna forma de cómo puedo configurar la máscara del nombre de la ventana? Como "WinName *", donde * - cualquier símbolo.
Volodymyr Prysiazhniuk
1
Mi implícitamente es de 10 segundos, pero en 2 segundos me da la excepción NoSuchWindowException.
Volodymyr Prysiazhniuk
2

Utilizo un iterador y un bucle while para almacenar los distintos identificadores de ventana y luego alternar entre uno y otro.

//Click your link
driver.findElement(By.xpath("xpath")).click();
//Get all the window handles in a set
Set <String> handles =driver.getWindowHandles();
Iterator<String> it = handles.iterator();
//iterate through your windows
while (it.hasNext()){
String parent = it.next();
String newwin = it.next();
driver.switchTo().window(newwin);
//perform actions on new window
driver.close();
driver.switchTo().window(parent);
            }
Status quo
fuente
No puede cambiar a nuevas pestañas, sin embargo, realiza clics en la nueva pestaña deseada. ¿Por qué?
paul
¿Hay alguna razón por la que este código pueda hacer que la prueba se vuelva muy lenta? Parece que después de este fragmento de código se necesitan unos 10 minutos para realizar cualquier acción en el newwin
Hugo
0
 main you can do :

 String mainTab = page.goToNewTab ();
 //do what you want
 page.backToMainPage(mainTab);  

 What you need to have in order to use the main   

        private static Set<String> windows;

            //get all open windows 
            //return current window
            public String initWindows() {
                windows = new HashSet<String>();
                driver.getWindowHandles().stream().forEach(n ->   windows.add(n));
                return driver.getWindowHandle();
            }

            public String getNewWindow() {
                List<String> newWindow = driver.getWindowHandles().stream().filter(n -> windows.contains(n) == false)
                        .collect(Collectors.toList());
                logger.info(newWindow.get(0));
                return newWindow.get(0);
            }


            public String goToNewTab() {
                String startWindow = driver.initWindows();
                driver.findElement(By.cssSelector("XX")).click();
                String newWindow = driver.getNewWindow();
                driver.switchTo().window(newWindow);
                return startWindow;
            }

            public void backToMainPage(String startWindow) {
                driver.close();
                driver.switchTo().window(startWindow);
            }
Ran Adler
fuente
0

Entonces, el problema con muchas de estas soluciones es que está asumiendo que la ventana aparece instantáneamente (nada sucede instantáneamente y las cosas suceden significativamente menos instantáneamente en IE). También está asumiendo que solo habrá una ventana antes de hacer clic en el elemento, lo que no siempre es el caso. Además, IE no devolverá los identificadores de ventana en un orden predecible. Entonces haría lo siguiente.

 public String clickAndSwitchWindow(WebElement elementToClick, Duration 
    timeToWaitForWindowToAppear) {
    Set<String> priorHandles = _driver.getWindowHandles();

    elementToClick.click();
    try {
        new WebDriverWait(_driver,
                timeToWaitForWindowToAppear.getSeconds()).until(
                d -> {
                    Set<String> newHandles = d.getWindowHandles();
                    if (newHandles.size() > priorHandles.size()) {
                        for (String newHandle : newHandles) {
                            if (!priorHandles.contains(newHandle)) {
                                d.switchTo().window(newHandle);
                                return true;
                            }
                        }
                        return false;
                    } else {
                        return false;
                    }

                });
    } catch (Exception e) {
        Logging.log_AndFail("Encountered error while switching to new window after clicking element " + elementToClick.toString()
                + " seeing error: \n" + e.getMessage());
    }

    return _driver.getWindowHandle();
}
Dominic Giallombardo
fuente
-1

Si tiene más de un navegador (usando java 8)

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class TestLink {

  private static Set<String> windows;

  public static void main(String[] args) {

    WebDriver driver = new FirefoxDriver();
    driver.get("file:///C:/Users/radler/Desktop/myLink.html");
    setWindows(driver);
    driver.findElement(By.xpath("//body/a")).click();
    // get new window
    String newWindow = getWindow(driver);
    driver.switchTo().window(newWindow);

    // Perform the actions on new window
    String text = driver.findElement(By.cssSelector(".active")).getText();
    System.out.println(text);

    driver.close();
    // Switch back
    driver.switchTo().window(windows.iterator().next());


    driver.findElement(By.xpath("//body/a")).click();

  }

  private static void setWindows(WebDriver driver) {
    windows = new HashSet<String>();
    driver.getWindowHandles().stream().forEach(n -> windows.add(n));
  }

  private static String getWindow(WebDriver driver) {
    List<String> newWindow = driver.getWindowHandles().stream()
        .filter(n -> windows.contains(n) == false).collect(Collectors.toList());
    System.out.println(newWindow.get(0));
    return newWindow.get(0);
  }

}
Ran Adler
fuente