Закрытие (отклонение) предварительного просмотра Chrome с помощью Java + Selenium - PullRequest
0 голосов
/ 20 июня 2019

Мой тест Selenium выглядит примерно так: клиент выбирает финансовый продукт, заполняет некоторые необходимые данные и в предварительном просмотре предъявляет документ с условиями / соглашением (в соответствии с местным законодательством). После печати / закрытия диалогового окна предварительного просмотра, клиент вводит дополнительные данные и продолжает работу, выбирает некоторые параметры и, наконец, получает еще один предварительный просмотр контракта. После этого он подтверждает контракт и процесс завершен. Я запускаю свои тесты на Chrome версии 75.

Пока я пробовал две вещи: 1. Переключитесь на предварительный просмотр печати с помощью Selenium, перейдите к кнопке «Отмена» через DOM и щелкните по ней. Но так как диалог использует теневой DOM, он очень уродлив, сложен в обслуживании и часто ломается после обновлений Chrome. 2. Пробовал использовать класс Robot из awt, он хорошо работает при локальном запуске, но не работает при работе на сетке Selenium, потому что окно Chrome не сфокусировано и не получает события клавиатуры.

Текущее состояние метода, обрабатывающего закрытие диалогового окна печати:

    public void closePrintPreview() {
        WebDriverWait wait = new WebDriverWait(driver, 5);
        wait.until(driver -> driver.getWindowHandles().size() > 1);
        driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());

        wait.until(d -> {
            if (d.getWindowHandles().size() > 1) {
                d.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
                try {
                    Robot robot = new Robot();
                    robot.keyPress(KeyEvent.VK_ESCAPE);
                    robot.keyRelease(KeyEvent.VK_ESCAPE);
                } catch (AWTException e) {
                    throw new RuntimeException(e);
                }
                return false;
            }
            return true;
        });

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

Так что мой вопрос был бы: есть ли более простой способ получить кнопку «Отмена» в предварительном просмотре печати или, может быть, какой-нибудь способ заставить окно Chrome сфокусироваться так, чтобы оно могло получать ключевые события от робота?

Ответы [ 2 ]

1 голос
/ 20 июня 2019

Вот решение в Python.

Вы можете обновить то же самое для работы в Java.

Python:

def cancelPrintPreview():
    # get the current time and add 180 seconds to wait for the print preview cancel button
    endTime = time.time() + 180
    # switch to print preview window
    driver.switch_to.window(driver.window_handles[-1])
    while True:
        try:
            # get the cancel button
            cancelButton = driver.execute_script(
                "return document.querySelector('print-preview-app').shadowRoot.querySelector('#sidebar').shadowRoot.querySelector('print-preview-header#header').shadowRoot.querySelector('paper-button.cancel-button')")
            if cancelButton:
                # click on cancel
                cancelButton.click()
                # switch back to main window
                driver.switch_to.window(driver.window_handles[0])
                return True
        except:
            pass
        time.sleep(1)
        if time.time() > endTime:
            driver.switch_to.window(driver.window_handles[0])
            break

Java

  public void closePrintPreview() {
        String jsCancel = "return document.querySelector('print-preview-app')" +
                ".shadowRoot.querySelector('#sidebar')" +
                ".shadowRoot.querySelector('print-preview-header#header')" +
                ".shadowRoot.querySelector('paper-button.cancel-button')";
        WebDriverWait wait = new WebDriverWait(driver, 5);
        JavascriptExecutor jse = (JavascriptExecutor) driver;
        WebElement cancelButton;

        wait.until(driver -> driver.getWindowHandles().size() > 1);
        driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[1]);

        while (driver.getWindowHandles().size() > 1) {
            driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[1]);
            cancelButton = (WebElement) jse.executeScript(jsCancel);
            cancelButton.click();
        }

        driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[0]);
    }

Вы можете проверить мой ответ здесь для получения дополнительной информации о работе с теневыми корневыми элементами.

0 голосов
/ 20 июня 2019

Вот реализация Java, основанная на ответе @supputuri:

  public void closePrintPreview() {
        String jsCancel = "return document.querySelector('print-preview-app')" +
                ".shadowRoot.querySelector('#sidebar')" +
                ".shadowRoot.querySelector('print-preview-header#header')" +
                ".shadowRoot.querySelector('paper-button.cancel-button')";
        WebDriverWait wait = new WebDriverWait(driver, 5);
        JavascriptExecutor jse = (JavascriptExecutor) driver;
        WebElement cancelButton;

        wait.until(driver -> driver.getWindowHandles().size() > 1);
        driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[1]);

        while (driver.getWindowHandles().size() > 1) {
            driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[1]);
            cancelButton = (WebElement) jse.executeScript(jsCancel);
            cancelButton.click();
        }

        driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[0]);
    }
...