C# 未使用Safari浏览器上的Selenium Webdriver选择下拉列表

C# 未使用Safari浏览器上的Selenium Webdriver选择下拉列表,c#,selenium-webdriver,safari,webdriver,safaridriver,C#,Selenium Webdriver,Safari,Webdriver,Safaridriver,在Safari浏览器上,我需要从下拉列表中选择一个选项,但有趣的是,它适用于除Mac OS上Safari之外的所有浏览器。 我将Safari 10.0.3与selenium webdriver版本3.3.0一起使用 我已经用C写了代码。请参考下面的代码- IWebDriver driver; driver = new SafariDriver(); List<string> handles = driver.WindowHandles.ToList<st

在Safari浏览器上,我需要从下拉列表中选择一个选项,但有趣的是,它适用于除Mac OS上Safari之外的所有浏览器。 我将Safari 10.0.3与selenium webdriver版本3.3.0一起使用

我已经用C写了代码。请参考下面的代码-

    IWebDriver driver;
    driver = new SafariDriver();
    List<string> handles = driver.WindowHandles.ToList<string>();
    driver.SwitchTo().Window(handles.First());
    driver.Navigate().GoToUrl("https://myip/MyPage.aspx");
    SelectElement element = new SelectElement(driver.FindElement(By.Id("securityQuestion")));
    int totalOptions = element.Options.Count;
    Random rnd = new Random();
    int rndValue = rnd.Next(1, totalOptions);
    element.SelectByIndex(rndValue); // This is not working for Safari browser      
    driver.FindElement(By.Id("securityAnswer")).SendKeys("test");
    driver.FindElement(By.Id("ctl00_Content_btnNext")).Click();
    driver.Close();

不会抛出错误,只是它没有从下拉列表中选择任何值。

这是safaridriver错误。修复程序位于WebKit中,并在此处跟踪:


作为一种变通方法,您可以使用JavaScript和DOM API修改选择的选项。

在这里尝试这个JS变通方法示例-作为C扩展实现。此代码适用于在版本10.1+上测试的Safari

这不是完整的代码,只是一个简单的片段。您可以扩展它以支持您喜欢的任何功能

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Internal;
using OpenQA.Selenium.Support.UI;

namespace Gravity.Plugins.Actions.Extensions
{
    public static class SelectExtensions
    {
        /// <summary>
        /// Select the option by the index, as determined by the "index" attribute of the
        /// element.
        /// </summary>
        /// <param name="selectElement">This <see cref="SelectElement"/>.</param>
        /// <param name="index">The value of the index attribute of the option to be selected.</param>
        public static void JsSelectByIndex(this SelectElement selectElement, int index)
        {
            // constants
            var script = $"options[{index}].selected = true;";

            // web element to act on
            var onElement = selectElement.WrappedElement;
            var onDriver = (IWrapsDriver)onElement;

            // execute
            ((IJavaScriptExecutor)onDriver).ExecuteScript(script, onElement);
        }

        /// <summary>
        /// Select all options by the text displayed.
        /// </summary>
        /// <param name="selectElement">This <see cref="SelectElement"/>.</param>
        /// <param name="text">The text of the option to be selected.</param>
        public static void JsSelectByText(this SelectElement selectElement, string text)
        {
            // constants
            var script =
                "var options = arguments[0].getElementsByTagName('option');" +
                "" +
                "for(i = 0; i < options.length; i++) {" +
                $"   if(options[i].innerText !== '{text}') {{" +
                "       continue;" +
                "    }" +
                "    options[i].selected = true;" +
                "    break;" +
                "}";

            // web element to act on
            var onElement = selectElement.WrappedElement;
            var onDriver = (IWrapsDriver)onElement;

            // execute
            ((IJavaScriptExecutor)onDriver).ExecuteScript(script, onElement);
        }

        /// <summary>
        /// Select an option by the value.
        /// </summary>
        /// <param name="selectElement"></param>
        /// <param name="value">The value of the option to be selected.</param>
        public static void JsSelectByValue(this SelectElement selectElement, string value)
        {
            // constants
            var script =
                "var options = arguments[0].getElementsByTagName('option');" +
                "" +
                "for(i = 0; i < options.length; i++) {" +
                $"   if(options[i].getAttribute('value') !== '{value}') {{" +
                "       continue;" +
                "    }" +
                "    options[i].selected = true;" +
                "    break;" +
                "}";

            // web element to act on
            var onElement = selectElement.WrappedElement;
            var onDriver = (IWrapsDriver)onElement;

            // execute
            ((IJavaScriptExecutor)onDriver).ExecuteScript(script, onElement);
        }
    }

    // Usage sample
    public class MySeleniumClass
    {
        public void DoAutomation()
        {
            var driver = new ChromeDriver()
            {
                Url = "https://gravitymvctestapplication.azurewebsites.net/UiControls"
            };
            var element = driver.FindElement(By.Id("select_menu"));
            var selectElement = new SelectElement(element);
            selectElement.JsSelectByIndex(1);
            selectElement.JsSelectByText("Two");
            selectElement.JsSelectByValue("3");
        }
    }
}

这是时间问题吗?也许Mac上的Safari很慢。在SelectElement行上放置断点,然后单步执行。它有用吗?如果是这样,您需要添加一些等待。如果在您完成所有操作后,它都不起作用,那么使用sendKeys按可见文本进行选择如何。@GaurangShah尝试了,但接下来的代码行没有显示出来executed@RohitN. 你说不执行是什么意思?它跳过了吗??它抛出了任何异常吗?@Gaurang no exception只是跳过代码执行,但这只发生在safari浏览器上,其余的都可以,事实上,即使Mac OS上的chrome浏览器也可以毫无问题地运行它