Comment basculer vers la nouvelle fenêtre du navigateur, qui s'ouvre après avoir cliqué sur le bouton?


86

J'ai une situation, lorsque cliquez sur le bouton ouvre la nouvelle fenêtre du navigateur avec les résultats de la recherche.

Existe-t-il un moyen de se connecter et de se concentrer sur une nouvelle fenêtre de navigateur ouverte?

Et travaillez avec, puis revenez à la (première) fenêtre d'origine.


Nous pouvons faire le changement automatiquement - vérifiez ici pour l'utilisation avancée - testautomationguru.com
vins

Réponses:


117

Vous pouvez basculer entre les fenêtres comme ci-dessous:

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

3
Je peux confirmer que la solution acceptée fonctionne toujours dans Chrome mais pas dans IE. Le nouveau handle de fenêtre n'est pas reconnu dans IE. @Elmue est incorrect car getWindowHandles()renvoie un Set et un Set ne garantit pas l'ordre . Le dernier élément n'est pas toujours la dernière fenêtre. Je suis surpris que son commentaire reçoive beaucoup de votes positifs.
argent

@silver: Je n'ai aucune idée de ce dont vous parlez. Dans mon code WindowHandles renvoie un ReadOnlyCollection <string> pour lequel je peux garantir que la dernière entrée est toujours la dernière fenêtre ouverte. J'ai testé ça. Si cela fonctionne parfaitement en C #, mais est mal implémenté en Java, vous devez le signaler comme un bogue.
Elmue

@Elmue Ceci est un thread Java. Veuillez lire la réponse de Luke (développeur Selenium) concernant getWindowHandles(). C'est un comportement connu (pas un bug) de la méthode et du Java Set <T> en particulier. Par conséquent, switchTo().window(handles[handles.length-1])n'est pas garanti en Java. La solution AC # ne peut pas être considérée comme correcte.
argent

5
@Elmue Pour la troisième (et dernière) fois, votre réponse est fausse pour Java, car pris en charge par la documentation et le développement, ce qui peut induire en erreur les gens. Postez une réponse où vous dites que c'est pour C #, pas de problème. Créez une carte de problème dans GitHub pour Java, allez-y. Simplement, votre réponse ne s'applique pas à la langue TAGGED dans le fil et les gens peuvent penser autrement. Si vous ne pouvez pas faire la distinction, votre compréhension fait défaut.
argent

3
@Elmue Au fait, vous avez également tort de dire que driver.close () ferme les deux fenêtres. Il ferme seulement le courant. driver.quit () tue toutes les instances. Je vois que quelqu'un vous a déjà signalé cela. Votre commentaire est plein d'erreurs. Bonne journée.
argent

12

Juste pour ajouter au contenu ...

Pour revenir à la fenêtre principale (fenêtre par défaut).

utilisation driver.switchTo().defaultContent();


11

Ce script vous aide à passer d'une fenêtre Parent à une fenêtre Enfant et à revenir cntrl à la fenêtre Parent

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 () fonctionnera pour une nouvelle fenêtre. S'il s'agit d'un nouvel onglet, utilisez le code pour fermer le nouvel onglet: driver.findElement (By.cssSelector ("body")). SendKeys (Keys.CONTROL + "w");
Ripon Al Wasim

4

Surya, votre façon de faire ne fonctionnera pas, pour deux raisons:

  1. vous ne pouvez pas fermer le pilote pendant l'évaluation du test car il perdra le focus , avant de passer à l'élément actif, et vous obtiendrez NoSuchWindowException.
  2. si les tests sont exécutés sur ChromeDriver, vous n'obtiendrez pas une fenêtre, mais un onglet sur clic dans votre application. Comme SeleniumDriver ne peut pas agir avec les onglets , ne bascule que d'une fenêtre à l'autre, il se bloque au clic à l'endroit où le nouvel onglet s'ouvre et se bloque à l'expiration du délai.

1
Vous pouvez en fait utiliser l'appel de driver.close () puisque vous changez de poignées de fenêtre sur le pilote et que vous appelez la fenêtre sur laquelle vous vous trouvez actuellement à fermer. Je l'utilise régulièrement dans mon code lorsque je traite plusieurs fenêtres. driver.Quit () est l'appel qui tuera le test. Dans Chromedriver, vous pouvez toujours appeler getWindowHandles () pour obtenir votre liste de fenêtres disponibles. Je ne peux pas penser à une raison d'utiliser un onglet dans un test Web.
Ben

@Elmue La question d'origine indiquait qu'un clic ouvre une deuxième fenêtre créant plusieurs poignées de fenêtre. Je peux faire l'appel driver.close (); et faire fermer ma fenêtre qui a actuellement le focus. Je peux alors passer à n'importe quelle autre fenêtre active de mon choix. driver.close () et driver.quit () ne partagent pas la même fonctionnalité. Un appel à driver.quit () tuera l'instance de pilote active alors que close ne tue que le handle de fenêtre actuel. En outre, je n'ai encore vu aucun appel qui ouvre uniquement un onglet après qu'un clic est appelé lorsque le javascript sur le site Web crée une nouvelle fenêtre.
Ben

Je me suis trompé et j'ai supprimé mon commentaire. Vous pouvez également supprimer votre réponse.
Elmue

3

Modifier le registre pour IE:

ie_x64_tabprocgrowth.png

  1. HKEY_CURRENT_USER \ Software \ Microsoft \ Internet Explorer \ Main
  2. Cliquez avec le bouton droit de la souris → Nouveau → Valeur de chaîne → Nom de la valeur: TabProcGrowth (créer s'il n'existe pas)
  3. TabProcGrowth (clic droit) → Modifier ... → Données de la valeur: 0

Source: Problème de commutation de fenêtres Selenium WebDriver dans Internet Explorer 8-10

Dans mon cas, IE a commencé à détecter de nouvelles poignées de fenêtre après la modification du registre.

Tiré du blog MSDN:

Croissance du processus d'onglet: définit la vitesse à laquelle IE crée des processus de nouvel onglet.

L'algorithme "Max-Number": il spécifie le nombre maximum de processus de tabulation qui peuvent être exécutés pour une seule session d'isolement pour un processus de trame unique à un niveau d'intégrité obligatoire spécifique (MIC). Les valeurs relatives sont:

  • TabProcGrowth = 0: les onglets et les cadres s'exécutent dans le même processus; les cadres ne sont pas unifiés entre les niveaux MIC.
  • TabProcGrowth = 1: tous les onglets d'un processus de trame donné s'exécutent dans un processus d'onglet unique pour un niveau MIC donné.

Source: l' ouverture d'un nouvel onglet peut lancer un nouveau processus avec Internet Explorer 8.0


Options Internet:

  • Sécurité → Décochez Activer le mode protégé pour toutes les zones (Internet, intranet local, sites de confiance, sites restreints)
  • Avancé → Sécurité → Décochez Activer le mode protégé amélioré

Code:

Navigateur: IE11 x64 (Zoom: 100%)
OS: 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);

Le code ci-dessus comprend une vérification if pour vous assurer que vous ne passez pas à la fenêtre parente car Set<T>aucun ordre n'est garanti en Java . WebDriverWaitsemble augmenter les chances de succès comme le soutient la déclaration ci-dessous.

Cité de Luke Inman-Semerau : (Développeur pour Selenium)

Le navigateur peut prendre du temps pour accuser réception de la nouvelle fenêtre, et vous pouvez tomber dans votre boucle switchTo () avant que la fenêtre contextuelle n'apparaisse.

Vous supposez automatiquement que la dernière fenêtre renvoyée par getWindowHandles () sera la dernière ouverte. Ce n'est pas nécessairement vrai, car ils ne sont pas garantis pour être retournés dans n'importe quel ordre.

Source: Impossible de gérer une fenêtre contextuelle dans IE, le contrôle n'est pas transféré vers la fenêtre contextuelle


Articles Similaires:


2

Vous pouvez utiliser:

driver.SwitchTo().Window(WindowName);

Où WindowName est une chaîne représentant le nom de la fenêtre vers laquelle vous souhaitez basculer le focus. Appelez à nouveau cette fonction avec le nom de la fenêtre d'origine pour y revenir lorsque vous avez terminé.


1
merci pour la suggestion, y a-t-il un moyen, comment je peux définir le masque de nom de fenêtre? Comme "WinName *", où * - n'importe quel symbole.
Volodymyr Prysiazhniuk

1
Mon implicitement est de 10 secondes, mais en 2 secondes, cela me donne l'exception NoSuchWindowException.
Volodymyr Prysiazhniuk

2

J'utilise un itérateur et une boucle while pour stocker les différentes poignées de fenêtre, puis j'intervertis.

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

Il ne parvient pas à passer aux nouveaux onglets, mais il effectue des clics sur le nouvel onglet souhaité. Pourquoi?
paul

y a-t-il une raison pour laquelle ce code peut rendre le test très lent? Il semble qu'après ce bit de code, il faut environ 10 minutes pour effectuer des actions dans le 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

Donc, le problème avec beaucoup de ces solutions est que vous supposez que la fenêtre apparaît instantanément (rien ne se passe instantanément, et les choses se passent beaucoup moins instantanément dans IE). De plus, vous supposez qu'il n'y aura qu'une seule fenêtre avant de cliquer sur l'élément, ce qui n'est pas toujours le cas. De plus, IE ne renverra pas les poignées de fenêtre dans un ordre prévisible. Je ferais donc ce qui suit.

 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

Si vous avez plus d'un navigateur (en utilisant 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);
  }

}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.