te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - How to filter getByLabelText query when found multiple elements? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to filter getByLabelText query when found multiple elements? - Stack Overflow

programmeradmin3浏览0评论

how to filter the getByLabelText query, if It is throwing an error of the type: TestingLibraryElementError: Found multiple elements with the text of: /to/i, I have the following HTML structure, which has some nested labels:

Current HTML structure

<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>

RTL Test

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

// query applied
screen.getByLabelText(/to/i);

how to filter the getByLabelText query, if It is throwing an error of the type: TestingLibraryElementError: Found multiple elements with the text of: /to/i, I have the following HTML structure, which has some nested labels:

Current HTML structure

<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>

RTL Test

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

// query applied
screen.getByLabelText(/to/i);
Share Improve this question edited Sep 8, 2021 at 5:38 Drew Reese 203k17 gold badges237 silver badges268 bronze badges asked Sep 8, 2021 at 4:22 Cristian FlórezCristian Flórez 2,7818 gold badges35 silver badges61 bronze badges 9
  • Does any of these help ? github./testing-library/dom-testing-library/issues/482 - stackoverflow./questions/68943625/… – Mauricio Gracia Gutierrez Commented Sep 8, 2021 at 4:28
  • 1 Thanks for the links but I had already seen both of them and I tried to apply those solutions and it does not work as expected, the test keeps crashing with the same error. – Cristian Flórez Commented Sep 8, 2021 at 4:31
  • i'm unable to reproduce the error, could you have a look on codesandbox.io/s/sad-easley-doom6, based on your HTML is it returning the input#transferFunds_to, can you fork it and make a reproducible error? – oieduardorabelo Commented Sep 8, 2021 at 4:36
  • 1 @oieduardorabelo I create a new one with all the html structure, there u can reproduce the error... I going to update my answer with the plet HTML. codesandbox.io/s/trhh8?file=/src/App.js:71-14670 – Cristian Flórez Commented Sep 8, 2021 at 4:59
  • App.test.js is empty on that link, could you double check you shared it correctly? thank you – oieduardorabelo Commented Sep 8, 2021 at 5:03
 |  Show 4 more ments

2 Answers 2

Reset to default 11

Issue

All getBy* queries throw an error when there are zero matches or greater than one match.

Queries

The error says you should use one of the getAllBy* queries which return an array of matches and only throws an error if no matches are found.

Solutions

Since you want to target a specific input element with id="transferFunds_to" attribute you've at least a couple options:

  1. Add a testid to the input and query by that.

    <input
      id="transferFunds_to"
      data-testid="transferFunds_to" // <-- add a data test id
      type="radio"
      class="ant-radio-button-input"
      value=""
    />
    

    test

    test("case-sensitive To", () => {
      render(<App />);
      screen.getByTestId("transferFunds_to");
    });
    
  2. Use a manual query and target by the specified id attribute.

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

thanks for the codesandbox Cristian: https://codesandbox.io/s/trhh8

as you pointed in your question, there is conflicting text matching on both labels

texts "Account to", "Choose the account to transfer to" inside the second label

if you are happy with that, and you don't want to change the html structure, the only available option is to use a more strict regex in your screen.getByLabelText

i forked your example and updated the regex to screen.getByLabelText(/^to$/i), and it worked as expected, since all other "to" are followed by or have a space after it, e.g. " to" or "to ", the label "To" doesn't have pre or post space, which fulfills the regex

the final test case is:

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");
});

have a look on https://codesandbox.io/s/react-testing-library-get-by-label-regex-g8tlx

of course, you can also change the API and use a .querySelector or more generic JS apis

发布评论

评论列表(0)

  1. 暂无评论