Selenium Webdriver 无法在下拉列表中选择值

Selenium Webdriver cannot choose a value in a dropdown list

我正在尝试使用 Java 实现 Selenium Webdriver。 基本上,我有一个空白字段的网站。用户单击该字段后,将出现一个包含 5 个选项的下拉列表,用户应选择一个选项。

代码如下所示

<!-- language: lang-html -->
<div class="default-form w-border scheduleAddFrom" style="display: block;">
<div>
<div class="section frameless nopadding nomargin" data-form-element="SectionHeading" style="min-width: 100%;">
<div class="section-body frameless nopadding nomargin">
<div class="default-form">
<div class="form-row required-message hidden" style="min-height: 25px;">
<div class="form-row print-avoid-page-break" data-form-element="FieldEdit" style="min-height: 25px;">
<label for="">Department</label>
<input id="Schedule-00-Row136153aa-9fa8-499b-8458-2b155443223bE-TaskId-Display" class="ui-autocomplete-display validate widget" type="text" autocomplete="off">
<span class="ui-autocomplete-display-icon"></span>
<div class="subhidden">
<select id="Schedule-00-Row136153aa-9fa8-499b-8458-2b155443223bE-TaskId" class="validate widget " data-default-value="" tabindex="5000" data-display-id="Schedule-00-Row136153aa-9fa8-499b-8458-2b155443223bE-TaskId-Display">
   <option value=""></option>
   <option value="OPT1">Option 1</option>
   <option value="OPT2">Option 2</option>
   <option value="OPT3">Option 3</option>
   <option value="OPT4">Option 4</option>
   <option value="OPT5">Option 5</option>
</select>

我尝试使用这个 Java 代码来选择选项 2

WebDriverWait wait = new WebDriverWait(driver, 100);

wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".form-row.print-avoid-page-break>label")));

//Start to find the element. The ID is dynamically randomly generated by the system each time the page loads except the last part TaskID, thus looking for the string TaskID   
Select dropdown = new Select (driver.findElement(By.xpath(".//*[contains(@id,'TaskId')]"))); 

dropdown.selectByValue("OPT2");

Seleniumreturns错误

org.openqa.selenium.ElementNotVisibleException: element not visible: Element is not currently visible and may not be manipulated

我感觉这是由<div class="subhidden">引起的,但我不太确定。 非常感谢任何建议。谢谢。

测试了下面的代码块,看起来不错。 查看 html 可以合理地假设选择器不会唯一 return 意图元素。我相信您希望 Select 标签包含 id TaskId。只需简单地使用 //select[contains(@id,'TaskId')] 进行标签相关搜索,因为 <input id="Schedule-00-Row136153aa-9fa8-499b-8458-2b155443223bE-TaskId-Display" 也具有相同文本的 ID TaskId 并且继续我建议您在将其插入测试之前测试 xpath ,至少从我的经验来看。

WebDriverWait wait = new WebDriverWait(driver, 100);
By selectElementSelector = By.xpath("//select[contains(@id,'TaskId')]");
WebElement selectElement = wait.until(ExpectedConditions.presenceOfElementLocated(selectElementSelector));
Select dropdown = new Select (selectElement);
dropdown.selectByValue("OPT2");

编辑

另一个可能的选择是使用合适的选择器查找元素和选项。同样,您必须测试选择器以确保它是唯一的并且是您想要的。

WebDriverWait wait = new WebDriverWait(driver, 100);
String optionToSelect = "OPT1";
//Selector is the trick here
By selectElementSelector = By.cssSelector("select[id*='TaskId']>option[value='" + optionToSelect + "']");

wait.until(ExpectedConditions.presenceOfElementLocated(selectElementSelector)).click();

我的 2c 值...

我把上面 HTML 放到一个文件中,另存为 html 并在 FF 中打开。然后我使用 Selenium IDE 来记录下拉选择。一旦转换为 Java 我得到了这个:

 new Select(driver.findElement(By.id("Schedule-00-Row136153aa-9fa8-499b-8458-2b155443223bE-TaskId"))).selectByVisibleText("Option 2");

我测试了这个,它工作正常。

找到根本原因。我的感觉是正确的。是<div class="subhidden">造成的,因为是隐藏元素,Selenium无法触及。 (虽然不确定是否有任何解决方法来处理隐藏元素)。

网页有2层。第 1 层是可见的下拉框,最终用户可以在其中选择值。

第 1 层的 HTML 代码看起来像

    <!-- language: lang-html -->
<input id="Schedule-00-Row831efe50-8f53-4c0f-b9b0-9b622221c62cE-TaskId-Display" class="ui-autocomplete-display validate widget" type="text" autocomplete="off">
    <div class="ui-calendar">
    <ul class="ui-autocomplete-list hidden" style="opacity: 0; visibility: hidden; top: 347px; left: 213px;">
    <li class="visible " data-value=""></li>
    <li class="visible" data-value="OPT1">Option 1</li>
    <li class="visible" data-value="OPT2">Option 2</li>
    <li class="visible" data-value="OPT3">Option 3</li>
    <li class="visible" data-value="OPT4">Option 4</li>
    <li class="visible" data-value="OPT5">Option 5</li>

后面还有一层,看起来像这样

<!-- language: lang-html -->
<span class="ui-autocomplete-display-icon"></span>
<div class="subhidden">
<select id="Schedule-00-Row831efe50-8f53-4c0f-b9b0-9b622221c62cE-TaskId" class="validate widget " data-default-value="" tabindex="5000" data-display-id="Schedule-00-Row831efe50-8f53-4c0f-b9b0-9b622221c62cE-TaskId-Display">
<option value=""></option>
<option value="OPT1">Option 1</option>
<option value="OPT2">Option 2</option>
<option value="OPT3">Option 3</option>
<option value="OPT4">Option 4</option>
<option value="OPT5">Option 5</option>
</select>

所以用户会在第1层的下拉框中选择值,然后将选择的值传送到第2层的下拉框进行进一步处理。

我试图将 Selenium 编码为 select 第 2 层(隐藏的)下拉框中的值,但没有意识到还有可以单击的另一层。

知道根本原因后,Selenium 的代码就这么简单

<!-- language: lang-java -->
WebElement Box = driver.findElement(By.xpath(".//*[contains(@id,'TaskId-Display')]"));
Box.click();

WebElement List = driver.findElement(By.xpath("html/body/ul[1]/li[2]"));
DivisionList.click();

总而言之,我强迫 Selenium select 隐藏下拉列表中的一个值。

@Saifur,非常感谢您的讨论。

要单击不可见元素,请尝试使用操作。 首先单击 - 打开下拉列表。 Next - 将光标移动到元素的坐标,然后单击坐标。

Actions build = new Actions(driver);
By YourSelectItem = By.XPath("xPath to find");
By YourOptionToClick= By.XPath("xPath to find");
IWebElement el  =  driver.FindElement(YourSelectItem));
IWebElement el  =  driver.FindElement(YourOptionToClick));
build.MoveToElement(el).Click().MoveToElement(YourOptionToClick).Click().Build().Perform();

对不起 C#,我不能写 java 模拟 :)