Selenium实现带复选框下拉菜单操作及仅获取选中项问题
Selenium Java: 仅获取下拉复选框中选中项的文本值
场景与需求
我们有一个包含多复选框的下拉菜单,部分复选框默认处于选中状态。需要用Selenium实现以下操作:
- 勾选/取消复选框
- 获取复选框对应的文本值
- 验证选中状态是否成功保存
但当前代码运行后会输出所有5个选项名称,实际需求是仅获取选中项的名称。
下拉菜单HTML结构
<div class="iframe-multi-dropdown multisection-dropdown outline-none1"> <ul class="top multiSelect" id="g-dropdown" data-type="multiSelect" autoid="dropdown-values"> <li id="li-0" data-level-id="" class="li-level1" tabindex="-1"> <h3 data-id="" data-acc-id="" id="li-0-h" data-level-header="level1-header" class="header level1-header clearfix Paragraph1 selected outline-none1 label-css-level1 selectable " role="presentation"> <input type="checkbox" aria-label1="" aria-hidden="true" name="level1" value=""> <span role="checkbox" aria-label="Rupendra,E@Reddy" tabindex="0" aria-checked="true" class="component-check-box yodlee-font-icon svg_tick outline-none1 check-box-css level1"></span> <span class="ellipsis name text text-css-level1" aria-hidden="true" title="Rupendra,E@Reddy" data-title="Rupendra,E@Reddy">Rupendra,E@Reddy</span> </h3> </li> <li id="li-1" data-level-id="" class="li-level1" tabindex="-1"> <h3 data-id="" id="li-1-h" data-acc-id="" data-level-header="level1-header" class=" header level1-header Paragraph1 clearfix outline-none1 label-css-level1 selectable " role="presentation"> <input type="checkbox" aria-label1="" aria-hidden="true" name="level1" value=""> <span role="checkbox" aria-label="Chandra,K" tabindex="0" aria-checked="false" class="component-check-box yodlee-font-icon outline-none1 check-box-css level1"></span> <span class="ellipsis name text text-css-level1" aria-hidden="true" title="Chandra,K" data-title="Chandra,K">Chandra,K</span> </h3> </li> <li id="li-2" data-level-id="" class="li-level1" tabindex="-1"> <h3 data-id="" id="li-2-h" data-acc-id="" data-level-header="level1-header" class=" header level1-header Paragraph1 clearfix outline-none1 label-css-level1 selectable " role="presentation"> <input type="checkbox" aria-label1="" aria-hidden="true" name="level1" value=""> <span role="checkbox" aria-label="Deven,S" tabindex="0" aria-checked="false" class="component-check-box yodlee-font-icon outline-none1 check-box-css level1"></span> <span class="ellipsis name text text-css-level1" aria-hidden="true" title="Deven,S" data-title="Deven,S">Deven,S</span> </h3> </li> <li id="li-3" data-level-id="" class="li-level1" tabindex="-1"> <h3 data-id="" data-acc-id="" id="li-3-h" data-level-header="level1-header" class="header level1-header clearfix Paragraph1 selected outline-none1 label-css-level1 selectable " role="presentation"> <input type="checkbox" aria-label1="" aria-hidden="true" name="level1" value=""> <span role="checkbox" aria-label="Mohan && Raj" tabindex="0" aria-checked="true" class="component-check-box yodlee-font-icon svg_tick outline-none1 check-box-css level1"></span> <span class="ellipsis name text text-css-level1" aria-hidden="true" title="Mohan && Raj" data-title="Mohan && Raj">Mohan && Raj</span> </h3> </li> <li id="li-4" data-level-id="" class="li-level1" tabindex="-1"> <h3 data-id="" data-acc-id="" id="li-4-h" data-level-header="level1-header" class="header level1-header clearfix Paragraph1 selected outline-none1 label-css-level1 selectable " role="presentation"> <input type="checkbox" aria-label1="" aria-hidden="true" name="level1" value=""> <span role="checkbox" aria-label="Yumiko<>K" tabindex="0" aria-checked="true" class="component-check-box yodlee-font-icon svg_tick outline-none1 check-box-css level1"></span> <span class="ellipsis name text text-css-level1" aria-hidden="true" title="Yumiko<>K" data-title="Yumiko<>K">Yumiko<>K</span> </h3> </li> </ul> <ul class="no-records hide"> <li id="test" class="li-level1" role="alert" aria-atomic="true" aria-live="assertive"> <div data-id="test" tabindex="0" class=" header level1-header Paragraph1 outline-none1 label-css-level1"> <span class="ellipsis name text text-css-level1"></span> </div> </li> </ul> </div>
当前Java代码
public List<String> checkUncheck() { LinkedList<String> owner = new LinkedList<String>(); List<WebElement> li = SeleniumUtil.getWebElements(d, "checkUncheck", pageName, frameName); int si =li.size(); System.out.println(si); for ( WebElement els : li ) { String values =els.getText(); if (!els.isSelected()) { els.click(); owner.add(els.getText().trim()); //logger.error("Could not able to get the owner name checkbox to click"); } if (els.isSelected()) { els.click(); } } return owner; }
调用代码:
logger.info("Check and Uncheck the checkboxes"); List<String> ownerName = manageAccount_loc.checkUncheck(); logger.info("The value selected in Pop up are " + ownerName);
问题分析
当前代码的逻辑存在两个核心问题:
- 重复点击冲突:同一个循环里先判断未选中就点击,紧接着又判断选中就点击,导致所有复选框被来回切换两次,最终状态回到初始值,但过程中错误添加了所有文本。
- 文本收集逻辑错误:只要点击未选中的复选框就添加文本,完全没有结合最终选中状态来筛选,不符合需求。
解决方案
我们分两种常见需求场景给出修正代码:
场景1:切换所有复选框状态后,收集最终选中的项
如果需求是先切换每个复选框的状态(选中变取消,取消变选中),再收集最终选中的项:
public List<String> checkUncheck() { LinkedList<String> selectedOwners = new LinkedList<>(); List<WebElement> checkboxItems = SeleniumUtil.getWebElements(d, "checkUncheck", pageName, frameName); // 第一步:切换每个复选框的状态 for (WebElement item : checkboxItems) { item.click(); } // 第二步:遍历收集最终选中的项文本 for (WebElement item : checkboxItems) { // 注意:如果isSelected()不生效,可通过aria-checked属性判断 boolean isChecked = item.isSelected() || Boolean.parseBoolean(item.findElement(By.cssSelector("span[role='checkbox']")).getAttribute("aria-checked")); if (isChecked) { selectedOwners.add(item.getText().trim()); } } return selectedOwners; }
场景2:仅收集初始状态下已选中的项(不切换状态)
如果需求只是获取默认选中的项,不需要切换状态:
public List<String> getSelectedOwners() { LinkedList<String> selectedOwners = new LinkedList<>(); List<WebElement> checkboxItems = SeleniumUtil.getWebElements(d, "checkUncheck", pageName, frameName); for (WebElement item : checkboxItems) { boolean isChecked = item.isSelected() || Boolean.parseBoolean(item.findElement(By.cssSelector("span[role='checkbox']")).getAttribute("aria-checked")); if (isChecked) { selectedOwners.add(item.getText().trim()); } } return selectedOwners; }
关键说明
- 由于HTML中是自定义复选框(用
<span role="checkbox">实现),原生isSelected()可能不生效,此时可以通过读取aria-checked属性来判断选中状态。 - 确保
SeleniumUtil.getWebElements()返回的是包含复选框和文本的容器元素(比如<li>或<h3>),这样getText()才能正确获取到用户名称。
内容的提问来源于stack exchange,提问作者Avinash Manhas
相关产品推荐
相关产品推荐

