chromedriver безголовый оповещения

у меня есть эта проблема с тестами selenium webdriver с chromedriver. Хотя я могу успешно запускать тесты при использовании браузера Chrome, я не могу запускать те же тесты в безголовом режиме.

Я не могу обрабатывать оповещения Js. На самом деле при снятии скриншота кажется, что предупреждение даже не всплывает.

оповещения скриншоты

Я пробовал несколько обходных путей:

1) driver.window_handles --> никакое другое окно не кажется настоящее

2) driver.execute_script("window.confirm = function(){return true;}") --> ничего не изменилось с этим скриптом

3) element = WebDriverWait(driver, 20).until(EC.alert_is_present()) и конечно явное ждать

в режиме браузера я использую простой:

try:
    print driver.switch_to.alert.text
    driver.switch_to.alert.accept()
except NoAlertPresentException as e: 
    print("no alert")

кто - нибудь еще имеет эту проблему с предупреждениями в безголовом режиме?

  • chromedriver V. 2.30.477691
  • Chrome Версия 59.0.3071.115

4 ответов


все еще имея эту проблему с Chrome 61, поэтому я потратил некоторое время на поиск другого решения. Мой любимый из-за его простоты вводит javascript до того, как предупреждение будет показано, чтобы автоматически принять предупреждение.

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

driver.ExecuteJavaScript("window.confirm = function(){return true;}");

работает как с безголовым хромом, так и с PhantomJS.


кажется, что у меня такая же проблема при запуске headless chrome. Окно предупреждения не всплывает на основе снимков экрана. Он отлично работает на chrome, но не безголовый chrome.

Я работаю на chrome 60.0.3112.72 и драйвер хром 2.30

потому что безголовый chrome автоматически отбрасывает предупреждения. проверить это: https://bugs.chromium.org/p/chromium/issues/detail?id=718235


кстати, как вы можете скриншот в chrome 59 в безголовом режиме? chrome 59 имеет ошибку, которая делает каждый снимок экрана 1x1 пиксельным изображением в безголовом режиме, поэтому я обновился до chrome 60.


поскольку Chrome безголовый не поддерживает (в настоящее время) оповещения, вы должны monkeypatch alert() и confirm() методы. Это подход, который я использовал (в C#):

    /// <summary>
    /// The Chrome Headless driver doesn't support alerts, so we need to override the window.alert method to get the expected behavior.
    /// </summary>
    /// <param name="driver">The active IWebDriver instance</param>
    /// <param name="result">The result that the alert should return, i.e., true if we want it "accepted", false if we don't</param>
    public static void SetupAlert(this IWebDriver driver, bool result)
    {
        // ks 7/27/17 - The Chrome Headless driver doesn't support alerts, so override the various window.alert methods to just set 
        const string scriptTemplate = @"
window.alertHandlerCalled = false;
window.alertMessage = null;
window.alert = window.confirm = function(str) {
    window.alertHandlerCalled = true;
    window.alertMessage = str;
    return {{result}};
};";

        var script = scriptTemplate.Replace("{{result}}", result.ToString().ToLower());
        var js = (IJavaScriptExecutor)driver;
        js.ExecuteScript(script);
    }

    /// <summary>
    /// This is an optional accompaniment to the <see cref="SetupAlert"/> method, which checks to see
    /// if the alert was, in fact, called. If you don't want to bother to check, don't worry about calling it.
    /// Note that this doesn't reset anything, so you need to call <see cref="SetupAlert"/> each time before calling
    /// this method.
    /// </summary>
    public static void WaitForAlert(this IWebDriver driver, TimeSpan? timeout = null)
    {
        const string script = @"return window.alertHandlerCalled";
        var js = (IJavaScriptExecutor)driver;
        var timeToBail = DateTime.Now.Add(timeout ?? TimeSpan.FromMilliseconds(500));
        while (DateTime.Now < timeToBail)
        {
            var result = (bool)js.ExecuteScript(script);
            if (result) return;
            Thread.Sleep(100);
        }
        throw new InvalidOperationException("The alert was not called.");
    }

Я использую его так:

        Driver.SetupAlert(true);
        this.ClickElement(ResetButton);
        Driver.WaitForAlert();

просто хотел добавить это в случае, если кто-то столкнется с этой проблемой, используя NightwatchJS.

выше принятое решение работало для меня, но с помощью JS ему потребовалась небольшая модификация от

driver.ExecuteJavaScript("window.confirm = function(){return true;}");

мне нужно было изменить его на

// this.api.perform() in my case is the same as browser.perform() 
this.api.perform(function () { this.confirm = function () { return true; }})