Переключение вкладок с помощью Selenium WebDriver с Java
Использование Selenium WebDriver с JAVA , Я пытаюсь автоматизировать функциональность, где мне нужно открыть новую вкладку, сделать там некоторые операции и вернуться к предыдущей вкладке (родительской). Я использовал ручку переключателя, но она не работает. И одна странная вещь, две вкладки имеют одинаковый дескриптор окна, из-за которого я не могу переключаться между вкладками.
Однако, когда я пытаюсь с различными окнами Firefox он работает, но для вкладки его не работает.
Пожалуйста, помогите мне, как я могу переключать вкладки. ОПЕРАЦИОННАЯ как я могу переключать вкладки без использования дескриптора окна, поскольку дескриптор окна одинаков для обеих вкладок в моем случае.
(я заметил , что когда вы открываете разные вкладки в одном окне, дескриптор окна остается тем же.)
19 ответов:
Этот код прекрасно работал для меня. Попробовать ее. Вам всегда нужно переключить драйвер на новую вкладку, прежде чем вы захотите что-то сделать на новой вкладке.psdbComponent.clickDocumentLink(); ArrayList<String> tabs2 = new ArrayList<String> (driver.getWindowHandles()); driver.switchTo().window(tabs2.get(1)); driver.close(); driver.switchTo().window(tabs2.get(0));
Это простое решение для открытия новой вкладки, изменения фокуса на ней, закрытия вкладки и возврата фокуса на старую / исходную вкладку:
@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()); }
Существует разница в том, как веб-драйвер обрабатывает различные окна и как он обрабатывает различные вкладки.
Кейс 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:
Если в одном окне есть несколько вкладок, то есть только один дескриптор окна. Таким образом, переключение между дескрипторами окна удерживает элемент управления на одной вкладке.
в этом случае использование 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");
Подробный пример кода можно найти here:
http://design-interviews.blogspot.com/2014/11/switching-between-tabs-in-same-browser-window.html
Работа вокруг
предположение : щелчок по чему-либо на вашей веб-странице приводит к открытию новой вкладки.
Используйте нижеприведенную логику для переключения на вторую вкладку.
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();
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
Надеюсь, это поможет вам..
Первое, что вам нужно сделать, это открыть новую вкладку и сохранить ее имя дескриптора. Лучше всего это делать с помощью 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(); }
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL,Keys.SHIFT,Keys.TAB);
Этот метод помогает переключаться между несколькими окнами. Ограничивающая проблема этого метода заключается в том, что он может использоваться только столько раз, пока не будет достигнуто требуемое окно. Надеюсь, это поможет.
С Selenium 2.53.1, использующим firefox 47.0.1 в качестве веб-драйвера на Java: независимо от того, сколько вкладок я открыл, " драйвер.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 }
Надеюсь, это даст вам хорошее представление о том, как управлять несколькими вкладками в нескольких браузерах окна.
Поскольку
driver.window_handles
не в порядке , лучшим решением является это.Сначала переключитесь на первую вкладку, используя ярлык
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.
Недавно у меня была проблема, ссылка была открыта в новой вкладке, но selenium по-прежнему сосредоточился на начальной вкладке.
Я использую Chromedriver и единственный способ, чтобы сосредоточиться на вкладке было для меня, чтобы использовать
switch_to_window()
.Вот код Python:
driver.switch_to_window(driver.window_handles[-1])
Таким образом, совет заключается в том, чтобы узнать имя нужного вам дескриптора окна, они хранятся в виде списка в
driver.window_handles
Пожалуйста, смотрите ниже:
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");
Надеюсь, что это полезно!
Это очень простой процесс: предположим, что у вас есть две вкладки, поэтому вам нужно сначала закрыть текущую вкладку с помощью
client.window(callback)
, потому что команда switch "переключается на первую доступную". Затем вы можете легко переключить вкладку с помощьюclient.switchTab
.
Краткий пример переключения между вкладками в браузере (в случае с одним окном):
// 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 для переключения на предыдущую вкладку.
Это будет работать для MacOS для Firefox и Chrome:
// 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, "{");
Для получения дескрипторов родительского окна.
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 вкладки, которую вы хотите переключить на
Публичный класс 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); }