如何使用带有 Java 的 Selenium WebDriver 切换到另一个选项卡

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29455355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:02:44  来源:igfitidea点击:

How to switch to another Tab using Selenium WebDriver with Java

javaselenium-webdriver

提问by Sampada Aggarwal

I am opening google.com and then clicking on "GMail" hyperlink a new tab is opened on the same browser.

我打开 google.com,然后单击“GMail”超链接,在同一浏览器上打开一个新选项卡。

Now I want to switch to this new tab where GMail is opened using Selenium WebDriver.

现在我想切换到这个使用 Selenium WebDriver 打开 GMail 的新选项卡。

Code snippet is :

代码片段是:

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

Now I want to go to the tab where I have opened GMail link. I have googled through N number of solutions but none of them worked.

现在我想转到打开 GMail 链接的选项卡。我用谷歌搜索了 N 个解决方案,但没有一个奏效。

For e.g.

例如

Solution 1 :

解决方案1:

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

Solution 2 :

解决方案2:

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

Kindly suggest. I am stuck on this.

请建议。我坚持这一点。

回答by Stan E

You have a possible right solution (Sol2), but the problem is you can't switch to a new tab untill it will not be loaded fully.

您有一个可能的正确解决方案 (Sol2),但问题是您无法切换到新选项卡,直到它无法完全加载。

So, solutions: 1) BAD ONE: put in a waiting timer, just sleep(2000) some time, and then

所以,解决方案:1)坏的一个:放置一个等待的计时器,只是睡眠(2000)一段时间,然后

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

2) Good one!

2)好一个!

Use native selenium things. First get all the available tabs opened with:

使用原生硒的东西。首先打开所有可用的选项卡:

driver.getWindowHandle();

Then swith to another tab:

然后切换到另一个选项卡:

driver.switchTo().window(myWindowHandle );

回答by Saifur

The window handles is not very safe with the index number since they could be very unordered. I would suggest you to find a list and do a loop and look for the intended one.

窗口句柄对于索引号不是很安全,因为它们可能非常无序。我建议您找到一个列表并进行循环并寻找预期的列表。

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

回答by TDHM

The way we manually switch to next tab is by pressing - CTRL + Page DownThe same we can do using Selenium like -

我们手动切换到下一个选项卡的方式是按 -CTRL + Page Down我们可以使用 Selenium 做同样的事情 -

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

回答by pcalkins

Seems to me that driver.getWindowHandles() does not work for tabs... you'll always get back a one item array with the CURRENT tab's handle... [deleted old answer as this seems to be fixed now]

在我看来,driver.getWindowHandles() 不适用于选项卡......你总是会得到一个带有 CURRENT 选项卡句柄的单项数组...... [删除旧答案,因为现在似乎已修复]

UPDATE (6/16/2016): the current version of Selenium (server standalone 2.53.0) seems to act differently. Now I'm using something like this to open/switch the driver to the new tab:

更新 (6/16/2016):Selenium 的当前版本(独立服务器 2.53.0)似乎表现不同。现在我使用这样的东西来打开/切换驱动程序到新标签:

UPDATE (11/16/2016): Selenium 3.0.1 seems to have changed things again? I have to use javascript to open a new tab now. This seems to work in Chrome only... Firefox opens a new window. I'm going to see if that behavior can be changed using geckodriver's settings (capabilities/profile?).

更新 (11/16/2016):Selenium 3.0.1 似乎又改变了?我现在必须使用 javascript 打开一个新选项卡。这似乎只适用于 Chrome... Firefox 会打开一个新窗口。我将看看是否可以使用 geckodriver 的设置(功能/配置文件?)更改该行为。

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

the getWindowHandles() method is now returning a Set. This has only been tested in Chrome so far, since Firefox version 47 currently has some serious problems using the firefoxdriver... and using geckodriver the Actions aren't working at all. [update 6/11/2016]: Firefox through geckodriver now returns a Set]

getWindowHandles() 方法现在返回一个 Set。到目前为止,这仅在 Chrome 中进行了测试,因为 Firefox 版本 47 目前在使用 firefoxdriver 时存在一些严重问题......而使用 geckodriver 时,操作根本无法工作。[更新 6/11/2016]:Firefox 通过 geckodriver 现在返回一个 Set]

You can also do something like this.. cast it to ArrayList:

你也可以做这样的事情..将它转换为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));

Update: To get around the geckodriver bug, I've switched to using element.sendkeys... something like this seems to work in Marionette and Chrome.. (Update2): Updated to javascript because of changes in Selenium 3.0.1:

更新:为了解决 geckodriver 错误,我已经改用 element.sendkeys ......像这样的东西似乎在 Marionette 和 Chrome 中工作......(更新 2):由于 Selenium 3.0.1 的变化而更新为 javascript:

// 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 (11/16/2016): the old method to close using Ctrl-W seems to be broken, too... use this:

更新 (11/16/2016):使用 Ctrl-W 关闭的旧方法似乎也被破坏了......使用这个:

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

回答by Charles Woodson

I'd suggest initializing a second driver to do the work for that tab, or open a second tab in the first driver and have that tab have it's own set of logic accomplishing what you need.

我建议初始化第二个驱动程序来完成该选项卡的工作,或者在第一个驱动程序中打开第二个选项卡并让该选项卡拥有自己的一组逻辑来完成您需要的操作。

The code below should give you a good idea of how you can manipulate different drivers/browsers/windows and multiple tabs within each driver using Selenium 2.53.1 and Chrome 51.0.

下面的代码应该让您很好地了解如何使用 Selenium 2.53.1 和 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
 }

I hope that helps

我希望有帮助

回答by OptimusPrime

Below is the Java Implementation using Robot Class, I have switched tabs multiple(7) times.

下面是使用 Robot 类的 Java 实现,我已经多次 (7) 次切换选项卡。

I Hope it will Help.

我希望它会有所帮助。

Imports:

进口:

import java.awt.Robot;

导入 java.awt.Robot;

import java.awt.event.KeyEvent;

导入 java.awt.event.KeyEvent;

import java.util.ArrayList;

导入 java.util.ArrayList;

import org.openqa.selenium.WebDriver;

导入 org.openqa.selenium.WebDriver;

import org.openqa.selenium.chrome.ChromeDriver;

导入 org.openqa.selenium.chrome.ChromeDriver;

Main Method

主要方法

public static void main(String[] args) {

    System.setProperty("webdriver.chrome.driver", "/Path/To/chromedriver/" + "chromedriver.exe");
    WebDriver driver = new ChromeDriver();

    // go to URL1
    driver.navigate().to("http://www.facebook.com");
    try {
        // Open New Tab by simulating Ctrl+t
        Robot r = new Robot();
        r.keyPress(KeyEvent.VK_CONTROL);
        r.keyPress(KeyEvent.VK_T);
        r.keyRelease(KeyEvent.VK_CONTROL);
        r.keyRelease(KeyEvent.VK_T);
        Thread.sleep(1000);

        // Create Array List to keep Tab information
        ArrayList<String> tabs2 = new ArrayList<String>(driver.getWindowHandles());

        // Navigate to New Tab
        driver.switchTo().window(tabs2.get(1));

        // go to URL2
        driver.navigate().to("http://www.google.com");

        // Navigate to Tab 0
        driver.switchTo().window(tabs2.get(0));

        Thread.sleep(2000);
        // Navigate to Tab 1
        driver.switchTo().window(tabs2.get(1));

        Thread.sleep(2000);
        // Navigate to Tab 0
        driver.switchTo().window(tabs2.get(0));

        Thread.sleep(2000);
        // Navigate to Tab 1
        driver.switchTo().window(tabs2.get(1));

        Thread.sleep(2000);
        // Navigate to Tab 1
        driver.switchTo().window(tabs2.get(0));
        driver.close();

        Thread.sleep(2000);

        // Navigate to Tab 1
        driver.switchTo().window(tabs2.get(1));
        driver.close();

    } catch (Exception e) {
    }

}

回答by user3638219

You can provide tab name parameter and try this:

您可以提供选项卡名称参数并尝试以下操作:

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

回答by Gavriel Cohen

There is an easy and short way:

有一个简单而简短的方法:

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

That's it, hope it help.

就是这样,希望有帮助。