Selenium C#如何选择Choices组件的下拉选项?
解决Choices组件下拉框无法选中选项的问题
我在UI中使用了基于Choices组件实现的单选下拉框,其HTML结构如下:
<div class="choices form-group form-choices" data-type="select-one" dir="ltr" tabindex="-1" role="listbox" aria-haspopup="true" aria-expanded="false"> <div class="form-control ui fluid selection dropdown" tabindex="0"> <select lang="en" class="form-control choices__input" type="text" name="data[serviceAmpsDelivered]" ref="selectContainer" dir="ltr" hidden="" tabindex="-1" data-choice="active"> <option value="6"><span>60</span></option> </select> <div class="choices__list choices__list--single"> <div class="choices__item choices__item--selectable" data-item="" data-id="38" data-value="6" data-custom-properties="null" aria-selected="true" data-deletable=""> <span>60</span> <button type="button" class="choices__button" aria-label="Remove item: '6'" data-button="">Remove item</button> </div> </div> </div> <div class="choices__list choices__list--dropdown" aria-expanded="false"> <div class="choices__list" role="listbox"> <div id="choices--data-oa-item-choice-1" class="choices__item choices__item--choice choices__item--selectable is-highlighted" role="option" data-choice="" data-id="1" data-value="1" data-select-text="" data-choice-selectable="" aria-selected="true"> <span>50</span> </div> <div id="choices--data-oa-item-choice-2" class="choices__item choices__item--choice choices__item--selectable " role="option" data-choice="" data-id="2" data-value="6" data-select-text="" data-choice-selectable=""> <span>60</span> </div> <div id="choices--data-oa-item-choice-3" class="choices__item choices__item--choice choices__item--selectable " role="option" data-choice="" data-id="3" data-value="2" data-select-text="" data-choice-selectable=""> <span>100</span> </div> <div id="choices--data-oa-item-choice-4" class="choices__item choices__item--choice choices__item--selectable " role="option" data-choice="" data-id="4" data-value="5" data-select-text="" data-choice-selectable=""> <span>150</span> </div> <div id="choices--data-oa-item-choice-5" class="choices__item choices__item--choice choices__item--selectable " role="option" data-choice="" data-id="5" data-value="3" data-select-text="" data-choice-selectable=""> <span>200</span> </div> <div id="choices--data-oa-item-choice-6" class="choices__item choices__item--choice choices__item--selectable " role="option" data-choice="" data-id="6" data-value="4" data-select-text="" data-choice-selectable=""> <span>400</span> </div> </div> </div> </div>
目前我可以通过代码点击打开该下拉框,但无法选中其中的选项,当前使用的C#代码如下:
WebElement element= (WebElement)driver.FindElement(By.XPath("/html/body/div[1]/div/div[1]/app/div/div[2]/div[2]/div/div[2]/app/div/div/div/div[2]/div[2]/div[2]/app/div/div/div/forms-app/div/div/div/div[1]/div[1]/div[1]/div[2]/div[2]/div[1]/div[1]")); Helper.JavaScriptClick(_driver, element); WebElement elementValue= (WebElement)driver.FindElement(By.XPath("/html/body/div[1]/div/div[1]/app/div/div[2]/div[2]/div/div[2]/app/div/div/div/div[2]/div[2]/div[2]/app/div/div/div/app/div/div/div/div[1]/div[1]/div[1]/div[2]/div[2]/div[1]/div[2]/div/div[4]")); Helper.JavaScriptClick(_driver, elementValue);
解决方案
1. 替换脆弱的绝对XPath定位
绝对XPath极易受DOM结构变化影响,改用基于组件类名和属性的相对定位:
// 定位Choices下拉框容器 var dropdownContainer = driver.FindElement(By.CssSelector(".choices.form-choices")); Helper.JavaScriptClick(_driver, dropdownContainer); // 等待下拉列表展开并定位目标选项(以选中"150"为例,对应data-value="5") var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); var targetOption = wait.Until(ExpectedConditions.ElementIsVisible(By.CssSelector(".choices__list--dropdown .choices__item[data-value='5']")));
2. 触发完整的点击事件
部分自定义组件需要完整的鼠标事件序列才能触发选中逻辑,替换JavaScriptClick为原生点击或模拟多事件:
// 优先使用原生Click targetOption.Click(); // 如果原生点击无效,用JavaScript触发完整事件序列 IJavaScriptExecutor js = (IJavaScriptExecutor)driver; js.ExecuteScript(@" var event = new MouseEvent('mousedown', {bubbles: true}); arguments[0].dispatchEvent(event); var event2 = new MouseEvent('mouseup', {bubbles: true}); arguments[0].dispatchEvent(event2); var event3 = new MouseEvent('click', {bubbles: true}); arguments[0].dispatchEvent(event3); ", targetOption);
3. 直接操作原生隐藏select元素
Choices组件基于原生select封装,可直接操作隐藏的select元素同步组件状态:
// 定位隐藏的select元素 var hiddenSelect = driver.FindElement(By.CssSelector("select.choices__input[name='data[serviceAmpsDelivered]']")); // 设置目标value hiddenSelect.SendKeys("5"); // 触发change事件通知组件更新 IJavaScriptExecutor js = (IJavaScriptExecutor)driver; js.ExecuteScript("arguments[0].dispatchEvent(new Event('change'));", hiddenSelect);
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

