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

React中Kendo DropDownList测试报错:无法找到指定role和name的元素

问题:React中Kendo DropDownList测试无法匹配name属性

1. 使用的Kendo DropDownList组件代码

<div className="col-lg-4 col-md-4 col-sm-4 col-xs-4 form-group">
<Label>CDN Code</Label>
<DropDownList
  id="cdnCode-dropdown"
  name="cdnCodeDD"
  value={props.CdnCodeTxt}
  onChange={handleChange}
  data={componentState.cdnCodeList}
  textField="text"
  dataItemKey="id"
  defaultItem={Constants.DefaultItem}
/>
</div>

2. 编写的React测试代码

test('renders cdncode dropdown', () => {
    render(<ComponentDetailsContent />);
    const element = screen.getByRole("listbox", {
        name: "cdnCodeDD",
    });
    expect(element).toBeInTheDocument();
});

3. 测试报错与异常现象

测试抛出如下错误:

TestingLibraryElementError: Unable to find an accessible element with the role "listbox" and name "cdnSicCodeDD"

报错中显示的可见listbox元素无关联name:

Name "":
      <span
        aria-activedescendant="option-01abe0e8-1cc2-4ca2-ac35-d2a04f7dda62--1"
        aria-expanded="false"
        aria-haspopup="true"
        aria-owns="0f6115c2-49f9-4430-bb2e-09841d34807b"
        class="k-dropdown-wrap k-state-default"
        id="cdnCode-dropdown"
        role="listbox"
        tabindex="0"
      />

使用getAllByRoles查询时,发现存在一个隐藏的原生select元素,其带有正确的name属性:

[...   
    <select aria-hidden="true" name="cdnCodeDD" style="opacity: 0; width: 1px; border: 0px; z-index: -1; position: absolute; left: 50%;" tabindex="-1"><option value="[object Object]" /></select></span>]

疑问点

  • 明明给DropDownList设置了name,为何测试时匹配不到?
  • 尝试用/cdncode/i作为匹配条件仍报错,该怎么处理?
  • 因工作限制无法安装Testing Playground插件,有没有替代的调试方案?

解答

为什么name属性不生效?

Kendo DropDownList是自定义渲染的组件,会生成两个核心元素:

  1. 可见的交互容器(带listbox角色的span),用于用户操作
  2. 隐藏的原生select,用于表单提交逻辑

你设置的name属性只会绑定到隐藏的原生select上,可见的span元素并不会关联这个name,所以用listbox角色+cdnCodeDDname查询时,自然匹配不到目标元素。另外注意报错中写的是cdnSicCodeDD,和你代码里的cdnCodeDD存在拼写差异,也可能是问题诱因。

测试匹配的可行方案

方案1:通过关联的label文本匹配(推荐)

这是最符合无障碍测试原则的方式,用户实际是通过label识别下拉框的:

test('renders cdncode dropdown', () => {
    render(<ComponentDetailsContent />);
    const element = screen.getByRole("listbox", {
        name: /cdn code/i,
    });
    expect(element).toBeInTheDocument();
});

方案2:通过元素id查询

如果label关联存在问题,可以直接用组件设置的id定位:

test('renders cdncode dropdown', () => {
    render(<ComponentDetailsContent />);
    // 方式1:通过role+id匹配
    const element = screen.getByRole("listbox", {
        id: "cdnCode-dropdown",
    });
    // 方式2:直接通过id查询
    // const element = screen.getByElementById("cdnCode-dropdown");
    expect(element).toBeInTheDocument();
});

方案3:查询隐藏的select(不推荐)

虽然能找到带正确name的隐藏select,但它是Kendo内部用于表单提交的元素,并非用户可见的交互节点,不符合测试用户行为的原则,仅作参考:

const hiddenSelect = screen.getByRole("combobox", { name: "cdnCodeDD" });
expect(hiddenSelect).toBeInTheDocument();

无需Testing Playground的调试方案

1. 打印DOM结构排查

在测试中使用screen.debug(),可以输出当前渲染的完整DOM,直观查看元素的role、name等属性:

test('debug dropdown elements', () => {
    render(<ComponentDetailsContent />);
    // 打印完整DOM
    screen.debug();
    // 或者只打印所有listbox元素
    screen.debug(screen.getAllByRole("listbox"));
});

2. 遍历元素属性确认

获取所有listbox元素,逐个打印关键属性,定位目标元素:

test('check all listbox elements', () => {
    render(<ComponentDetailsContent />);
    const listboxes = screen.getAllByRole("listbox");
    listboxes.forEach((box, index) => {
        console.log(`Listbox ${index}:`, {
            id: box.id,
            ariaLabel: box.getAttribute('aria-label'),
            surroundingText: box.parentElement?.textContent.trim()
        });
    });
});

3. 用query系列方法避免报错中断

用queryByRole替代getByRole,它不会抛出错误,而是返回null或元素,方便排查是否存在匹配项:

test('check dropdown existence', () => {
    render(<ComponentDetailsContent />);
    const element = screen.queryByRole("listbox", { name: /cdn code/i });
    console.log('匹配到的元素:', element);
    expect(element).toBeInTheDocument();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 06:20:27