Selenium Java环境下非标准下拉框span元素选择实现方案
问题说明
Java环境下使用Selenium开展Web自动化测试时,需完成衬衫自定义尺码选择组件的选项选中操作。该组件不属于标准select原生下拉框,常规下拉选择逻辑不适用;目前已通过XPath定位实现下拉选项列表展开,但无法选中列表内匹配目标文本的选项。
关联参考信息
- 测试场景:商品详情页尺码选择组件操作
- 现有测试代码:
package First_Test; import java.time.Duration; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.WindowType; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.ISelect; import org.openqa.selenium.support.ui.Select; import org.openqa.selenium.Keys; import io.github.bonigarcia.wdm.WebDriverManager; public class Practice_First { public static void main(String[] args) throws InterruptedException { //System.setProperty("webdriver.chrome.driver", "./Driver/chromedriver.exe"); WebDriverManager.chromedriver().setup(); WebDriver driver = new ChromeDriver(); driver.get("目标站点地址"); driver.manage().window().maximize(); Thread.sleep(3000); String originalWindow= driver.getWindowHandle(); Thread.sleep(5000); driver.findElement(By.id("wzrk-cancel")).click(); // driver.findElement(By.xpath("//button[@id='wzrk-cancel']")).click(); driver.findElement(By.xpath("//a[@href='/men']//div[@class='Gender-centralize']//span[@class='Gender-CTA'][normalize-space()='Shop Now']")).click(); Thread.sleep(2000); //driver.findElement(By.cssSelector("a[href='shop-emporio-armani-camouflage-print-t-shirt-in-mercerised-cotton-for-men-215380566_20.html']")).click(); // driver.findElement(By.cssSelector("a[title=\"Camouflage Print T-shirt in Mercerised Cotton\"]")).click(); driver.findElement(By.xpath("//span[normalize-space()='675 AED']")).click(); Thread.sleep(3000); driver.findElement(By.xpath("//button[@title='Blue']")).click(); Thread.sleep(2000); driver.findElement(By.xpath("//div[@class='Select-control']")).click(); Thread.sleep(1000); //driver.findElement(By.xpath("//div[@class='Select Dropdown SizeSelection-options Thread.sleep(1000); */ //driver.close(); } }
- 下拉收起状态的组件DOM结构:
<div class="Select Dropdown SizeSelection-options SizeSelection-fixedSize has-value Select--single" xpath="1"> <input name="sizeCode" type="hidden" value="75"> <div class="Select-control"> <div class="Select-multi-value-wrapper" id="react-select-sizeCode--value"> <div class="Select-value"> <span class="Select-value-label" role="option" aria-selected="true" id="react-select-sizeCode--value-item">M</span> </div> <div aria-expanded="false" aria-owns="" aria-activedescendant="react-select-sizeCode--value" aria-disabled="false" class="Select-input" role="combobox" style="border:0;width:1px;display:inline-block" tabindex="0"> </div> </div> <span class="Select-arrow-zone"><svg width="12" height="7" viewBox="0 0 20 10" class="svg"> <path d="M0 0l10 10L20 0" stroke="#2d2d2d" class="svg-stroke"> </path> </svg> </span> </div> </div>
解决方案
该组件为React-Select自定义下拉组件,Selenium自带的Select类仅支持原生<select>标签,对这类自定义组件无效,按以下逻辑修改即可:
- 移除代码中所有硬编码的
Thread.sleep()等待,替换为显式等待,避免因页面加载速度波动导致元素定位失败。 - 之前抓取的DOM是下拉收起状态的结构,下拉展开后的选项节点是动态渲染插入到页面中的,不在
Select-control节点内部,展开后选项节点统一带Select-option类名,可直接通过文本匹配定位。 - 定位到目标选项后直接执行点击操作即可,若出现元素点击被遮挡的情况,可使用JS点击做兜底。
核心实现代码参考:
// 引入显式等待相关依赖 import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.JavascriptExecutor; // 替换原有点击Select-control后的逻辑 WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); // 点击展开尺码下拉框 WebElement sizeDropdownTrigger = wait.until(ExpectedConditions.elementToBeClickable( By.xpath("//div[contains(@class,'SizeSelection-options')]//div[@class='Select-control']") )); sizeDropdownTrigger.click(); // 传入需要选中的目标尺码值,比如要选S/M/L/XL直接修改该变量即可 String targetSizeVal = "L"; // 等待下拉选项加载完成,匹配对应文本的选项 WebElement targetOption = wait.until(ExpectedConditions.elementToBeClickable( By.xpath("//div[contains(@class,'Select-menu')]//div[contains(@class,'Select-option') and normalize-space()='" + targetSizeVal + "']") )); // 常规点击 targetOption.click(); // 若常规点击报错被拦截,替换为下面的JS点击兜底 // ((JavascriptExecutor)driver).executeScript("arguments[0].click();", targetOption);
注意事项:操作自定义下拉组件时不需要调用Selenium原生Select类的相关方法,直接按普通Web元素做定位、点击操作即可。
内容的提问来源于stack exchange,提问作者Qasim_Khan
相关产品推荐
相关产品推荐

