Come passare alla nuova finestra del browser, che si apre dopo aver fatto clic sul pulsante?


86

Ho una situazione, quando si fa clic sul pulsante si apre la nuova finestra del browser con i risultati della ricerca.

C'è un modo per connettersi e concentrarsi sulla nuova finestra del browser aperta?

E lavoraci, quindi torna alla (prima) finestra originale.


Possiamo eseguire il passaggio automaticamente - controlla qui per l'utilizzo avanzato - testautomationguru.com/…
vins

Risposte:


118

Puoi passare da una finestra all'altra come di seguito:

// 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)

4
Posso confermare che la soluzione accettata funziona costantemente in Chrome ma non in IE. Il nuovo handle di finestra non viene riconosciuto in IE. @Elmue non è corretto perché getWindowHandles()restituisce un Set e un Set non garantisce l'ordinazione . L'ultimo elemento non è sempre l'ultima finestra. Sono sorpreso che il suo commento riceva molti voti positivi.
argento

@ argento: non ho idea di cosa stai parlando. Nel mio codice WindowHandles restituisce un ReadOnlyCollection <string> per il quale posso garantire che l'ultima voce è sempre l'ultima finestra aperta. L'ho provato. Se funziona perfettamente in C #, ma è implementato in modo errato in Java, dovresti segnalarlo come un bug.
Elmue

1
@Elmue Questo è un thread Java. Si prega di leggere Luke (sviluppatore Selenium) risposta di merito a getWindowHandles(). È un comportamento noto (non bug) del metodo e in particolare di Java Set <T>. Pertanto, switchTo().window(handles[handles.length-1])non è garantito in Java. Non si può affermare che la soluzione AC # sia corretta.
argento

6
@Elmue Per la terza (e ultima) volta, la tua risposta è falsa per Java in quanto supportato da docs e dev che possono INGANNARE le persone. Pubblica una risposta in cui dici che è per C #, nessun problema. Solleva una scheda problema in GitHub per Java, vai avanti. Semplicemente la tua risposta non è applicabile per la lingua TAGGED nel thread e le persone potrebbero pensare diversamente. Se non puoi fare la distinzione, la tua comprensione manca.
argento

3
@Elmue A proposito, hai anche torto nel dire che driver.close () chiude entrambe le finestre. Chiude solo la corrente. driver.quit () uccide tutte le istanze. Vedo che qualcuno te l'ha già fatto notare. Il tuo commento è pieno di errori. Buona giornata.
argento

12

Solo per aggiungere al contenuto ...

Per tornare alla finestra principale (finestra predefinita).

uso driver.switchTo().defaultContent();


11

Questo script ti aiuta a passare da una finestra padre a una finestra figlia e tornare indietro cntrl alla finestra padre

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
          }
       }

1
driver.close () funzionerà per la nuova finestra. Se è una nuova scheda, utilizzare il codice per chiudere la nuova scheda: driver.findElement (By.cssSelector ("body")). SendKeys (Keys.CONTROL + "w");
Ripon Al Wasim,

4

Surya, la tua strada non funzionerà, per due motivi:

  1. non è possibile chiudere il driver durante la valutazione del test poiché perderà la concentrazione , prima di passare all'elemento attivo, e si otterrà NoSuchWindowException.
  2. se i test vengono eseguiti su ChromeDriver non otterrai una finestra, ma una scheda al clic nella tua applicazione. Poiché SeleniumDriver non può agire con le schede , passa solo da una finestra all'altra, si blocca al clic nel punto in cui si apre la nuova scheda e si arresta in modo anomalo al timeout.

1
Puoi effettivamente usare la chiamata per driver.close () poiché stai cambiando gli handle della finestra sul driver e stai chiamando la finestra che stai attualmente chiudendo. Lo uso regolarmente nel mio codice quando si tratta di più finestre. driver.Quit () è la chiamata che ucciderà il test. In Chromedriver puoi ancora chiamare getWindowHandles () per ottenere l'elenco delle finestre disponibili. Non riesco a pensare a un motivo per utilizzare una scheda in un test web.
Ben

@Elmue La domanda originale affermava che un clic apre una seconda finestra creando più maniglie della finestra. Posso fare la chiamata driver.close (); e chiudere la finestra che attualmente è attiva. Posso quindi passare a qualsiasi altra finestra attiva di mia scelta. driver.close () e driver.quit () non condividono la stessa funzionalità. Una chiamata per driver.quit () ucciderà l'istanza del driver attivo mentre close ucciderà solo l'handle della finestra corrente. Inoltre, devo ancora vedere alcuna chiamata che apre una scheda solo dopo che viene chiamato un clic quando il javascript sul sito Web crea una nuova finestra.
Ben

Ho sbagliato e ho cancellato il mio commento. Puoi anche eliminare la tua risposta.
Elmue

3

Modifica registro per IE:

ie_x64_tabprocgrowth.png

  1. HKEY_CURRENT_USER \ Software \ Microsoft \ Internet Explorer \ Main
  2. Fare clic con il pulsante destro del mouse → Nuovo → Valore stringa → Nome valore: TabProcGrowth (crea se non esiste)
  3. TabProcGrowth (clic destro) → Modifica ... → Dati valore: 0

Fonte: problema con il cambio di finestre di Selenium WebDriver in Internet Explorer 8-10

Nel mio caso, IE ha iniziato a rilevare nuovi handle di finestra dopo la modifica del registro.

Tratto dal blog MSDN:

Crescita processo scheda: imposta la velocità con cui IE crea processi Nuova scheda.

L'algoritmo "Max-Number": specifica il numero massimo di processi di tabulazione che possono essere eseguiti per una singola sessione di isolamento per un singolo processo frame a uno specifico livello di integrità obbligatoria (MIC). I valori relativi sono:

  • TabProcGrowth = 0: schede e frame vengono eseguiti all'interno dello stesso processo; i frame non sono unificati tra i livelli MIC.
  • TabProcGrowth = 1: tutte le schede per un determinato processo di frame vengono eseguite in un unico processo di scheda per un dato livello MIC.

Origine: l' apertura di una nuova scheda potrebbe avviare un nuovo processo con Internet Explorer 8.0


Opzioni Internet:

  • Sicurezza → Deseleziona Abilita modalità protetta per tutte le zone (Internet, Intranet locale, Siti attendibili, Siti con restrizioni)
  • Avanzate → Sicurezza → Deseleziona Abilita modalità protetta avanzata

Codice:

Browser: IE11 x64 (Zoom: 100%) Sistema
operativo: 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);

Il codice sopra include un controllo if per assicurarsi di non passare alla finestra principale poiché Set<T>non ha alcun ordine garantito in Java .WebDriverWaitsembra aumentare le possibilità di successo come sostenuto dalla dichiarazione di seguito.

Citato da Luke Inman-Semerau : (Developer for Selenium)

Il browser potrebbe impiegare del tempo per riconoscere la nuova finestra e potresti cadere nel ciclo switchTo () prima che venga visualizzata la finestra popup.

Si presume automaticamente che l'ultima finestra restituita da getWindowHandles () sarà l'ultima aperta. Non è necessariamente vero, poiché non è garantito che vengano restituiti in qualsiasi ordine.

Origine: impossibile gestire un popup in IE, il controllo non viene trasferito alla finestra popup


Post correlati:


2

Potresti usare:

driver.SwitchTo().Window(WindowName);

Dove WindowName è una stringa che rappresenta il nome della finestra a cui si desidera attivare lo stato attivo. Chiama di nuovo questa funzione con il nome della finestra originale per tornare ad essa quando hai finito.


1
grazie per il suggerimento, c'è un modo, come posso impostare la maschera del nome della finestra? Come "WinName *", dove * - qualsiasi simbolo.
Volodymyr Prysiazhniuk

1
Il mio implicitamente è di 10 secondi, ma in 2 secondi mi dà l'eccezione NoSuchWindowException.
Volodymyr Prysiazhniuk

2

Uso l'iteratore e un ciclo while per memorizzare le varie maniglie delle finestre e quindi passare avanti e indietro.

//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);
            }

Non riesce a passare a nuove schede, tuttavia esegue clic sulla nuova scheda desiderata. Perché?
paul

c'è qualche motivo per cui questo codice può rendere il test molto lento? Sembra che dopo questo bit di codice ci vogliono circa 10 minuti per eseguire qualsiasi azione nel 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);
            }

0

Quindi il problema con molte di queste soluzioni è che presumi che la finestra appaia istantaneamente (non accade nulla all'istante e le cose accadono molto meno all'istante in IE). Inoltre stai assumendo che ci sarà solo una finestra prima di fare clic sull'elemento, il che non è sempre il caso. Inoltre IE non restituirà gli handle di finestra in un ordine prevedibile. Quindi farei quanto segue.

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

-1

Se hai più di un browser (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);
  }

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.