使用 Selenium WebDriver 和 Java 切换选项卡

用 Java 使用 Selenium WebDriver。 我试图自动化一个功能,其中我必须打开一个新的选项卡做一些操作,并返回到以前的选项卡(父)。 我用开关把手,但它不工作。 还有一件奇怪的事情,这两个标签有相同的窗口句柄,因为我不能在标签之间切换。

然而,当我尝试使用不同的 Firefox 窗口时,它工作了,但是对于 tab,它不工作。

我怎样才能切换标签? 或者,在我的例子中,如何在不使用窗口句柄作为窗口句柄的情况下切换标签?

(我观察到,当您在同一个窗口中打开不同的选项卡时,窗口句柄保持不变)

379930 次浏览

绕过去

假设 : 通过点击网页上的某个东西可以打开一个新的标签页。

使用下面的逻辑切换到第二个选项卡。

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

以同样的方式,您可以再次切换回第一个选项卡。

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

我最近遇到了一个问题,链接在一个新的选项卡中打开,但是硒仍然集中在最初的选项卡上。

我正在使用 ChromeDriver,而专注于标签的唯一方法就是使用 switch_to_window()

下面是 Python 代码:

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

因此,技巧是找出您需要的窗口句柄的名称,它们以列表的形式存储在

driver.window_handles

这是一个简单的解决方案,打开一个新的标签,改变焦点到它,关闭标签,并返回焦点到旧的/原来的标签:

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

请参阅以下内容:

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

希望这对你有帮助!

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

这个代码对我很有用。试试看。您总是需要切换您的驱动程序到新的标签,然后才要做一些新的标签。

Web 驱动程序如何处理不同的窗口以及如何处理不同的选项卡是有区别的。

案例1:
如果有多个窗口,那么以下代码可以提供帮助:

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


案例2:
如果同一个窗口中有多个选项卡,那么只有一个窗口句柄。因此,在窗口句柄之间切换可以使控件保持在同一个选项卡中。< br/> 在这种情况下,使用 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");

详细的示例代码可以在这里找到:
Http://design-interviews.blogspot.com/2014/11/switching-between-tabs-in-same-browser-window.html

这是一个非常简单的过程: 假设您有两个选项卡,因此您需要首先使用 client.window(callback)关闭当前选项卡,因为 switch 命令“切换到第一个可用的选项卡”。然后您可以轻松地切换标签使用 client.switchTab

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

希望对你有帮助。

一个简单的例子说明如何在浏览器中的选项卡之间切换(在只有一个窗口的情况下) :

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

我编写 Thread.sleep(2000)只是为了有一个超时来查看选项卡之间的切换。

可以使用 CTRL + TAB 切换到下一个选项卡,使用 CTRL + SHIFT + TAB 切换到上一个选项卡。

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

此方法有助于在多个窗口之间切换。这种方法的限制性问题是,它只能使用这么多次,直到达到所需的窗口。希望能有帮助。

Selenium 2.53.1使用 firefox47.0.1作为 Java 中的 WebDriver: 无论我打开多少个标签,“ driver.getWindowHandles ()”只会返回一个句柄,所以不可能在标签之间切换。

一旦我开始使用 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
}

希望这能让您了解如何在多个浏览器窗口中操作多个选项卡。

这将适用于用于 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, "{");

您需要做的第一件事是打开一个新的选项卡并保存它的句柄名。最好使用 javascript 而不是密钥(ctrl + t) ,因为密钥在自动化服务器上并不总是可用的。例如:

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

您需要做的第二件事是在选项卡之间切换。只通过切换窗口句柄来完成,不会总是有效,因为您将处理的选项卡将不会总是处于焦点,Selenium 将不时失败。 正如我所说的,使用键有点问题,而且 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();
}

获取父窗口句柄。

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

这个简单的答案对我很有用:

for (String handle1 : driver1.getWindowHandles()) {
System.out.println(handle1);
driver1.switchTo().window(handle1);
}

所选答案的缺陷在于,它不必要地假定 webDriver.getWindowHandles()的顺序。getWindowHandles()方法返回一个 Set,它不保证顺序。

我使用下面的代码来更改选项卡,它不假定任何排序。

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

调用此方法并将要切换到的选项卡的 url 的子字符串传递给参数

由于 driver.window_handles的顺序不对,一个更好的解决方案是这样的。

首先切换到第一个选项卡使用快捷方式 Control + X切换到浏览器窗口中的‘ x’th 选项卡。

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.

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

试试这个,应该能行

WebDriver driver = new FirefoxDriver();


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


numPage - int (0,1..)

字符串 mainWindow = driver.getWindowHandle () ; SeleniumHelper.switchToChildWindow () ; .. . .//你的断言步骤

SwitchToWindow (mainWindow) ;

在 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.

硒4有新的特性:

//打开新选项卡并切换到新选项卡 driver.switchTo().newWindow(WindowType.TAB);

//打开新窗口并切换到新窗口 driver.switchTo().newWindow(WindowType.WINDOW);

GetWindowHandles () 是一个 Set.I,通过

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

说你想切换到第二个标签,然后(转换后)使用

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