Selenium c# Webdriver下拉菜单不会触发Javascript

本文关键字:Javascript Webdriver 下拉菜单 Selenium | 更新日期: 2023-09-27 18:04:50

我正在使用selenium来测试我的网页。

我有一个下拉框,我想为它选择一个选项。这将触发一些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");

在选择/单击下拉选项方面,我错过了什么?

谢谢

Selenium c# Webdriver下拉菜单不会触发Javascript

我最近使用FirefoxDriver时遇到了同样的问题。在我的特定设置中,我在<html>标记上有一个冒泡委托的"更改"事件处理程序,该处理程序没有触发:

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攻击
  • 使用Selenium中的本地事件

缺点

  • 执行时间稍长一些

我用的是FirefoxDriver而不是InternetExplorer Driver,现在看起来一切正常。

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

试试这个。注意我是如何调用jQuery .change事件(JavaScript的onchange事件)的。我有另一个依赖于这个下拉菜单的下拉菜单,为了让这个依赖的下拉菜单填充,我必须调用那个事件。为了让它工作,我还必须为我的Firefox驱动程序启用Native Events。我看到你在按值选择,而不是按选项文本。您应该能够修改我的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 %>')