Як перейти на нове вікно браузера, яке відкривається після натискання на кнопку?


86

У мене ситуація, коли натискання кнопки відкриває нове вікно браузера з результатами пошуку.

Чи є спосіб підключитися та зосередитися на новому вікні браузера?

І попрацюйте з цим, а потім поверніться до початкового (першого) вікна.


Ми можемо зробити перемикання автоматично - перевірте тут для розширеного використання - testautomationguru.com/…
vins

Відповіді:


117

Ви можете переключатися між вікнами, як показано нижче:

// Store the current window handle
String winHandleBefore = driver.getWindowHandle();

// Perform the click operation that opens new window

// Switch to new window opened
for(String winHandle : driver.getWindowHandles()){
    driver.switchTo().window(winHandle);
}

// Perform the actions on new window

// Close the new window, if that window no more required
driver.close();

// Switch back to original browser (first window)
driver.switchTo().window(winHandleBefore);

// Continue with original browser (first window)

3
Я можу підтвердити, що прийняте рішення постійно працює в Chrome, але не в IE. Нова дескриптор вікна не розпізнається в IE. @Elmue неправильний, оскільки getWindowHandles()повертає набір, а набір не гарантує замовлення . Останній елемент не завжди є останнім вікном. Я здивований, що його коментар отримує багато голосів.
срібло

@silver: Я не уявляю, про що ти говориш. У моєму коді WindowHandles повертає ReadOnlyCollection <string>, для якого я можу гарантувати, що останній запис завжди є останнім відкритим вікном. Я тестував це. Якщо це чудово працює в C #, але неправильно реалізовано в Java, ви повинні повідомити про це як про помилку.
Elmue

@Elmue Це нитка Java. Будь ласка , прочитайте (розробник Selenium) Люка відповідь про getWindowHandles(). Це відома поведінка (а не помилка) методу та Java Set <T> зокрема. Тому switchTo().window(handles[handles.length-1])в Java не гарантується. Не можна стверджувати, що рішення AC # є правильним.
срібло

5
@Elmue Втретє (і останній) раз ваша відповідь невірна для Java, що підтримується документами та розробниками, які можуть ОЗНАЧИТИ людей. Опублікуйте відповідь там, де ви кажете, що це для C #, не біда. Підніміть картку випуску в GitHub для Java, продовжуйте. Просто ваша відповідь не стосується мови, позначеної в ланцюжку, і люди можуть думати інакше. Якщо ви не можете зробити різницю, вам бракує розуміння.
срібло

3
@Elmue До речі, ви також помиляєтесь, кажучи, що driver.close () закриває обидва вікна. Це лише закриває струм. driver.quit () вбиває всі екземпляри. Я бачу, хтось уже вказував вам на це. Ваш коментар сповнений помилок. Гарного дня.
срібло

12

Просто додати до вмісту ...

Щоб повернутися до головного вікна (вікно за замовчуванням).

використання driver.switchTo().defaultContent();


11

Цей сценарій допоможе вам перейти з батьківського вікна на дочірнє вікно та повернути cntrl на батьківське вікно

String parentWindow = driver.getWindowHandle();
Set<String> handles =  driver.getWindowHandles();
   for(String windowHandle  : handles)
       {
       if(!windowHandle.equals(parentWindow))
          {
          driver.switchTo().window(windowHandle);
         <!--Perform your operation here for new window-->
         driver.close(); //closing child window
         driver.switchTo().window(parentWindow); //cntrl to parent window
          }
       }

1
driver.close () буде працювати в новому вікні. Якщо це нова вкладка, використовуйте код, щоб закрити нову вкладку: driver.findElement (By.cssSelector ("тіло")). SendKeys (Keys.CONTROL + "w");
Ріпон Аль-Васім

4

Сур'я, твій шлях не буде працювати з двох причин:

  1. Ви не можете закрити драйвер під час оцінки тесту, оскільки він втратить фокус , перш ніж перейти на активний елемент, і ви отримаєте NoSuchWindowException.
  2. якщо тест запущений на ChromeDriver, ви отримаєте не вікно, а вкладку з клацанням у вашій програмі. Оскільки SeleniumDriver не може діяти з вкладками , лише перемикається між вікнами, він натискає на клавішу, де відкривається нова вкладка, і аварійно завершує роботу.

1
Ви насправді можете використовувати виклик для driver.close (), оскільки ви перемикаєте ручки вікон на драйвері і закликаєте закрити вікно, яке ви зараз перебуваєте. Я регулярно використовую його у своєму коді, коли маю справу з декількома вікнами. driver.Quit () - це виклик, який уб'є тест. У Chromedriver ви все ще можете зателефонувати до getWindowHandles (), щоб отримати список доступних вікон. Я не можу придумати причину використовувати вкладку в веб-тесті.
Ben

@Elmue Оригінальне запитання стверджувало, що клацання відкриває друге вікно, створюючи кілька дескрипторів вікна. Я можу зробити драйвер дзвінка.close (); і закрити моє вікно, яке зараз має фокус. Потім я можу перейти до будь-якого іншого активного вікна на мій вибір. driver.close () та driver.quit () не мають однакових функціональних можливостей. Виклик driver.quit () вб'є активний екземпляр драйвера, тоді як закриття вбиває лише поточний дескриптор вікна. Крім того, я ще не бачив жодного дзвінка, який відкривав би лише вкладку після виклику клацання, коли javascript на веб-сайті створює нове вікно.
Бен

Я помилився і видалив свій коментар. Ви також можете видалити свою відповідь.
Elmue

3

Змінення реєстру для IE:

ie_x64_tabprocgrowth.png

  1. HKEY_CURRENT_USER \ Software \ Microsoft \ Internet Explorer \ Main
  2. Клацніть правою кнопкою миші → Створити → Значення рядка → Назва значення: TabProcGrowth (створити, якщо не існує)
  3. TabProcGrowth (клацніть правою кнопкою миші) → Змінити ... → Дані про значення: 0

Джерело: проблема переключення вікон Selenium WebDriver в Internet Explorer 8-10

У моєму випадку IE почав виявляти ручки нових вікон після редагування реєстру.

Взято з блогу MSDN:

Зростання процесу вкладок: Встановлює швидкість, з якою IE створює процеси нової вкладки.

Алгоритм "Max-Number": Вказує максимальну кількість процесів вкладок, які можуть бути виконані за один сеанс ізоляції для одного кадрового процесу на певному обов'язковому рівні цілісності (MIC). Відносними значеннями є:

  • TabProcGrowth = 0: вкладки та кадри працюють в рамках одного і того ж процесу; кадри не уніфіковані між рівнями MIC.
  • TabProcGrowth = 1: усі вкладки для даного кадрового процесу виконуються в одній вкладці для даного рівня MIC.

Джерело: відкриття нової вкладки може запустити новий процес за допомогою Internet Explorer 8.0


Властивості Інтернету:

  • Безпека → Зніміть прапорець Увімкнути захищений режим для всіх зон (Інтернет, локальна інтрамережа, надійні сайти, обмежені сайти)
  • Додатково → Безпека → Зніміть галочку Увімкнути посилений захищений режим

Код:

Браузер: IE11 x64 (масштабування: 100%)
ОС: Windows 7 x64
Selenium: 3.5.1
WebDriver: IEDriverServer x64 3.5.1

public static String openWindow(WebDriver driver, By by) throws IOException {
String parentHandle = driver.getWindowHandle(); // Save parent window
WebElement clickableElement = driver.findElement(by);
clickableElement.click(); // Open child window
WebDriverWait wait = new WebDriverWait(driver, 10); // Timeout in 10s
boolean isChildWindowOpen = wait.until(ExpectedConditions.numberOfWindowsToBe(2));
if (isChildWindowOpen) {
    Set<String> handles = driver.getWindowHandles();
    // Switch to child window
    for (String handle : handles) {
        driver.switchTo().window(handle);
        if (!parentHandle.equals(handle)) {
            break;
        }
    }
    driver.manage().window().maximize();
}
return parentHandle; // Returns parent window if need to switch back
}



/* How to use method */
String parentHandle = Selenium.openWindow(driver, by);

// Do things in child window
driver.close();

// Return to parent window
driver.switchTo().window(parentHandle);

Наведений вище код включає перевірку if, щоб переконатися, що ви не перемикаєтесь на батьківське вікно, оскільки Set<T>не має гарантованого замовлення в Java .WebDriverWaitсхоже, збільшує шанс на успіх, що підтверджується наведеним нижче твердженням.

Цитується від Люка Інмана-Семерау : (розробник селену)

Браузер може зайняти час, щоб підтвердити нове вікно, і ви можете потрапити у цикл switchTo () до появи спливаючого вікна.

Ви автоматично припускаєте, що останнє вікно, яке повертає getWindowHandles (), буде останнім відкритим. Це не обов’язково вірно, оскільки їх не гарантовано повертати в будь-якому порядку.

Джерело: Не вдається обробити спливаюче вікно в IE, керування не переноситься у спливаюче вікно


Схожі повідомлення:


2

Ви можете використовувати:

driver.SwitchTo().Window(WindowName);

Де WindowName - рядок, що представляє ім'я вікна, на яке потрібно переключити фокус. Викличте цю функцію ще раз із назвою оригінального вікна, щоб повернутися до неї, коли закінчите.


1
дякую за пропозицію, чи є спосіб, як я можу встановити маску імені вікна? Як "WinName *", де * - будь-який символ.
Володимир Присяжнюк

1
Я імпліцитно складає 10 секунд, але через 2 секунди це дає мені виняток NoSuchWindowException.
Володимир Присяжнюк

2

Я використовую ітератор і цикл while, щоб зберігати різні ручки вікон, а потім перемикатися вперед і назад.

//Click your link
driver.findElement(By.xpath("xpath")).click();
//Get all the window handles in a set
Set <String> handles =driver.getWindowHandles();
Iterator<String> it = handles.iterator();
//iterate through your windows
while (it.hasNext()){
String parent = it.next();
String newwin = it.next();
driver.switchTo().window(newwin);
//perform actions on new window
driver.close();
driver.switchTo().window(parent);
            }

Не вдається перейти на нові вкладки, однак виконує клацання на потрібній новій вкладці. Чому?
Пол

чи є якась причина, через яку цей код може спричинити дуже повільний тест? Здається, що після цього біта коду потрібно приблизно 10 хвилин, щоб виконати будь-які дії у ньювіні
Гюго,

0
 main you can do :

 String mainTab = page.goToNewTab ();
 //do what you want
 page.backToMainPage(mainTab);  

 What you need to have in order to use the main   

        private static Set<String> windows;

            //get all open windows 
            //return current window
            public String initWindows() {
                windows = new HashSet<String>();
                driver.getWindowHandles().stream().forEach(n ->   windows.add(n));
                return driver.getWindowHandle();
            }

            public String getNewWindow() {
                List<String> newWindow = driver.getWindowHandles().stream().filter(n -> windows.contains(n) == false)
                        .collect(Collectors.toList());
                logger.info(newWindow.get(0));
                return newWindow.get(0);
            }


            public String goToNewTab() {
                String startWindow = driver.initWindows();
                driver.findElement(By.cssSelector("XX")).click();
                String newWindow = driver.getNewWindow();
                driver.switchTo().window(newWindow);
                return startWindow;
            }

            public void backToMainPage(String startWindow) {
                driver.close();
                driver.switchTo().window(startWindow);
            }

0

Отже, проблема з багатьма з цих рішень полягає в тому, що ви припускаєте, що вікно з’являється миттєво (нічого не відбувається миттєво, і все відбувається значно менше миттєво в IE). Також ви припускаєте, що до натискання елемента буде лише одне вікно, що не завжди так. Також IE не поверне дескриптори вікна у передбачуваному порядку. Тому я зробив би наступне.

 public String clickAndSwitchWindow(WebElement elementToClick, Duration 
    timeToWaitForWindowToAppear) {
    Set<String> priorHandles = _driver.getWindowHandles();

    elementToClick.click();
    try {
        new WebDriverWait(_driver,
                timeToWaitForWindowToAppear.getSeconds()).until(
                d -> {
                    Set<String> newHandles = d.getWindowHandles();
                    if (newHandles.size() > priorHandles.size()) {
                        for (String newHandle : newHandles) {
                            if (!priorHandles.contains(newHandle)) {
                                d.switchTo().window(newHandle);
                                return true;
                            }
                        }
                        return false;
                    } else {
                        return false;
                    }

                });
    } catch (Exception e) {
        Logging.log_AndFail("Encountered error while switching to new window after clicking element " + elementToClick.toString()
                + " seeing error: \n" + e.getMessage());
    }

    return _driver.getWindowHandle();
}

-1

Якщо у вас більше одного браузера (за допомогою Java 8)

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class TestLink {

  private static Set<String> windows;

  public static void main(String[] args) {

    WebDriver driver = new FirefoxDriver();
    driver.get("file:///C:/Users/radler/Desktop/myLink.html");
    setWindows(driver);
    driver.findElement(By.xpath("//body/a")).click();
    // get new window
    String newWindow = getWindow(driver);
    driver.switchTo().window(newWindow);

    // Perform the actions on new window
    String text = driver.findElement(By.cssSelector(".active")).getText();
    System.out.println(text);

    driver.close();
    // Switch back
    driver.switchTo().window(windows.iterator().next());


    driver.findElement(By.xpath("//body/a")).click();

  }

  private static void setWindows(WebDriver driver) {
    windows = new HashSet<String>();
    driver.getWindowHandles().stream().forEach(n -> windows.add(n));
  }

  private static String getWindow(WebDriver driver) {
    List<String> newWindow = driver.getWindowHandles().stream()
        .filter(n -> windows.contains(n) == false).collect(Collectors.toList());
    System.out.println(newWindow.get(0));
    return newWindow.get(0);
  }

}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.