C# 从从属下拉框Selenium web驱动程序中选择一个选项

C# 从从属下拉框Selenium web驱动程序中选择一个选项,c#,internet-explorer,selenium,driver,C#,Internet Explorer,Selenium,Driver,我的应用程序必须在IE中使用。我正在自动化测试,脚本首先必须在第一个下拉框中选择一个选项,类别,以获得在第二个下拉框中显示的类别相关选项,名称。然后,脚本在名称中选择一个选项,将显示一个关联的页面。 在类别中进行选择之前,名称没有任何选项。HTML来源: <select id="drop_Category"> <option value =""/> <option value = "Category1"> Text - Category1

我的应用程序必须在IE中使用。我正在自动化测试,脚本首先必须在第一个下拉框中选择一个选项,类别,以获得在第二个下拉框中显示的类别相关选项,名称。然后,脚本在名称中选择一个选项,将显示一个关联的页面。 在类别中进行选择之前,名称没有任何选项。HTML来源:

<select id="drop_Category">
   <option value =""/>
   <option value = "Category1">
     Text - Category1
   <option value = "Category2">
     Text - Category2
<select id="drop_Name">
这段代码不起作用,因为Name中的列表尚未加载,脚本无法找到文本为C1_Name3的选项,所以我添加了隐式等待。等待没有帮助,所以我试图捕捉异常。这是代码的第二个版本:

//Select option in drop-box "Category"
stringText = "Category1";
var dropCategory = new SelectElement(driver.FindElement(By.Id("drop_Category")));
dropCategory.SelectByText(stringText);

//Select option in drop-box "Name"
stringText = "C1_Name3"
try
{
   var dropName = new SelectElement(driver.FindElement(By.Id("drop_Name")));
   dropName.SelectByText(stringText);   
}
catch (NoSuchElementException)
{
   var dropName = new SelectElement(driver.FindElement(By.Id("drop_Name")));
   dropName.SelectByText(stringText);   
}
它工作正常,但有时仍会由于InvalidSelectorException或StaleElementReferenceException异常而崩溃。我不知道该怎么做才能使这项工作始终如一。另外,我是这个领域的新手,所以我不确定像我的第二个版本那样编写代码是否是一种不好的做法。非常感谢您的帮助。

初始方法

通常根据我的经验,除了等待时间方法外,还需要睡眠时间;所以试着把两者结合起来

例如,我会尝试循环,直到找到所需的元素。伪代码如下:

从中,当用于查找元素的选择器未返回WebElement时,也会引发该异常。因此,捕捉无接触异常就足够了

替代方法

从您的问题开始就存在于代码中。 因此,driver.findElement将始终通过ID drop\u Name查找WebElement 区别在于,在选择Category1之前,drop_Name没有值。 因此,您可以尝试以下等待功能: 注意:代码是用Java编写的;可以很容易地移植到C

private static void waitUntilOptionsLoad() {
    while(true) {
        Thread.sleep(1000);
        List<WebElement> options = driver.findElement(By.id("drop_Name"))
                        .findElements(By.tagName("option"));
        if (options.size() > 0 ) { 
            System.out.println("More than one option tag found; therefore options have loaded");
            break;
        }
}

如果元素需要时间才能显示并可用,为什么不使用显式等待?谢谢。我结合了两种方法:首先使用wait函数确保加载名称列表,然后在Name中尝试选择并捕获任何其他异常,而不使用try..catch,有时会出现错误元素不再有效。它起作用了。我有一个循环,20多个这种类型的测试运行良好。
//Select option in drop-box "Category"
stringText = "Category1";
var dropCategory = new SelectElement(driver.FindElement(By.Id("drop_Category")));
dropCategory.SelectByText(stringText);

//Select option in drop-box "Name"
stringText = "C1_Name3"
try
{
   var dropName = new SelectElement(driver.FindElement(By.Id("drop_Name")));
   dropName.SelectByText(stringText);   
}
catch (NoSuchElementException)
{
   var dropName = new SelectElement(driver.FindElement(By.Id("drop_Name")));
   dropName.SelectByText(stringText);   
}
boolean found = false;
while (!found) {
try
{
   var dropName = new SelectElement(driver.FindElement(By.Id("drop_Name")));
   dropName.SelectByText(stringText);
   found = true;  
}
catch (NoSuchElementException)
{
   var dropName = new SelectElement(driver.FindElement(By.Id("drop_Name")));
   dropName.SelectByText(stringText); 
   //do a short sleep here e.g. 500ms depending on the speed of your site  
}

}
private static void waitUntilOptionsLoad() {
    while(true) {
        Thread.sleep(1000);
        List<WebElement> options = driver.findElement(By.id("drop_Name"))
                        .findElements(By.tagName("option"));
        if (options.size() > 0 ) { 
            System.out.println("More than one option tag found; therefore options have loaded");
            break;
        }
}