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

时间:2018-06-05 09:44:11

标签: c# selenium-webdriver

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

我需要选择证书并点击“确定”。

有人可以帮忙吗?

以下是我正在使用的代码:

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

1 个答案:

答案 0 :(得分:0)

你没有提到你正在使用什么浏览器,但这是我为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.");
            }
        }
    }
}