web-dev-qa-db-ja.com

Chromedriverヘッドレスアラート

この問題は、chromedriverを使用したSelenium webdriverテストで発生します。 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
12
Alex Pas

Chrome 61)の時点でまだこの問題が発生しているので、別の解決策を探すのにしばらく時間を費やしました。簡単なのは、アラートが表示される前にJavaScriptを挿入してアラートを自動的に受け入れることです。 。

次のコード行を挿入するだけですbeforeアラートを表示させる行:

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

ヘッドレスchromeとPhantomJSの両方で動作します。

16

ヘッドレスクロムを実行すると、同じ問題が発生するようです。スクリーンショットに基づいてアラートウィンドウがポップアップしません。 chromeでは正常に機能しますが、ヘッドレスクロムでは機能しません。

chrome 60.0.3112.72 and chrome driver 2.30

ヘッドレスchromeはアラートを自動的に破棄するため、これを確認してください: https://bugs.chromium.org/p/chromium/issues/detail?id=718235


ところで、ヘッドレスモードでchrome 59でスクリーンショットを作成できるのはなぜですか?chrome 59には、すべてのスクリーンショットがヘッドレスモードで1x1ピクセルの画像になるというバグがあります、chrome 60にアップグレードしました。

3
Luyao Zhou

Chrome headlessは(現在のところ)アラートをサポートしていないため、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();
1
Ken Smith

誰かが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; }})
0
ChaBuku Bakke