web-dev-qa-db-fra.com

Comment passer à un autre onglet avec Selenium WebDriver avec Java

J'ouvre google.com, puis en cliquant sur l'hyperlien "GMail", un nouvel onglet s'ouvre sur le même navigateur.

Maintenant, je souhaite passer à ce nouvel onglet où GMail est ouvert à l'aide de Selenium WebDriver.

L'extrait de code est: 

  WebDriver wd = new ChromeDriver();
  wd.get("https://www.google.co.in/?gws_rd=ssl");       
  wd.findElement(By.linkText("Gmail")).sendKeys(Keys.CONTROL,Keys.RETURN);

Maintenant, je veux aller à l'onglet où j'ai ouvert le lien GMail. J'ai cherché sur N nombre de solutions, mais aucune d'entre elles n'a fonctionné.

Par exemple.

Solution 1:

String Tab1 = wd.getWindowHandle(); 
ArrayList<String> availableWindows = new ArrayList<String>(wd.getWindowHandles()); 
if (!availableWindows.isEmpty()) { 
wd.switchTo().window(availableWindows.get(1)); 
}

Solution 2:

driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"\t");

Suggère de bien vouloir. Je suis coincé là-dessus.

5
Sammi

Il me semble que driver.getWindowHandles () ne fonctionne pas pour les onglets ... vous récupérerez toujours un tableau à élément unique avec le handle de l'onglet CURRENT ... [ancienne réponse supprimée car elle semble être corrigée maintenant]

UPDATE (16/06/2016): la version actuelle de Selenium (serveur autonome 2.53.0) semble agir différemment. Maintenant, j'utilise quelque chose comme ceci pour ouvrir/changer le pilote vers le nouvel onglet:

UPDATE (16/11/2016): Selenium 3.0.1 semble avoir encore changé les choses? Je dois utiliser javascript pour ouvrir un nouvel onglet maintenant. Cela semble fonctionner uniquement dans Chrome ... Firefox ouvre une nouvelle fenêtre. Je vais voir si ce comportement peut être changé en utilisant les paramètres de geckodriver (capacités/profil?). 

// Actions actions = new Actions(driver); 
// actions.keyDown(Keys.CONTROL).sendKeys("t").keyUp(Keys.CONTROL).build().perform();

((JavascriptExecutor)driver).executeScript("window.open('about:blank', '_blank');");

Set<String> tab_handles = driver.getWindowHandles();
    int number_of_tabs = tab_handles.size();
    int new_tab_index = number_of_tabs-1;
    driver.switchTo().window(tab_handles.toArray()[new_tab_index].toString()); 

la méthode getWindowHandles () renvoie maintenant un ensemble. Cela n’a été testé que dans Chrome jusqu’à présent, car Firefox version 47 rencontre actuellement de graves problèmes d’utilisation du firefoxdriver ... et de geckodriver, les actions ne fonctionnent pas du tout. [mise à jour le 11/06/2016]: Firefox via geckodriver renvoie désormais un ensemble]

Vous pouvez aussi faire quelque chose comme ça .. lancez-le dans ArrayList:

  //  set tab_index to the number of window/tab you want.  0 is the first tab 

       ArrayList<String> tabs_windows = new ArrayList<String> (driver.getWindowHandles());
    driver.switchTo().window(tabs_windows.get(tab_index));

Mise à jour: Pour contourner le bogue geckodriver, je suis passé à element.sendkeys ... quelque chose comme cela semble fonctionner dans Marionette et Chrome .. (Update2): mise à jour en javascript en raison de modifications apportées à Selenium 3.0.1:

// driver.findElement(By.cssSelector("body")).sendKeys(Keys.chord(Keys.CONTROL, "t"));

((JavascriptExecutor)driver).executeScript("window.open('about:blank', '_blank');");

    Set<String> tab_handles = driver.getWindowHandles();
    int number_of_tabs = tab_handles.size();
    int new_tab_index = number_of_tabs-1;
    driver.switchTo().window(tab_handles.toArray()[new_tab_index].toString()); 

UPDATE (16/11/2016): l'ancienne méthode pour fermer avec Ctrl-W semble être cassée, aussi ... utilisez ceci:

((JavascriptExecutor)driver).executeScript("close();");
8
pcalkins

Pour passer manuellement à l’onglet suivant, vous devez appuyer sur - CTRL + Page Down De la même façon, vous pouvez utiliser Selenium comme - 

driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL, Keys.PAGE_DOWN);
5
TDHM

Les poignées de fenêtre ne sont pas très sûres avec le numéro d'index car elles pourraient être très désordonnées. Je vous suggérerais de trouver une liste, de faire une boucle et de chercher celle qui vous est destinée.

public void TabHandles() {
    driver.get("https://www.google.co.in/?gws_rd=ssl");

    String currentWindowHandle = driver.getWindowHandle();

    driver.findElement(By.linkText("Gmail")).sendKeys(Keys.CONTROL, Keys.RETURN);

    //Get the list of all window handles
    ArrayList<String> windowHandles = new ArrayList<String>(driver.getWindowHandles());

    for (String window:windowHandles){

        //if it contains the current window we want to eliminate that from switchTo();
        if (window != currentWindowHandle){
            //Now switchTo new Tab.
            driver.switchTo().window(window);
            //Do whatever you want to do here.

            //Close the newly opened tab
            driver.close();
        }
    }
}
3
Saifur

Vous avez une bonne solution possible (Sol2), mais le problème est que vous ne pouvez pas basculer vers un nouvel onglet avant que le chargement ne soit terminé.

Donc, les solutions: 1) BAD ONE: mettre en attente, il suffit de dormir (2000) un certain temps, puis 

driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"\t");

2) Bon!

Utilisez des choses de sélénium natif. Commencez par ouvrir tous les onglets disponibles avec:

driver.getWindowHandle();

Puis passez à un autre onglet:

driver.switchTo().window(myWindowHandle );
1
Stan E

Vous pouvez fournir un paramètre de nom d'onglet et essayer ceci:

public boolean switchToTab(String tabName){
    log.debug("Switch to {} tab",tabName);
    ArrayList<String> tab = new ArrayList<>(driver.getWindowHandles());
    ArrayList<String> tabList = new ArrayList<>();
    for (int i =0;i<tab.size();i++){
        tabList.add(i,driver.switchTo().window(tab.get(i)).getTitle());
        driver.switchTo().window(tab.get(0));
        if(tabList.get(i).equals(tabName)){
            driver.switchTo().window(tab.get(i));
                return true;
        }
    }
    return false;
}
1
user3638219

Il existe un moyen simple et rapide:

import Java.util.ArrayList;

ArrayList<String> tabs2 = new ArrayList<String>(driver.getWindowHandles());
driver.switchTo().window(tabs2.get(1)); //Tab number

//Can change it for next tab like that or previous:

driver.switchTo().window(tabs2.get(1));
driver.close();
driver.switchTo().window(tabs2.get(0));

Ça y est, espérons que ça aide.

0
Gavriel Cohen

Je suggérerais d'initialiser un deuxième pilote pour faire le travail pour cet onglet, ou d'ouvrir un deuxième onglet dans le premier pilote et de laisser à cet onglet son propre ensemble de logique réalisant ce dont vous avez besoin.

Le code ci-dessous devrait vous donner une bonne idée de la façon dont vous pouvez manipuler différents pilotes/navigateurs/fenêtres et plusieurs onglets dans chaque pilote à l'aide de Selenium 2.53.1 et de Chrome 51.0.

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

J'espère que ça aide

0
Charles Woodson