繁体   English   中英

我在C#中使用Selenium Webdriver,无法在证书弹出窗口中单击“确定”

[英]I am using selenium webdriver in C#, I am unable to click ok in the certificate pop-up

我正在尝试选择使用C#代码弹出的证书,但无法选择弹出窗口并单击“确定”。

我需要选择证书,然后单击“确定”。

有人可以帮忙吗?

这是我正在使用的代码:

//driver.SwitchTo().Alert().Accept();
//IAlert popup = driver.SwitchTo().Alert();
//popup.Accept();

您没有提及正在使用的浏览器,但这是我为IE执行的操作。 我实际上不能直接使用Selenium,但是我可以使用Windows自动化系统来运行它,该系统通常由辅助功能软件(如屏幕阅读器)使用。

此代码特定于IE,如果您使用其他浏览器,则必须对其进行调整。

using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Automation;

namespace Application.Automation.WindowsDesktop.Interactions
{
    using System.Diagnostics;
    using System.Linq;
    using System.Windows.Forms;

    public static class DesktopInteractions
    {
        private static Int32 WM_KEYDOWN = 0x100;
        private static Int32 WM_KEYUP = 0x101;

        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("user32.dll", SetLastError = true)]
        static extern bool PostMessage(IntPtr hWnd, int Msg, System.Windows.Forms.Keys wParam, int lParam);

        /// <summary>
        /// This method attempts to interact with the IE Security Certificate Window
        /// <exception> Throws InvalidOperationException if it can not locate the window or the submit control </exception>
        /// </summary>
        public static void HandleWindowsSecurityWindow(string certificateName)
        {
            AutomationElement securityCertificateWindow = null;

            int waitSeconds = 1;
            int currentAttempt = 0;
            int maximumAttempts = 300;

            //Find Security Window
            AutomationElement certificateWindow = null;
            while (currentAttempt <= maximumAttempts && certificateWindow == null)
            {
                Debug.WriteLine("Searching for security window");
                var ieWindows = AutomationElement.RootElement
                                                 .FindAll(TreeScope.Children,
                                                          new PropertyCondition(AutomationElement.ControlTypeProperty,
                                                                                ControlType.Pane))
                                                 .Cast<AutomationElement>()
                                                 .Where(window => window.Current.Name.Contains("Internet Explorer"));

                Debug.WriteLine($"Found {ieWindows.Count()} IE windows");
                foreach (var window in ieWindows)
                {
                    Debug.WriteLine($"Looking for security window");
                    certificateWindow = window.FindFirst(TreeScope.Descendants,
                                                         new PropertyCondition(AutomationElement.ClassNameProperty,
                                                                               "#32770")) ??
                                        certificateWindow;
                }

                if (certificateWindow == null)
                {
                    Thread.Sleep((int) TimeSpan.FromSeconds(1)
                                               .TotalMilliseconds);
                }

                currentAttempt++;
            }

            if (certificateWindow != null)
            {
                Debug.WriteLine("Security window found");

                if (certificateName != null)
                {
                    // Select the certificate
                    Debug.WriteLine($"Searching for certificate named '{certificateName}'.");
                    var certificateListItem = certificateWindow.FindFirst(TreeScope.Descendants,
                                                                          new AndCondition(new PropertyCondition(AutomationElement.ControlTypeProperty,
                                                                                                                 ControlType.ListItem),
                                                                                           new PropertyCondition(AutomationElement.NameProperty,
                                                                                                                 certificateName)));
                    if (certificateListItem == null)
                    {
                        throw new ArgumentException($"No certificate found with the name '{certificateName}'.");
                    }

                    Debug.WriteLine("Certificate found");
                    // This is the only way I could "click" on the desired certificate.  Focus the item, then simulate pressing the space-bar.
                    certificateListItem.SetFocus();
                    PostMessage((IntPtr) certificateWindow.Current.NativeWindowHandle, WM_KEYDOWN, Keys.Space, 0);
                    PostMessage((IntPtr) certificateWindow.Current.NativeWindowHandle, WM_KEYUP, Keys.Space, 0);
                }
                else
                {
                    Debug.WriteLine("No certificate specified, using default.");
                }

                // Click to OK button
                Debug.WriteLine("Clicking OK");
                var okButton = certificateWindow.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "OK"));
                var click = (InvokePattern) okButton.GetCurrentPattern(InvokePattern.Pattern);
                click.Invoke();
            }
            else
            {
                throw new InvalidOperationException("Unable to get a handle on the Security certification window.");
            }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM