当发现多个元素时如何过滤 getByLabelText 查询?

Cri*_*rez 5 javascript unit-testing reactjs jestjs react-testing-library

如何过滤getByLabelText查询,如果它抛出类型错误:TestingLibraryElementError: Found multiple elements with the text of: /to/i,我有以下 HTML 结构,其中有一些嵌套标签:

当前的 HTML 结构

<div class="ant-row ant-form-item ant-radio-group-cards" style="row-gap: 0px;">
    <div class="ant-col ant-form-item-label">
        <!-- <label> with "To" text -->
        <label for="transferFunds_to" class="ant-form-item-required" title="To">To</label> 
    </div>
    <div class="ant-col ant-form-item-control">
        <div class="ant-form-item-control-input">
            <div class="ant-form-item-control-input-content">
                <!-- Other <label> with "To" text here -->
                <label class="ant-radio-button-wrapper">
                    <span class="ant-radio-button"><input id="transferFunds_to" type="radio" class="ant-radio-button-input" value="" /><span class="ant-radio-button-inner"></span></span>
                    <span>
                        <li class="ant-list-item">
                            <div class="ant-list-item-meta">
                                <div class="ant-list-item-meta-avatar">
                                    <svg width="1em" height="1em" viewBox="0 0 16 16" fill="none" style="font-size: 48px;"></svg>
                                </div>
                                <div class="ant-list-item-meta-content">
                                    <!-- "To" word here inside a label -->
                                    <h4 class="ant-list-item-meta-title">Account to</h4>
                                    <div class="ant-list-item-meta-description">Choose the account to transfer to</div>
                                </div>
                            </div>
                            <span role="img" class="anticon icon-size-middle" style="align-self: center;">
                                <svg width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false" class=""></svg>
                            </span>
                        </li>
                    </span>
                </label>
            </div>
        </div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

RTL测试

import { screen } from '@testing-library/react';

// query applied
screen.getByLabelText(/to/i);
Run Code Online (Sandbox Code Playgroud)

Dre*_*ese 11

问题

getBy*当存在零个匹配项或大于一个匹配项时,所有查询都会引发错误。

查询

在此输入图像描述

该错误表明您应该使用返回匹配数组的查询之一getAllBy*,并且仅在未找到匹配项时才抛出错误。

解决方案

由于您想使用属性input来定位特定元素,因此id="transferFunds_to"您至少有几个选项:

  1. 在输入中添加 atestid并据此进行查询。

    <input
      id="transferFunds_to"
      data-testid="transferFunds_to" // <-- add a data test id
      type="radio"
      class="ant-radio-button-input"
      value=""
    />
    
    Run Code Online (Sandbox Code Playgroud)

    测试

    test("case-sensitive To", () => {
      render(<App />);
      screen.getByTestId("transferFunds_to");
    });
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用手动查询并按指定id属性定位。

    test("case-sensitive To", () => {
      const { container } = render(<App />);
      container.querySelector("#transferFunds_to")
    });
    
    Run Code Online (Sandbox Code Playgroud)

编辑如何过滤 getbylabeltext-query-when-found-multiple-elements


oie*_*elo 2

感谢克里斯蒂安的codesandbox: https: //codesandbox.io/s/trhh8

正如您在问题中指出的那样,两个标签上的文本匹配存在冲突

在第二个标签内文本“帐户至”、“选择要转入的帐户”

如果您对此感到满意,并且不想更改 html 结构,唯一可用的选择是在您的screen.getByLabelText

我将您的示例分叉并将正则表达式更新为screen.getByLabelText(/^to$/i),并且它按预期工作,因为所有其他“to”后面都跟有或后面有一个空格,例如" to""to ",标签"To"没有前置或后置空格,这满足正则表达式

最终的测试用例是:

import { screen, render } from "@testing-library/react";
import App from "./App";

test("case-sensitive To", () => {
  render(<App />);
  expect(screen.getByLabelText(/^to$/i).id).toBe("transferFunds_to");
});
Run Code Online (Sandbox Code Playgroud)

看看https://codesandbox.io/s/react-testing-library-get-by-label-regex-g8tlx

当然,你也可以更改API并使用一个.querySelector或更通用的JS api