jest-dom

@testing-library/jest-dom 库提供了一套自定义的 jest 匹配器,您可以使用它们来扩展 jest。这些匹配器将使您的测试更具声明性,更易于阅读和维护。

安装

// npm
npm install --save-dev @testing-library/jest-dom


// yarn
yarn add --dev @testing-library/jest-dom

注意:建议您安装 jest-dom 的 eslint 插件,该插件提供可自动修复的 lint 规则,可防止误报测试,并确保您在测试中使用正确的匹配器,从而提高测试的可读性。更多详细信息请访问 eslint-plugin-jest-dom

用法

在你的测试设置文件中导入一次 @testing-library/jest-dom,然后你就可以开始测试了:

// In your own jest-setup.js (or any other name)
import '@testing-library/jest-dom'

// In jest.config.js add (if you haven't already)
setupFilesAfterEnv: ['<rootDir>/jest-setup.js']
使用 @jest/globals

如果你在使用 @jest/globals 并且设置了 injectGlobals: false,你需要在你的测试设置文件中使用不同的 import 方式:

// In your own jest-setup.js (or any other name)
import '@testing-library/jest-dom/jest-globals'
使用 Vitest

如果你正在使用 vitest,这个模块将按原样工作,但你需要在你的测试设置文件中使用不同的导入方式。这个文件应该添加到你的 vitest 配置中的 setupFiles 属性:

// In your own vitest-setup.js (or any other name)
import '@testing-library/jest-dom/vitest'

// In vitest.config.js add (if you haven't already)
setupFiles: ['./vitest-setup.js']
使用 TypeScript

如果正在使用 TypeScript,请确保您配置文件是 .ts 而不是 .js,以包含必要的类型。如果还没有的话,你还需要在 tsconfig.json 中包含你的设置文件:

  // In tsconfig.json
  "include": [
    ...
    "./jest-setup.ts"
  ],
与其他Jest的expect兼容

如果您正在使用与 Jest 的 expect 接口兼容的不同测试运行器,那么您可能可以使用这个库:

import * as matchers from '@testing-library/jest-dom/matchers'
import {expect} from 'my-test-runner/expect'

expect.extend(matchers)

自定义匹配器

@testing-library/jest-dom 可以与任何从查询中返回 DOM 元素的库或框架一起使用。以下自定义匹配器示例是使用 @testing-library 套件中的匹配器(例如 getByTestId、queryByTestId、getByText 等)编写的。

toBeDisabled

从用户的角度来检查,一个元素是否被禁用。根据规范,以下元素可以被禁用:buttoninputselecttextareaoptgroupoptionfieldset和自定义元素。

这个自定义匹配器将元素视为禁用状态,如果元素是上面列出的可禁用元素类型之一,并且存在禁用属性。 如果元素位于支持禁用的父表单元素中,并且存在禁用属性,它也会将元素视为禁用状态。

<button data-testid="button" type="submit" disabled>submit</button>
<fieldset disabled><input type="text" data-testid="input" /></fieldset>
<a href="..." disabled>link</a>
expect(getByTestId('button')).toBeDisabled()
expect(getByTestId('input')).toBeDisabled()
expect(getByText('link')).not.toBeDisabled()

这个自定义匹配器没有考虑到aria-disabled属性是否存在。更多关于为什么这种情况的信息,请查看 #144

toBeEnabled 

从用户的角度来检查一个元素是否没有被禁用。它工作的方式就像 not.toBeDisabled()。使用这个匹配器可以避免在测试中使用双重否定。

toBeEmptyDOMElement

断言一个元素是否对用户没有可见的内容。它忽略了注释,但是如果元素包含空白字符,那么它将会失败。

<span data-testid="not-empty"><span data-testid="empty"></span></span>
<span data-testid="with-whitespace"> </span>
<span data-testid="with-comment"><!-- comment --></span>
expect(getByTestId('empty')).toBeEmptyDOMElement()
expect(getByTestId('not-empty')).not.toBeEmptyDOMElement()
expect(getByTestId('with-whitespace')).not.toBeEmptyDOMElement()
toBeInTheDocument

断言一个元素是否在文档中。

<span data-testid="html-element"><span>Html Element</span></span>
<svg data-testid="svg-element"></svg>
expect(
  getByTestId(document.documentElement, 'html-element'),
).toBeInTheDocument()
expect(getByTestId(document.documentElement, 'svg-element')).toBeInTheDocument()
expect(
  queryByTestId(document.documentElement, 'does-not-exist'),
).not.toBeInTheDocument()

注意:这个匹配器不会找到被分离的元素。元素必须被添加到文档中,才能通过 toBeInTheDocument 找到。如果你希望在一个被分离的元素中搜索,请使用: toContainElement

toBeInvalid

检查元素当前是否无效。

如果元素具有没有值或值为“true”的aria-invalid属性,或者checkValidity()的结果为false,则该元素是无效的。

<input data-testid="no-aria-invalid" />
<input data-testid="aria-invalid" aria-invalid />
<input data-testid="aria-invalid-value" aria-invalid="true" />
<input data-testid="aria-invalid-false" aria-invalid="false" />

<form data-testid="valid-form">
  <input />
</form>

<form data-testid="invalid-form">
  <input required />
</form>
expect(getByTestId('no-aria-invalid')).not.toBeInvalid()
expect(getByTestId('aria-invalid')).toBeInvalid()
expect(getByTestId('aria-invalid-value')).toBeInvalid()
expect(getByTestId('aria-invalid-false')).not.toBeInvalid()

expect(getByTestId('valid-form')).not.toBeInvalid()
expect(getByTestId('invalid-form')).toBeInvalid()
toBeRequired

检查一个表单元素当前是否为必填项。如果元素具有 required 或 aria-required="true" 属性,则必须包含该元素。

<input data-testid="required-input" required />
<input data-testid="aria-required-input" aria-required="true" />
<input data-testid="conflicted-input" required aria-required="false" />
<input data-testid="aria-not-required-input" aria-required="false" />
<input data-testid="optional-input" />
<input data-testid="unsupported-type" type="image" required />
<select data-testid="select" required></select>
<textarea data-testid="textarea" required></textarea>
<div data-testid="supported-role" role="tree" required></div>
<div data-testid="supported-role-aria" role="tree" aria-required="true"></div>
expect(getByTestId('required-input')).toBeRequired()
expect(getByTestId('aria-required-input')).toBeRequired()
expect(getByTestId('conflicted-input')).toBeRequired()
expect(getByTestId('aria-not-required-input')).not.toBeRequired()
expect(getByTestId('optional-input')).not.toBeRequired()
expect(getByTestId('unsupported-type')).not.toBeRequired()
expect(getByTestId('select')).toBeRequired()
expect(getByTestId('textarea')).toBeRequired()
expect(getByTestId('supported-role')).not.toBeRequired()
expect(getByTestId('supported-role-aria')).toBeRequired()
toBeValid

检查元素的值当前是否有效。一个元素如果没有 aria-invalid 属性或者其属性值为 "false",则它是有效的。如果它是一个表单元素,checkValidity() 的结果也必须是true。

<input data-testid="no-aria-invalid" />
<input data-testid="aria-invalid" aria-invalid />
<input data-testid="aria-invalid-value" aria-invalid="true" />
<input data-testid="aria-invalid-false" aria-invalid="false" />

<form data-testid="valid-form">
  <input />
</form>

<form data-testid="invalid-form">
  <input required />
</form>
expect(getByTestId('no-aria-invalid')).toBeValid()
expect(getByTestId('aria-invalid')).not.toBeValid()
expect(getByTestId('aria-invalid-value')).not.toBeValid()
expect(getByTestId('aria-invalid-false')).toBeValid()

expect(getByTestId('valid-form')).toBeValid()
expect(getByTestId('invalid-form')).not.toBeValid()
toBeVisible

检查某个元素当前是否对用户可见。如果满足以下所有条件,则元素可见:

  • 它存在于文档中
  • 它没有 hidden 属性
  • 它的 CSS 属性 opacity 未设置为 0
  • 它的 CSS 属性display未设置为 none
  • 它的 CSS 属性visibility未设置为 hidden  collapse 
  • 它的父元素也是可见的(依此类推,直到 DOM 树的顶部)
  • 如果 <details /> 有 open 属性
<div data-testid="zero-opacity" style="opacity: 0">Zero Opacity Example</div>
<div data-testid="visibility-hidden" style="visibility: hidden">
  Visibility Hidden Example
</div>
<div data-testid="display-none" style="display: none">Display None Example</div>
<div style="opacity: 0">
  <span data-testid="hidden-parent">Hidden Parent Example</span>
</div>
<div data-testid="visible">Visible Example</div>
<div data-testid="hidden-attribute" hidden>Hidden Attribute Example</div>
<details>
  <summary>Title of hidden text</summary>
  Hidden Details Example
</details>
<details open>
  <summary>Title of visible text</summary>
  <div>Visible Details Example</div>
</details>
expect(getByText('Zero Opacity Example')).not.toBeVisible()
expect(getByText('Visibility Hidden Example')).not.toBeVisible()
expect(getByText('Display None Example')).not.toBeVisible()
expect(getByText('Hidden Parent Example')).not.toBeVisible()
expect(getByText('Visible Example')).toBeVisible()
expect(getByText('Hidden Attribute Example')).not.toBeVisible()
expect(getByText('Hidden Details Example')).not.toBeVisible()
expect(getByText('Visible Details Example')).toBeVisible()
toContainElement
toContainElement(element: HTMLElement | SVGElement | null)

断言一个元素是否包含另一个元素作为其后代。

<span data-testid="ancestor"><span data-testid="descendant"></span></span>
const ancestor = getByTestId('ancestor')
const descendant = getByTestId('descendant')
const nonExistantElement = getByTestId('does-not-exist')

expect(ancestor).toContainElement(descendant)
expect(descendant).not.toContainElement(ancestor)
expect(ancestor).not.toContainElement(nonExistantElement)
toContainHTML
toContainHTML(htmlText: string)

断言一个表示HTML元素的字符串是否包含在另一个元素中。字符串应包含有效的HTML,而不包含任何不完整的HTML。

<span data-testid="parent"><span data-testid="child"></span></span>
// These are valid uses
expect(getByTestId('parent')).toContainHTML('<span data-testid="child"></span>')
expect(getByTestId('parent')).toContainHTML('<span data-testid="child" />')
expect(getByTestId('parent')).not.toContainHTML('<br />')

// These won't work
expect(getByTestId('parent')).toContainHTML('data-testid="child"')
expect(getByTestId('parent')).toContainHTML('data-testid')
expect(getByTestId('parent')).toContainHTML('</span>')

你可能并不需要用到这个匹配器。我们鼓励从用户如何在浏览器中感知应用的角度进行测试。这就是为什么不建议测试特定的DOM结构。

这在被测试的代码渲染来自外部源的HTML,且您想验证该HTML代码是否按预期使用的情况下会很有用。

不应用于检查您控制的 DOM 结构。请使用 toContainElement 代替。

toHaveAccessibleDescription 
toHaveAccessibleDescription(expectedAccessibleDescription?: string | RegExp)

断言一个元素具有预期的可用描述。你可以传递预期的可访问描述的确切字符串,或者你可以使用正则表达式进行部分匹配,或者使用 expect.stringContaining/expect.stringMatching。

<a
  data-testid="link"
  href="/"
  aria-label="Home page"
  title="A link to start over"
  >Start</a>
<a data-testid="extra-link" href="/about" aria-label="About page">About</a>
<img src="avatar.jpg" data-testid="avatar" alt="User profile pic" />
<img
  src="logo.jpg"
  data-testid="logo"
  alt="Company logo"
  aria-describedby="t1"
/>
<span id="t1" role="presentation">The logo of Our Company</span>
<img
  src="logo.jpg"
  data-testid="logo2"
  alt="Company logo"
  aria-description="The logo of Our Company"
/>
expect(getByTestId('link')).toHaveAccessibleDescription()
expect(getByTestId('link')).toHaveAccessibleDescription('A link to start over')
expect(getByTestId('link')).not.toHaveAccessibleDescription('Home page')
expect(getByTestId('extra-link')).not.toHaveAccessibleDescription()
expect(getByTestId('avatar')).not.toHaveAccessibleDescription()
expect(getByTestId('logo')).not.toHaveAccessibleDescription('Company logo')
expect(getByTestId('logo')).toHaveAccessibleDescription(
  'The logo of Our Company',
)
expect(getByTestId('logo2')).toHaveAccessibleDescription(
  'The logo of Our Company',
)
toHaveAccessibleErrorMessage
toHaveAccessibleErrorMessage(expectedAccessibleErrorMessage?: string | RegExp)

断言一个元素具有预期的可访问错误消息。您可以传递预期可访问错误消息的确切字符串。或者,您可以通过传递正则表达式或使用 expect.stringContaining/expect.stringMatching 进行部分匹配。

<input
  aria-label="Has Error"
  aria-invalid="true"
  aria-errormessage="error-message"
/>
<div id="error-message" role="alert">This field is invalid</div>

<input aria-label="No Error Attributes" />
<input
  aria-label="Not Invalid"
  aria-invalid="false"
  aria-errormessage="error-message"
/>
// Inputs with Valid Error Messages
expect(getByRole('textbox', {name: 'Has Error'})).toHaveAccessibleErrorMessage()
expect(getByRole('textbox', {name: 'Has Error'})).toHaveAccessibleErrorMessage(
  'This field is invalid',
)
expect(getByRole('textbox', {name: 'Has Error'})).toHaveAccessibleErrorMessage(
  /invalid/i,
)
expect(
  getByRole('textbox', {name: 'Has Error'}),
).not.toHaveAccessibleErrorMessage('This field is absolutely correct!')

// Inputs without Valid Error Messages
expect(
  getByRole('textbox', {name: 'No Error Attributes'}),
).not.toHaveAccessibleErrorMessage()

expect(
  getByRole('textbox', {name: 'Not Invalid'}),
).not.toHaveAccessibleErrorMessage()
toHaveAccessibleName
toHaveAccessibleName(expectedAccessibleName?: string | RegExp)

断言一个元素具有预期的可访问名称。例如,可以断言表单元素和按钮都进行了适当的标记。

<img data-testid="img-alt" src="" alt="Test alt" />
<img data-testid="img-empty-alt" src="" alt="" />
<svg data-testid="svg-title"><title>Test title</title></svg>
<button data-testid="button-img-alt"><img src="" alt="Test" /></button>
<p><img data-testid="img-paragraph" src="" alt="" /> Test content</p>
<button data-testid="svg-button"><svg><title>Test</title></svg></p>
<div><svg data-testid="svg-without-title"></svg></div>
<input data-testid="input-title" title="test" />
expect(getByTestId('img-alt')).toHaveAccessibleName('Test alt')
expect(getByTestId('img-empty-alt')).not.toHaveAccessibleName()
expect(getByTestId('svg-title')).toHaveAccessibleName('Test title')
expect(getByTestId('button-img-alt')).toHaveAccessibleName()
expect(getByTestId('img-paragraph')).not.toHaveAccessibleName()
expect(getByTestId('svg-button')).toHaveAccessibleName()
expect(getByTestId('svg-without-title')).not.toHaveAccessibleName()
expect(getByTestId('input-title')).toHaveAccessibleName()
toHaveAttribute
toHaveAttribute(attr: string, value?: any)

检查给定的元素是否具有属性。你还可以选择性地检查该属性是否具有特定的预期值或部分匹配,使用 expect.stringContaining/expect.stringMatching

<button data-testid="ok-button" type="submit" disabled>ok</button>
const button = getByTestId('ok-button')

expect(button).toHaveAttribute('disabled')
expect(button).toHaveAttribute('type', 'submit')
expect(button).not.toHaveAttribute('type', 'button')

expect(button).toHaveAttribute('type', expect.stringContaining('sub'))
expect(button).toHaveAttribute('type', expect.not.stringContaining('but'))
toHaveClass
toHaveClass(...classNames: string[], options?: {exact: boolean})

检查给定的元素在其 class 属性中是否具有某些 class 属性值。除非你正在断言的元素没有任何class,否则你必须至少提供一个 class。

<button data-testid="delete-button" class="btn extra btn-danger">
  Delete item
</button>
<button data-testid="no-classes">No Classes</button>
const deleteButton = getByTestId('delete-button')
const noClasses = getByTestId('no-classes')

expect(deleteButton).toHaveClass('extra')
expect(deleteButton).toHaveClass('btn-danger btn')
expect(deleteButton).toHaveClass(/danger/, 'btn')
expect(deleteButton).toHaveClass('btn-danger', 'btn')
expect(deleteButton).not.toHaveClass('btn-link')
expect(deleteButton).not.toHaveClass(/link/)
expect(deleteButton).not.toHaveClass(/btn extra/) // It does not match

expect(deleteButton).toHaveClass('btn-danger extra btn', {exact: true}) // to check if the element has EXACTLY a set of classes
expect(deleteButton).not.toHaveClass('btn-danger extra', {exact: true}) // if it has more than expected it is going to fail

expect(noClasses).not.toHaveClass()
toHaveFocus

断言元素是否获取焦点。

<div><input type="text" data-testid="element-to-focus" /></div>
const input = getByTestId('element-to-focus')

input.focus()
expect(input).toHaveFocus()

input.blur()
expect(input).not.toHaveFocus()
toHaveFormValues
toHaveFormValues(expectedValues: {
  [name: string]: any
})

检查表单或字段集是否包含每个给定名称的表单控件,并具有指定的值。

需要强调的是,这个匹配器只能在表单或字段集元素上调用。

这使得它可以利用 form 和 fieldset 中的 .elements 属性,可靠地获取其中的所有表单控件。

这也避免了用户提供一个包含多个表单的容器的可能性,从而避免了混合使用不相关的表单控件,甚至可能导致它们之间发生冲突。

这个匹配器抽象了根据表单控件类型获取表单控件值的特殊性。例如,<input> 元素具有 value 属性,但 <select> 元素则没有。以下是所有涵盖的情况列表: 

  • <input type="number">元素返回值是数字类型,而不是 一个字符串。
  • <input type="checkbox">元素:
    • 如果有一个具有给定 name 属性的单独复选框,它将被视为布尔值,如果复选框被选中,则返回 true,否则返回 false。
    • 如果有一个以上具有相同名称属性的复选框,则它们将作为单个表单控件集体处理,并将返回一个数组,其中包含集合中所有选中复选框的值。
  • <input type="radio"> 元素通过 name 属性分组,并且该组被视为单个表单控件。此表单控件将返回值作为字符串,该字符串对应于组内所选单选按钮的 value 属性值。
  • <input type="text">  元素将值作为字符串返回。这同样适用于 <input> 元素,其类型属性可能是上面未明确说明的其他任何类型(例如 search、email、date、password、hidden 等)。
  • 没有 multiple 属性的 <select> 元素将返回与选定选项的 value 属性相对应的字符串值,如果没有选定选项,则返回 undefined。
  • <select multiple> 元素将值作为包含所有选定选项值的数组返回。
  • <textarea> 元素将它们的值作为字符串返回。该值对应于它们的节点内容。

例如,以上规则使得从一个单选控件的使用切换到一组单选按钮的使用变得简单。或者从一个多选控件的使用切换到一组复选框的使用也变得简单。这个匹配器用来比较的形式值集合是一样的。

<form data-testid="login-form">
  <input type="text" name="username" value="jane.doe" />
  <input type="password" name="password" value="12345678" />
  <input type="checkbox" name="rememberMe" checked />
  <button type="submit">Sign in</button>
</form>
expect(getByTestId('login-form')).toHaveFormValues({
  username: 'jane.doe',
  rememberMe: true,
})
toHaveStyle
toHaveStyle(css: string | object)

检查某个元素是否应用了具有特定值的特定 CSS 属性。只有当元素应用了所有期望的属性时才会匹配,而不仅仅是其中一些属性。

<button
  data-testid="delete-button"
  style="display: none; background-color: red"
>
  Delete item
</button>
const button = getByTestId('delete-button')

expect(button).toHaveStyle('display: none')
expect(button).toHaveStyle({display: 'none'})
expect(button).toHaveStyle(`
  background-color: red;
  display: none;
`)
expect(button).toHaveStyle({
  backgroundColor: 'red',
  display: 'none',
})
expect(button).not.toHaveStyle(`
  background-color: blue;
  display: none;
`)
expect(button).not.toHaveStyle({
  backgroundColor: 'blue',
  display: 'none',
})

这也适用于通过类名应用于元素的规则,这些规则在文档当前活动的样式表中定义。CSS优先级的通常规则适用。

toHaveTextContent
toHaveTextContent(text: string | RegExp, options?: {normalizeWhitespace: boolean})

检查给定的节点是否具有文本内容。这支持元素,但也支持文本节点和片段。当传递一个字符串参数时,它将对节点内容进行部分大小写敏感匹配。要进行不区分大小写的匹配,您可以使用带有/i修饰符的RegExp。如果你想匹配整个内容,你可以使用正则表达式来实现。

<span data-testid="text-content">Text Content</span>
const element = getByTestId('text-content')

expect(element).toHaveTextContent('Content')
expect(element).toHaveTextContent(/^Text Content$/) // to match the whole content
expect(element).toHaveTextContent(/content$/i) // to use case-insensitive match
expect(element).not.toHaveTextContent('content')
toHaveValue
toHaveValue(value: string | string[] | number)

检查给定的表单元素是否具有指定的值。它接受 <input> 和 <select> <textarea> <input type="checkbox"> 和 <input type="radio">,只有使用 oBeChecked 或toHaveFormValues 才能进行有意义的匹配。

对于所有其他表单元素,值匹配使用的是与 toHaveFormValues 相同的算法。

<input type="text" value="text" data-testid="input-text" />
<input type="number" value="5" data-testid="input-number" />
<input type="text" data-testid="input-empty" />
<select multiple data-testid="select-number">
  <option value="first">First Value</option>
  <option value="second" selected>Second Value</option>
  <option value="third" selected>Third Value</option>
</select>
const textInput = getByTestId('input-text')
const numberInput = getByTestId('input-number')
const emptyInput = getByTestId('input-empty')
const selectInput = getByTestId('select-number')

expect(textInput).toHaveValue('text')
expect(numberInput).toHaveValue(5)
expect(emptyInput).not.toHaveValue()
expect(selectInput).toHaveValue(['second', 'third'])
toHaveDisplayValue
toHaveDisplayValue(value: string | RegExp | (string|RegExp)[])

检查给定的表单元素是否具有指定的显示值(最终用户将看到的值)。它接受 <input><select><textarea><input type="checkbox"> 和 <input type="radio">,只有使用 oBeChecked 或 toHaveFormValues 才能进行有意义的匹配。

<label for="input-example">First name</label>
<input type="text" id="input-example" value="Luca" />

<label for="textarea-example">Description</label>
<textarea id="textarea-example">An example description here.</textarea>

<label for="single-select-example">Fruit</label>
<select id="single-select-example">
  <option value="">Select a fruit...</option>
  <option value="banana">Banana</option>
  <option value="ananas">Ananas</option>
  <option value="avocado">Avocado</option>
</select>

<label for="multiple-select-example">Fruits</label>
<select id="multiple-select-example" multiple>
  <option value="">Select a fruit...</option>
  <option value="banana" selected>Banana</option>
  <option value="ananas">Ananas</option>
  <option value="avocado" selected>Avocado</option>
</select>
const input = screen.getByLabelText('First name')
const textarea = screen.getByLabelText('Description')
const selectSingle = screen.getByLabelText('Fruit')
const selectMultiple = screen.getByLabelText('Fruits')

expect(input).toHaveDisplayValue('Luca')
expect(input).toHaveDisplayValue(/Luc/)
expect(textarea).toHaveDisplayValue('An example description here.')
expect(textarea).toHaveDisplayValue(/example/)
expect(selectSingle).toHaveDisplayValue('Select a fruit...')
expect(selectSingle).toHaveDisplayValue(/Select/)
expect(selectMultiple).toHaveDisplayValue([/Avocado/, 'Banana'])
toBeChecked

检查给定的元素是否被选中。它接受类型为复选框或单选按钮的 input,以及具有复选框、单选按钮或 switch 和有效的aria-checked属性("true"或"false")的元素。

<input type="checkbox" checked data-testid="input-checkbox-checked" />
<input type="checkbox" data-testid="input-checkbox-unchecked" />
<div role="checkbox" aria-checked="true" data-testid="aria-checkbox-checked" />
<div
  role="checkbox"
  aria-checked="false"
  data-testid="aria-checkbox-unchecked"
/>

<input type="radio" checked value="foo" data-testid="input-radio-checked" />
<input type="radio" value="foo" data-testid="input-radio-unchecked" />
<div role="radio" aria-checked="true" data-testid="aria-radio-checked" />
<div role="radio" aria-checked="false" data-testid="aria-radio-unchecked" />
<div role="switch" aria-checked="true" data-testid="aria-switch-checked" />
<div role="switch" aria-checked="false" data-testid="aria-switch-unchecked" />
const inputCheckboxChecked = getByTestId('input-checkbox-checked')
const inputCheckboxUnchecked = getByTestId('input-checkbox-unchecked')
const ariaCheckboxChecked = getByTestId('aria-checkbox-checked')
const ariaCheckboxUnchecked = getByTestId('aria-checkbox-unchecked')
expect(inputCheckboxChecked).toBeChecked()
expect(inputCheckboxUnchecked).not.toBeChecked()
expect(ariaCheckboxChecked).toBeChecked()
expect(ariaCheckboxUnchecked).not.toBeChecked()

const inputRadioChecked = getByTestId('input-radio-checked')
const inputRadioUnchecked = getByTestId('input-radio-unchecked')
const ariaRadioChecked = getByTestId('aria-radio-checked')
const ariaRadioUnchecked = getByTestId('aria-radio-unchecked')
expect(inputRadioChecked).toBeChecked()
expect(inputRadioUnchecked).not.toBeChecked()
expect(ariaRadioChecked).toBeChecked()
expect(ariaRadioUnchecked).not.toBeChecked()

const ariaSwitchChecked = getByTestId('aria-switch-checked')
const ariaSwitchUnchecked = getByTestId('aria-switch-unchecked')
expect(ariaSwitchChecked).toBeChecked()
expect(ariaSwitchUnchecked).not.toBeChecked()
toBePartiallyChecked

检查给定的元素是否部分被选中。它接受类型为checkbox的输入和具有checkbox角色的元素,其aria-checked属性值为"mixed",或者类型为checkbox的输入,其indeterminate属性设置为true。

<input type="checkbox" aria-checked="mixed" data-testid="aria-checkbox-mixed" />
<input type="checkbox" checked data-testid="input-checkbox-checked" />
<input type="checkbox" data-testid="input-checkbox-unchecked" />
<div role="checkbox" aria-checked="true" data-testid="aria-checkbox-checked" />
<div
  role="checkbox"
  aria-checked="false"
  data-testid="aria-checkbox-unchecked"
/>
<input type="checkbox" data-testid="input-checkbox-indeterminate" />
const ariaCheckboxMixed = getByTestId('aria-checkbox-mixed')
const inputCheckboxChecked = getByTestId('input-checkbox-checked')
const inputCheckboxUnchecked = getByTestId('input-checkbox-unchecked')
const ariaCheckboxChecked = getByTestId('aria-checkbox-checked')
const ariaCheckboxUnchecked = getByTestId('aria-checkbox-unchecked')
const inputCheckboxIndeterminate = getByTestId('input-checkbox-indeterminate')

expect(ariaCheckboxMixed).toBePartiallyChecked()
expect(inputCheckboxChecked).not.toBePartiallyChecked()
expect(inputCheckboxUnchecked).not.toBePartiallyChecked()
expect(ariaCheckboxChecked).not.toBePartiallyChecked()
expect(ariaCheckboxUnchecked).not.toBePartiallyChecked()

inputCheckboxIndeterminate.indeterminate = true
expect(inputCheckboxIndeterminate).toBePartiallyChecked()
toHaveRole
toHaveRole(expectedRole: string)

断言元素具有预期的角色。这在您已经通过除角色本身以外的其他查询访问到某个元素,并想对其可访问性做出更多断言的情况下是非常有用的。该角色可以匹配一个明确的角色(通过 role 属性),或者通过隐式 ARIA 语义匹配一个隐式角色。

注意:角色是通过字符串相等性直接匹配的,不会继承 ARIA 角色层次结构。因此,查询类似 'checkbox' 的超类角色不会包含具有类似 'switch' 的子类角色的元素。

<button data-testid="button">Continue</button>
<div role="button" data-testid="button-explicit">Continue</button>
<button role="switch button" data-testid="button-explicit-multiple">Continue</button>
<a href="/about" data-testid="link">About</a>
<a data-testid="link-invalid">Invalid link<a/>
expect(getByTestId('button')).toHaveRole('button')
expect(getByTestId('button-explicit')).toHaveRole('button')
expect(getByTestId('button-explicit-multiple')).toHaveRole('button')
expect(getByTestId('button-explicit-multiple')).toHaveRole('switch')
expect(getByTestId('link')).toHaveRole('link')
expect(getByTestId('link-invalid')).not.toHaveRole('link')
expect(getByTestId('link-invalid')).toHaveRole('generic')
toHaveErrorMessage

这个自定义匹配器已弃用。建议使用 toHaveAccessibleErrorMessage,它更符合官方规范的实现,更全面。

toHaveErrorMessage(text: string | RegExp)

检查给定的元素是否带有 ARIA 错误消息。使用 aria-errormessage 属性来引用包含自定义错误消息文本的另一个元素。 不允许多个id。 作者必须同时使用 aria-invalid 和 aria-errormessage。 可以通过 aria-errormessage 规范了解更多信息。

<label for="startTime"> Please enter a start time for the meeting: </label>
<input
  id="startTime"
  type="text"
  aria-errormessage="msgID"
  aria-invalid="true"
  value="11:30 PM"
/>
<span id="msgID" aria-live="assertive" style="visibility:visible">
  Invalid time: the time must be between 9:00 AM and 5:00 PM
</span>
const timeInput = getByLabel('startTime')

expect(timeInput).toHaveErrorMessage(
  'Invalid time: the time must be between 9:00 AM and 5:00 PM',
)
expect(timeInput).toHaveErrorMessage(/invalid time/i) // to partially match
expect(timeInput).toHaveErrorMessage(expect.stringContaining('Invalid time')) // to partially match
expect(timeInput).not.toHaveErrorMessage('Pikachu!')

参考:GitHub - testing-library/jest-dom: :owl: Custom jest matchers to test the state of the DOM

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值