如何访问测试库中被多个元素破坏的文本

dar*_*usz 17 unit-testing jestjs testing-library

这是我的代码示例

<div class="dropdown" data-testid="dropdown">
  <div class="option" data-testid="option">
   <b>[AF]</b> Afghanistan
  </div>
  <div class="option" data-testid="option">
   <b>[AL]</b> Albania
  </div>
  <div class="option" data-testid="option">
   <b>[DZ]</b> Algeria
  </div>
 </div>
Run Code Online (Sandbox Code Playgroud)

我需要做的是通过文本访问第一个元素以触发 userEvent.selectOptions

const dropdown = getByTestId('dropdown');
userEvent.selectOptions(dropdown, screen.getByText('[AF] Afghanistan'))
Run Code Online (Sandbox Code Playgroud)

我得到的是:

TestingLibraryElementError:无法找到带有文本的元素:[AF] 阿富汗。这可能是因为文本被多个元素分解。在这种情况下,您可以为文本匹配器提供一个函数,以使您的匹配器更加灵活。

显然是因为我试图查询的文本被元素破坏了。

请注意,这不是一个选择/选项下拉列表,它没有任何可访问的角色,所以我只能通过 screen.getByText 查询它

jul*_*ves 23

getBy*查询接受TextMatch作为参数,这意味着参数可以是字符串、正则表达式或函数。在这种情况下,我们可以使用函数(而不是字符串)并定位我们要选择的特定元素。

这是一个应用此逻辑并使其可重用的辅助函数。

const getByTextContent = (text) => {
    // Passing function to `getByText`
    return screen.getByText((content, element) => {
        const hasText = element => element.textContent === text
        const elementHasText = hasText(element)
        const childrenDontHaveText = Array.from(element?.children || []).every(child => !hasText(child))
        return elementHasText && childrenDontHaveText
  })
}
Run Code Online (Sandbox Code Playgroud)

快速解释一下发生了什么:查询将遍历 DOM 中的所有元素,但我们希望避免返回超出需要的元素。我们确保所有子级都没有与其父级相同的文本。这确保了我们返回的元素是实际包含目标文本的元素。

getByTextContent然后可以在测试中使用辅助函数,如下所示。

const dropdown = getByTestId('dropdown');
userEvent.selectOptions(dropdown, getByTextContent('[AF] Afghanistan'))
Run Code Online (Sandbox Code Playgroud)