【问题标题】:Selenium C# Webdriver Dropdown Doesn't Fire JavascriptSelenium C# Webdriver Dropdown 不会触发 Javascript
【发布时间】:2011-08-09 11:05:11
【问题描述】:

我正在使用 Seleniunm 测试我的网页。

我有一个下拉框,我想为其选择一个选项。这会触发一些 Ajax 来获取相关单元的一些数据。

当我正常查看页面时,这工作正常,但使用 selenium 会更改文本框中的选项,但不会触发 Ajax。

页面上的标记:

<select id="measure" name="measure">
    <option selected="selected" value="1">Metric</option>
    <option value="2">US Imperial</option>
    <option value="3">UK Imperial</option>
</select>

C#代码:

var dropDown = WebDriver.FindElementById("measure");
var selectElement = new SelectElement(dropDown);
selectElement.SelectByValue("3");

在选择/单击下拉选项方面我缺少什么?

谢谢

【问题讨论】:

    标签: c# ajax selenium webdriver


    【解决方案1】:

    我最近在使用 FirefoxDriver 时遇到了同样的问题。在我的特定设置中,我在 &lt;html&gt; 标签上有一个冒泡的委托“更改”事件处理程序,但没有触发:

    document.documentElement.addEventListener("change", handleChange, false);
    
    function handleChange(event) {
        // do stuff
    }
    

    即使在下拉列表中,以下代码也没有触发 onchange:

    SelectElement select = new SelectElement(element);
    
    select.SelectByText("Foo");
    

    该选项将被选中,但甚至没有触发任何更改——即使将焦点设置到另一个表单字段也是如此。在触发更改事件之前,我使用自己的鼠标在下拉列表中选择了一个新值。

    我通过单击下拉菜单,然后单击其中的选项来解决此问题:

    IWebElement element = // ...
    
    element.Click();
    
    element.FindElements(By.TagName("option"))
           .Single(opt => opt.Text == Value)
           .Click();
    

    这是一个方便的扩展方法,可以做同样的事情:

    public static class IWebElementExtensions
        /// <summary>
        /// Selects an option in a dropdown list by visible option text.
        /// </summary>
        /// <param name="element"></param>
        /// <param name="optionText"></param>
        public static void SelectOptionByText(this IWebElement element, string optionText)
        {
            if (element == null)
                throw new ArgumentNullException("element");
    
            if (element.TagName != "select")
                throw new ArgumentException("The element must be a <select> tag");
    
            if (optionText == null)
                throw new ArgumentNullException("optionText");
    
            var options = element.FindElements(By.TagName("option"))
                                 .Where(opt => opt.Text == optionText);
    
            if (options.Count() == 0)
                throw new NoSuchElementException("Could not find <option>" + optionText + "</option> inside <select id=\"" + element.GetAttribute("id") + "\">");
    
            if (options.Count() > 1)
                throw new WebDriverException("Too many <option>" + optionText + "</option> tags inside <select id=\"" + element.GetAttribute("id") + "\">");
    
            element.Click();
            options.Single().Click();
            element.Click();
        }
    }
    

    并使用:

    element.SelectOptionByText("Foo");
    

    好处

    • 没有 JavaScript hack
    • 在 Selenium 中使用原生事件

    缺点

    • 执行时间稍长

    【讨论】:

      【解决方案2】:

      我使用 FirefoxDriver 而不是 InternetExplorer 驱动程序,现在一切正常。

      【讨论】:

      • 我正在使用 FirefoxDriver,但它无法正常工作。
      【解决方案3】:

      我发现使用 jQuery 比 WebDriver 的 SelectElement 类效果更好。

      试试这个。请注意我是如何调用 jQuery .change 事件(JavaScript onchange 事件)的。我有另一个依赖于此下拉列表的下拉列表,因此为了填充依赖下拉列表,我必须调用该事件。为了让它工作,我还必须为我的 Firefox 驱动程序启用本机事件。我看到您是按值选择,而不是按选项文本。您应该能够使用可用于按值选择的代码来修改我的 jQuery 代码。此外,如果您使用 ASP.NET 控件,则使用 WebDriver 的代码将无法正常工作,因为 id 基于浏览器是动态的。因此,您必须使用客户端 ID 通过 jQuery 获取 ID。如果您是这种情况,我也在下面粘贴了该代码。

      public static void SetDropdownSelectedOptionValue(IWebDriver driver, string tagId, string newValue)
      {
          //new SelectElement(driver.FindElement(By.Id("book-country_id"))).SelectByText(newValue);
      
          IJavaScriptExecutor js = driver as IJavaScriptExecutor;
          js.ExecuteScript("$('#" + tagId + " option:contains(" + newValue + ")').attr('selected', 'selected')");
          js.ExecuteScript("$('#" + tagId + "').change()");
          //driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(Config.WAIT_TIME));
          System.Threading.Thread.Sleep(1000);
      }
      

      在调用 onchange 原生事件时是必需的。

      FirefoxProfile firefoxProfile = new FirefoxProfile();
      firefoxProfile.EnableNativeEvents = true;
      

      如果使用 ASP.NET 控件,请使用此 jQuery 代码而不是显式 ID。当然修改这段代码,把 tagId 放在中间来获取 jQuery 选择器。

      $('#<%=dropdownid.ClientID %>')
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-07
        • 2019-06-14
        相关资源
        最近更新 更多