简体   繁体   English

使用 Selenium WebDriver 和 Java 切换选项卡

[英]Switch tabs using Selenium WebDriver with Java

Using Selenium WebDriver with Java.在 Java 中使用 Selenium WebDriver。 I am trying to automate a functionality where I have to open a new tab do some operations there and come back to previous tab (Parent).我正在尝试自动化一个功能,我必须打开一个新选项卡在那里执行一些操作并返回到上一个选项卡(父级)。 I used switch handle but it's not working.我使用了开关手柄,但它不起作用。 And one strange thing the two tabs are having same window handle due to which I am not able to switch between tabs.一件奇怪的事情是两个选项卡具有相同的窗口句柄,因此我无法在选项卡之间切换。

However when I am trying with different Firefox windows it works, but for tab it's not working.但是,当我尝试使用不同的 Firefox 窗口时,它可以工作,但对于选项卡它不起作用。

How can I switch tabs?如何切换标签? Or, how can I switch tabs without using window handle as window handle is same of both tabs in my case?或者,如何在不使用窗口句柄的情况下切换选项卡,因为在我的情况下,两个选项卡的窗口句柄相同?

(I have observed that when you open different tabs in same window, window handle remains same) (我观察到,当您在同一个窗口中打开不同的选项卡时,窗口句柄保持不变)

    psdbComponent.clickDocumentLink();
    ArrayList<String> tabs2 = new ArrayList<String> (driver.getWindowHandles());
    driver.switchTo().window(tabs2.get(1));
    driver.close();
    driver.switchTo().window(tabs2.get(0));

This code perfectly worked for me.这段代码非常适合我。 Try it out.试试看。 You always need to switch your driver to new tab, before you want to do something on new tab.在你想在新标签上做某事之前,你总是需要将你的驱动程序切换到新标签。

This is a simple solution for opening a new tab, changing focus to it, closing the tab and return focus to the old/original tab:这是一个简单的解决方案,用于打开新选项卡、将焦点更改为它、关闭选项卡并将焦点返回到旧/原始选项卡:

@Test
public void testTabs() {
    driver.get("https://business.twitter.com/start-advertising");
    assertStartAdvertising();

    // considering that there is only one tab opened in that point.
    String oldTab = driver.getWindowHandle();
    driver.findElement(By.linkText("Twitter Advertising Blog")).click();
    ArrayList<String> newTab = new ArrayList<String>(driver.getWindowHandles());
    newTab.remove(oldTab);
    // change focus to new tab
    driver.switchTo().window(newTab.get(0));
    assertAdvertisingBlog();

    // Do what you want here, you are in the new tab

    driver.close();
    // change focus back to old tab
    driver.switchTo().window(oldTab);
    assertStartAdvertising();

    // Do what you want here, you are in the old tab
}

private void assertStartAdvertising() {
    assertEquals("Start Advertising | Twitter for Business", driver.getTitle());
}

private void assertAdvertisingBlog() {
    assertEquals("Twitter Advertising", driver.getTitle());
}

There is a difference how web driver handles different windows and how it handles different tabs. Web 驱动程序处理不同窗口的方式和处理不同选项卡的方式有所不同。

Case 1:情况1:
In case there are multiple windows, then the following code can help:如果有多个窗口,则以下代码可以提供帮助:

//Get the current window handle
String windowHandle = driver.getWindowHandle();

//Get the list of window handles
ArrayList tabs = new ArrayList (driver.getWindowHandles());
System.out.println(tabs.size());
//Use the list of window handles to switch between windows
driver.switchTo().window(tabs.get(0));

//Switch back to original window
driver.switchTo().window(mainWindowHandle);


Case 2:案例二:
In case there are multiple tabs in the same window, then there is only one window handle.如果同一窗口中有多个选项卡,则只有一个窗口句柄。 Hence switching between window handles keeps the control in the same tab.因此,在窗口句柄之间切换会使控件保持在同一个选项卡中。
In this case using Ctrl + \t (Ctrl + Tab) to switch between tabs is more useful.在这种情况下,使用 Ctrl + \t (Ctrl + Tab) 在选项卡之间切换更有用。

//Open a new tab using Ctrl + t
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"t");
//Switch between tabs using Ctrl + \t
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"\t");

Detailed sample code can be found here:详细的示例代码可以在这里找到:
http://design-interviews.blogspot.com/2014/11/switching-between-tabs-in-same-browser-window.html http://design-interviews.blogspot.com/2014/11/switching-between-tabs-in-same-browser-window.html

Work around解决方法

Assumption : By Clicking something on your web page leads to open a new tab.假设:通过单击网页上的某些内容会打开一个新选项卡。

Use below logic to switch to second tab.使用以下逻辑切换到第二个选项卡。

new Actions(driver).sendKeys(driver.findElement(By.tagName("html")), Keys.CONTROL).sendKeys(driver.findElement(By.tagName("html")),Keys.NUMPAD2).build().perform();

In the same manner you can switch back to first tab again.以同样的方式,您可以再次切换回第一个选项卡。

new Actions(driver).sendKeys(driver.findElement(By.tagName("html")), Keys.CONTROL).sendKeys(driver.findElement(By.tagName("html")),Keys.NUMPAD1).build().perform();

Since the driver.window_handles is not in order , a better solution is this.由于driver.window_handles不是 in order ,因此这是一个更好的解决方案。

first switch to the first tab using the shortcut Control + X to switch to the 'x' th tab in the browser window .首先使用快捷键Control + X切换到第一个选项卡以切换到浏览器窗口中的第 'x' 个选项卡。

driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "1");
# goes to 1st tab

driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "4");
# goes to 4th tab if its exists or goes to last tab.
String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL, Keys.RETURN);
    WebElement e = driver.findElement(By
            .xpath("html/body/header/div/div[1]/nav/a"));
e.sendKeys(selectLinkOpeninNewTab);//to open the link in a current page in to the browsers new tab

    e.sendKeys(Keys.CONTROL + "\t");//to move focus to next tab in same browser
    try {
        Thread.sleep(8000);
    } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    //to wait some time in that tab
    e.sendKeys(Keys.CONTROL + "\t");//to switch the focus to old tab again

Hope it helps to you..希望对你有帮助。。

The first thing you need to do is opening a new tab and save it's handle name.您需要做的第一件事是打开一个新选项卡并保存它的句柄名称。 It will be best to do it using javascript and not keys(ctrl+t) since keys aren't always available on automation servers.最好使用 javascript 而不是键 (ctrl+t) 来执行此操作,因为自动化服务器上​​的键并不总是可用的。 example:例子:

public static String openNewTab(String url) {
    executeJavaScript("window.parent = window.open('parent');");
    ArrayList<String> tabs = new ArrayList<String>(bot.driver.getWindowHandles());
    String handleName = tabs.get(1);
    bot.driver.switchTo().window(handleName);
    System.setProperty("current.window.handle", handleName);
    bot.driver.get(url);
    return handleName;
}

The second thing you need to do is switching between the tabs.您需要做的第二件事是在选项卡之间切换。 Doing it by switch window handles only, will not always work since the tab you'll work on, won't always be in focus and Selenium will fail from time to time.仅通过切换窗口句柄来执行此操作并不总是有效,因为您将处理的选项卡不会始终处于焦点,并且 Selenium 会不时出现故障。 As I said, it's a bit problematic to use keys, and javascript doesn't really support switching tabs, so I used alerts to switch tabs and it worked like a charm:正如我所说,使用键有点问题,而且 javascript 并不真正支持切换选项卡,所以我使用警报来切换选项卡,它就像一个魅力:

public static void switchTab(int tabNumber, String handleName) {
        driver.switchTo().window(handleName);
        System.setProperty("current.window.handle", handleName);
        if (tabNumber==1)
            executeJavaScript("alert(\"alert\");");
        else
            executeJavaScript("parent.alert(\"alert\");");
        bot.wait(1000);
        driver.switchTo().alert().accept();
    }
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL,Keys.SHIFT,Keys.TAB);

This method helps in switching between multiple windows.此方法有助于在多个窗口之间切换。 The restricting problem with this method is that it can only be used so many times until the required window is reached.这种方法的限制性问题是它只能使用这么多次,直到达到所需的窗口。 Hope it helps.希望能帮助到你。

With Selenium 2.53.1 using firefox 47.0.1 as the WebDriver in Java: no matter how many tabs I opened, "driver.getWindowHandles()" would only return one handle so it was impossible to switch between tabs. Selenium 2.53.1 使用 firefox 47.0.1 作为 Java 中的 WebDriver:无论我打开多少个选项卡,“driver.getWindowHandles()”都只会返回一个句柄,因此无法在选项卡之间切换。

Once I started using Chrome 51.0, I could get all handles.一旦我开始使用 Chrome 51.0,我就可以得到所有的句柄。 The following code show how to access multiple drivers and multiple tabs within each driver.以下代码显示了如何访问多个驱动程序和每个驱动程序中的多个选项卡。

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

Hopefully that gives you a good idea of how to manipulate multiple tabs in multiple browser windows.希望这能让您很好地了解如何在多个浏览器窗口中操作多个选项卡。

Simple Answer which worked for me:对我有用的简单答案:

for (String handle1 : driver1.getWindowHandles()) {
        System.out.println(handle1); 
        driver1.switchTo().window(handle1);     
}
Set<String> tabs = driver.getWindowHandles();
Iterator<String> it = tabs.iterator();
tab1 = it.next();
tab2 = it.next();
driver.switchTo().window(tab1);
driver.close();
driver.switchTo().window(tab2);

Try this.尝试这个。 It should work它应该工作

I had a problem recently, the link was opened in a new tab, but selenium focused still on the initial tab.我最近遇到了一个问题,链接是在一个新选项卡中打开的,但是 selenium 仍然专注于初始选项卡。

I'm using Chromedriver and the only way to focus on a tab was for me to use switch_to_window() .我正在使用 Chromedriver,专注于选项卡的唯一方法是使用switch_to_window()

Here's the Python code:这是Python代码:

driver.switch_to_window(driver.window_handles[-1])

So the tip is to find out the name of the window handle you need, they are stored as list in所以提示是找出您需要的窗口句柄的名称,它们作为列表存储在

driver.window_handles

Please see below:请看下面:

WebDriver driver = new FirefoxDriver();

driver.manage().window().maximize();
driver.get("https://www.irctc.co.in/");
String oldTab = driver.getWindowHandle();

//For opening window in New Tab
String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL,Keys.RETURN); 
driver.findElement(By.linkText("Hotels & Lounge")).sendKeys(selectLinkOpeninNewTab);

// Perform Ctrl + Tab to focus on new Tab window
new Actions(driver).sendKeys(Keys.chord(Keys.CONTROL, Keys.TAB)).perform();

// Switch driver control to focused tab window
driver.switchTo().window(oldTab);

driver.findElement(By.id("textfield")).sendKeys("bangalore");

Hope this is helpful!希望这有帮助!

It is A very simple process: assume you have two tabs so you need to first close the current tab by using client.window(callback) because the switch command "switches to the first available one".这是一个非常简单的过程:假设您有两个选项卡,因此您需要首先使用client.window(callback)关闭当前选项卡,因为切换命令“切换到第一个可用的选项卡”。 Then you can easily switch tab using client.switchTab .然后,您可以使用client.switchTab轻松切换选项卡。

A brief example of how to switch between tabs in a browser (in case with one window):如何在浏览器中的选项卡之间切换的一个简短示例(如果有一个窗口):

// open the first tab
driver.get("https://www.google.com");
Thread.sleep(2000);

// open the second tab
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
driver.get("https://www.google.com");
Thread.sleep(2000);

// switch to the previous tab
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "" + Keys.SHIFT + "" + Keys.TAB);
Thread.sleep(2000);

I write Thread.sleep(2000) just to have a timeout to see switching between the tabs.我写Thread.sleep(2000)只是为了有一个超时来查看选项卡之间的切换。

You can use CTRL+TAB for switching to the next tab and CTRL+SHIFT+TAB for switching to the previous tab.您可以使用 CTRL+TAB 切换到下一个选项卡,使用 CTRL+SHIFT+TAB 切换到上一个选项卡。

This will work for the MacOS for Firefox and Chrome:这适用于 Firefox 和 Chrome 的 MacOS:

// opens the default browser tab with the first webpage
driver.get("the url 1");
thread.sleep(2000);

// opens the second tab
driver.findElement(By.cssSelector("Body")).sendKeys(Keys.COMMAND + "t");
driver.get("the url 2");
Thread.sleep(2000);

// comes back to the first tab
driver.findElement(By.cssSelector("Body")).sendKeys(Keys.COMMAND, Keys.SHIFT, "{");

To get parent window handles.获取父窗口句柄。

String parentHandle = driverObj.getWindowHandle();
public String switchTab(String parentHandle){
    String currentHandle ="";
    Set<String> win  = ts.getDriver().getWindowHandles();   

    Iterator<String> it =  win.iterator();
    if(win.size() > 1){
        while(it.hasNext()){
            String handle = it.next();
            if (!handle.equalsIgnoreCase(parentHandle)){
                ts.getDriver().switchTo().window(handle);
                currentHandle = handle;
            }
        }
    }
    else{
        System.out.println("Unable to switch");
    }
    return currentHandle;
}

The flaw with the selected answer is that it unnecessarily assumes order in webDriver.getWindowHandles() .所选答案的缺陷是它不必要地假定webDriver.getWindowHandles()中的顺序。 The getWindowHandles() method returns a Set , which does not guarantee order. getWindowHandles()方法返回一个Set ,它不保证顺序。

I used the following code to change tabs, which does not assume any ordering.我使用以下代码更改选项卡,它不假定任何顺序。

String currentTabHandle = driver.getWindowHandle();
String newTabHandle = driver.getWindowHandles()
       .stream()
       .filter(handle -> !handle.equals(currentTabHandle ))
       .findFirst()
       .get();
driver.switchTo().window(newTabHandle);
protected void switchTabsUsingPartOfUrl(String platform) {
    String currentHandle = null;
    try {
        final Set<String> handles = driver.getWindowHandles();
        if (handles.size() > 1) {
            currentHandle = driver.getWindowHandle();
        }
        if (currentHandle != null) {
            for (final String handle : handles) {
                driver.switchTo().window(handle);
                if (currentUrl().contains(platform) && !currentHandle.equals(handle)) {
                    break;
                }
            }
        } else {
            for (final String handle : handles) {
                driver.switchTo().window(handle);
                if (currentUrl().contains(platform)) {
                    break;
                }
            }
        }
    } catch (Exception e) {
        System.out.println("Switching tabs failed");
    }
}

Call this method and pass parameter a substring of url of the tab you want to switch to调用此方法并将参数传递给要切换到的选项卡的 url 的子字符串

public class TabBrowserDemo {公共类 TabBrowserDemo {

public static void main(String[] args) throws InterruptedException {
    System.out.println("Main Started");
    System.setProperty("webdriver.gecko.driver", "driver//geckodriver.exe");
    WebDriver driver = new FirefoxDriver();
    driver.get("https://www.irctc.co.in/eticketing/userSignUp.jsf");
    driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

    driver.findElement(By.xpath("//a[text()='Flights']")).click();
    waitForLoad(driver);
    Set<String> ids = driver.getWindowHandles();
    Iterator<String> iterator = ids.iterator();
    String parentID = iterator.next();
    System.out.println("Parent WIn id " + parentID);
    String childID = iterator.next();
    System.out.println("child win id " + childID);

    driver.switchTo().window(childID);
    List<WebElement> hyperlinks = driver.findElements(By.xpath("//a"));

    System.out.println("Total links in tabbed browser " + hyperlinks.size());

    Thread.sleep(3000);
//  driver.close();
    driver.switchTo().window(parentID);
    List<WebElement> hyperlinksOfParent = driver.findElements(By.xpath("//a"));

    System.out.println("Total links " + hyperlinksOfParent.size());

}

public static void waitForLoad(WebDriver driver) {
    ExpectedCondition<Boolean> pageLoadCondition = new
            ExpectedCondition<Boolean>() {
                public Boolean apply(WebDriver driver) {
                    return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
                }
            };
    WebDriverWait wait = new WebDriverWait(driver, 30);
    wait.until(pageLoadCondition);
}
    public void switchToNextTab() {
        ArrayList<String> tab = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(tab.get(1));
    }
    
    public void closeAndSwitchToNextTab() {
        driver.close();
        ArrayList<String> tab = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(tab.get(1));
    }

    public void switchToPreviousTab() {
        ArrayList<String> tab = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(tab.get(0));
    }

    public void closeTabAndReturn() {
        driver.close();
        ArrayList<String> tab = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(tab.get(0));
    }

    public void switchToPreviousTabAndClose() {
        ArrayList<String> tab = new ArrayList<>(driver.getWindowHandles());
        driver.switchTo().window(tab.get(1));
        driver.close();
    }
WebDriver driver = new FirefoxDriver();

driver.switchTo().window(driver.getWindowHandles().toArray()[numPage].toString());

numPage - int (0,1..)

String mainWindow = driver.getWindowHandle();字符串 mainWindow = driver.getWindowHandle(); seleniumHelper.switchToChildWindow(); seleniumHelper.switchToChildWindow(); .. ..//your assertion steps .. ..//你的断言步骤

seleniumHelper.switchToWindow(mainWindow); seleniumHelper.switchToWindow(mainWindow);

with Java I used this for switching the selenium focus to the new tab.使用 Java,我使用它来将 selenium 焦点切换到新选项卡。

//Before the action that redirect to the new tab:
String windHandleCurrent = driver.getWindowHandle();
// code that click in a btn/link in order to open a new tab goes here
// now to make selenium move to the new tab 
ArrayList<String> windows = new ArrayList<String>(driver.getWindowHandles());
    for(int i =0;i<windows.size();i++ ) {
        String aWindow = windows.get(i);
        if(aWindow != windHandleCurrent) {
            driver.switchTo().window(aWindow);
        }
    }
// now you can code your AssertJUnit for the new tab.

Selenium 4 has new features: Selenium 4 具有新功能:

// Opens a new tab and switches to new tab driver.switchTo().newWindow(WindowType.TAB); // 打开一个新选项卡并切换到新选项卡driver.switchTo().newWindow(WindowType.TAB);

// Opens a new window and switches to new window driver.switchTo().newWindow(WindowType.WINDOW); // 打开一个新窗口并切换到新窗口driver.switchTo().newWindow(WindowType.WINDOW);

driver.getWindowHandles() is a Set.I converted it to array of objects by driver.getWindowHandles()是一个 Set.I 将它转换为对象数组

Object[] a=driver.getWindowHandles().toArray;

Say you want to switch to 2nd tab then (after conversion) use假设您想切换到第二个选项卡,然后(转换后)使用

driver.switchTo().windows(a[1].toString());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM