You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Selenium测试偶现同时打开两行下拉菜单问题求助

偶现异常:表格两行下拉框同时展开的成因分析

问题背景

我们的网站有支持新增行的表格,每行包含下拉框、文本框等相同元素。测试时表格固定为2行,测试步骤为:先编辑第一行下拉框,紧接着编辑第二行下拉框。

定位下拉框的XPATH选择器:

(//input[@name='ProductPriceChannelId'])[1] // 第一行
(//input[@name='ProductPriceChannelId'])[2] // 第二行

通过浏览器检查工具搜索该XPATH,始终显示找到唯一元素,但每10次测试会出现1次异常:选择第一行下拉框选项后,打开第二行下拉框时,第一行下拉框也会展开,导致两个下拉菜单同时显示。

相关代码与测试步骤

核心操作代码示例

  1. 点击下拉框元素(第一行示例):
var field = _webDriver.FindElement(By.XPath($"(//input[@name='ProductPriceChannelId'])[1]"));
field.Click();
  1. 点击下拉选项:
var field = _webDriver.FindElement(By.XPath($"//p[normalize-space()='{nameOfElementToChoose}']"));
field.Click();

测试步骤代码

// ---------- 编辑服务费版本
// 1. 第一行:编辑服务费版本
_h.EditServiceChargesVersion(1, s);
// 检查无验证提示
_h.CheckOverlapValidation(1, false);
_h.CheckOverlapValidation(2, false);
// 2. 第二行:编辑服务费版本
_h.EditServiceChargesVersion(2, s);
// 检查两行的验证提示
_h.CheckOverlapValidation(1, true);
_h.CheckOverlapValidation(2, true);
_h.Save(SaveButtonStates.Error);

相关方法实现

EditServiceChargesVersion方法

public void EditServiceChargesVersion(int rowPosition, ServiceCharge s)
{
var rowSelector = $"//tbody//tr[@class='mud-table-row'][{rowPosition}]";
_a.ClickElementFromDropDown($"{rowSelector}{VersionSelector}", $"{(int)s.ServiceChargeVersionId!} - {s.ServiceChargeVersionId.GetDisplayName()}");
}

ClickElementFromDropDown方法

public void ClickElementFromDropDown(string selector, string nameOfElementToChoose, bool shouldCompareValue = true)
{
    ClickOnElementWithWait(selector, $"//p[normalize-space()='{nameOfElementToChoose}']");
    ClickOnElement($"//p[normalize-space()='{nameOfElementToChoose}']");
    if (shouldCompareValue)
    {
        GetValueFromElementAndCompare(selector, nameOfElementToChoose);
    }
}

ClickOnElementWithWait方法

public void ClickOnElementWithWait(string selector, string selectorWait, int? timeToWait = null)
{
var field = _webDriver.FindElement(By.XPath(selector));
field.Click();
_fluentWait.Until(ExpectedConditions.ElementExists(By.XPath(selectorWait)));
}

异常成因分析

  • 页面状态未完全同步:选择第一行下拉框选项后,前端需要时间完成下拉菜单关闭、DOM状态更新(比如移除展开类、隐藏下拉面板)。如果测试代码在DOM状态未更新完成时就点击第二行下拉框,前端事件监听逻辑会出现混乱,第一行下拉框的展开状态标记未被及时清除,导致点击第二行时触发第一行的展开事件。
  • 下拉选项定位模糊:点击下拉选项使用的//p[normalize-space()='{nameOfElementToChoose}']是全局XPATH,未限定在当前行的下拉面板内。如果第一行下拉面板因渲染延迟未完全隐藏,该XPATH可能同时匹配两行的下拉选项,误触第一行下拉面板区域导致其重新展开。
  • 等待条件不精准:ClickOnElementWithWait方法仅等待选项元素存在,未等待第一行下拉面板消失或隐藏。即使选项元素已加载,第一行下拉面板可能还未完成关闭动画或状态更新,此时执行后续操作会引发冲突。
  • 前端事件竞态条件:前端处理下拉框展开/关闭的事件多为异步逻辑(比如动画、状态更新),当测试代码操作速度快于前端事件处理速度时,会出现竞态条件——第一行的关闭事件未处理完成,第二行的展开事件已触发,导致两个下拉框的状态管理混乱。

内容的提问来源于stack exchange,提问作者Beardy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 16:20:54