Skip to main content
 首页 » 编程设计

c#之selenium webdriver (c#)之遍历选择菜单的最佳方式之然后验证元素样式更新

2024年02月01日27xxx_UU

我想遍历选择菜单中的所有可用选项,依次单击每个选项,然后验证单击每个选项是否会更新具有宽度和高度值的特定元素。

这是选择菜单的代码:

 <span id="SizeSelectContainer" class="dropdownButton" style="min-width: 100px; max-width: 120px;"> 
            <select id="SizeSelect" title="Zoom" tabindex="23" data-l10n-id="zoom" style="min-width: 126px;"> 
                <option id="SizeAutoOption" title="" value="auto" selected="selected" data-l10n-id="pagesizeauto">Automatic Size</option> 
                <option id="SizeActualOption" title="" value="page-size-actual" data-l10n-id="pagesizeactual">Actual Size</option> 
                <option title="" value="0.1">10</option> 
                <option title="" value="0.5">50</option> 
                <option title="" value="1">100</option>                          
            </select> 
        </span> 

当我单击每个选项时,位于页面其他位置的另一个元素中的值将发生变化(见下文)- 选择时没有任何“已选择”属性应用于任何下拉选项(默认选项除外) ) 所以我不能断言基于“选定”属性的选择。

我要做的(我还没有在我的示例中编码)是当一个特定的选择选项被选中时,另一个页面元素(如下所示)将更新以保持新的宽度和高度值:

<div id="Container" class="page" style="width: 547px; height: 865px; data-loaded="true"> 

这是我到目前为止的想法 - 请注意,我知道我还没有断言任何东西

        IWebElement AutoSize = UtilityClass.driver.FindElement(By.Id("SizeAutoOption")); 
        IWebElement ActualSize = UtilityClass.driver.FindElement(By.Id("SizeActualOption")); 
 
        IWebElement Ten = UtilityClass.driver.FindElement(By.XPath("//*[@id='SizeSelect']/option[3]")); 
        IWebElement Fifty = UtilityClass.driver.FindElement(By.XPath("//*[@id='SizeSelect']/option[4]")); 
        IWebElement Hundred = UtilityClass.driver.FindElement(By.XPath("//*[@id='SizeSelect']/option[5]"));   
 
        Object[] SelectElements = new Object[] { AutoSize, ActualSize, Ten, Fifty, Hundred }; 
 
        for (int i = 0; i < SelectElements.Count(); i++) 
        { 
            if (i == 0) 
            { 
                AutoSize.Click(); 
                System.Threading.Thread.Sleep(1000); 
            } 
            else if (i == 1) 
            { 
                ActualSize.Click(); 
                System.Threading.Thread.Sleep(1000); 
            } 
            else if (i == 2) 
            { 
                Ten.Click(); 
                System.Threading.Thread.Sleep(1000); 
            } 
            else if (i == 3) 
            { 
                Fifty.Click(); 
                System.Threading.Thread.Sleep(1000); 
            } 
            else if (i == 4) 
            { 
                Hundred.Click(); 
                System.Threading.Thread.Sleep(1000); 
            } 
         } 

我真的只是想确认一下这是否是解决此问题的最佳方法。我问的原因是我基本上简化了上面的代码示例,实际上我有 50 多个选择选项要验证 - 更不用说我还有许多其他选择菜单,其中包含尽可能多的选项以实现自动化。

请您参考如下方法:

这里有几个问题。

首先是 for 循环不是您想要的。

第二个是 Selenium 在 SelectElement 类中为您包装了所有“在选择中找到一个选项”功能,因此您不必一开始就这样做:

第三个是您的 XPath 构造在很大程度上基于位置。位置不好,因为它是可以改变的。如果我在该列表的最顶部添加一个选项,您的测试将会中断,但它不应该。我没有破坏应用程序功能,只是更改了列表顺序,您的测试将失败。

第四个问题是您持有对您的元素的引用,并且您已经说过当您单击该选项时页面将发生变化。这可能会导致 StaleReferenceException,具体取决于点击的实际操作。我说可能是因为它不应该但是如果你的应用程序被编码来做一些导致Selenium认为“对此的引用不再有效”的事情,它会抛出异常.

第五个问题是您正在遍历一个不必要的 object 数组。你知道他们的类型。它是 IWebElement。如果您只是将它定义为 Object,您就没有利用类的力量。

最后一个问题是您正在使用 Thread.Sleep。您显然正在等待某事,因此使用 Selenium 中的显式等待来实际等待某事,而不是“让我们等几秒钟”。

https://github.com/SeleniumHQ/selenium/blob/master/dotnet/src/support/UI/SelectElement.cs

(记住 Selenium 是开源的)

SelectElement actualSizeSelect = new SelectElement(UtilityClass.driver.FindElement(By.Id("SizeSelect"))); 

这使您能够按文本进行搜索:

actualSizeSelect.SelectByText("10"); 

现在您的测试不会关心“10”在列表中的确切位置!

这也让您能够循环遍历给定 select 中的所有选项,如下所示:

IList<IWebElement> options = actualSizeSelect.AllOptions; 

您现在在 select 中有了一个 option 列表。所以让我们遍历它们:

foreach (IWebElement option in options)  
{ 
    option.Click(); // just a demo to show you. 
}