mirror of
https://github.com/hanzoai/vitest.git
synced 2026-09-24 17:04:25 +00:00
237 lines
8.8 KiB
TypeScript
237 lines
8.8 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { render } from './utils'
|
|
|
|
describe('.toHaveAccessibleErrorMessage', () => {
|
|
const input = 'input'
|
|
const errorId = 'error-id'
|
|
const error = 'This field is invalid'
|
|
const strings = {true: String(true), false: String(false)}
|
|
|
|
describe('Positive Test Cases', () => {
|
|
it("Fails the test if an invalid `id` is provided for the target element's `aria-errormessage`", () => {
|
|
const secondId = 'id2'
|
|
const secondError = 'LISTEN TO ME!!!'
|
|
|
|
const {queryByTestId} = render(`
|
|
<div>
|
|
<${input} data-testid="${input}" aria-invalid="${strings.true}" aria-errormessage="${errorId} ${secondId}" />
|
|
<div data-testid="${errorId}" id="${errorId}" role="alert">${error}</div>
|
|
<div data-testid="${secondId}" id="${secondId}" role="alert">${secondError}</div>
|
|
</div>
|
|
`)
|
|
|
|
const field = queryByTestId('input')
|
|
expect(field).toHaveAccessibleErrorMessage()
|
|
expect(field).toHaveAccessibleErrorMessage(new RegExp(error[0]))
|
|
|
|
expect(field).toHaveAccessibleErrorMessage(error + ' ' + secondError)
|
|
|
|
expect(() => expect(field).toHaveAccessibleErrorMessage(error)).toThrow()
|
|
expect(() =>
|
|
expect(field).toHaveAccessibleErrorMessage(secondError),
|
|
).toThrow()
|
|
|
|
expect(field).toHaveAccessibleErrorMessage(new RegExp(secondError[0]))
|
|
})
|
|
|
|
it('Fails the test if the target element is valid according to the WAI-ARIA spec', () => {
|
|
const noAriaInvalidAttribute = 'no-aria-invalid-attribute'
|
|
const validFieldState = 'false'
|
|
const invalidFieldStates = [
|
|
'true',
|
|
// difference with jest-dom
|
|
// https://www.w3.org/TR/wai-aria-1.2/#aria-invalid
|
|
// If the attribute is not present, or its value is false, or its value
|
|
// is an EMPTY STRING, the default value of false applies.
|
|
// '',
|
|
'grammar',
|
|
'spelling',
|
|
'asfdafbasdfasa',
|
|
]
|
|
|
|
function renderFieldWithState(state) {
|
|
return render(`
|
|
<div>
|
|
<${input} data-testid="${input}" aria-invalid="${state}" aria-errormessage="${errorId}" />
|
|
<div data-testid="${errorId}" id="${errorId}" role="alert">${error}</div>
|
|
<input data-testid="${noAriaInvalidAttribute}" aria-errormessage="${errorId}" />
|
|
</div>
|
|
`)
|
|
}
|
|
|
|
// Success Cases
|
|
invalidFieldStates.forEach(invalidState => {
|
|
const {queryByTestId} = renderFieldWithState(invalidState)
|
|
const field = queryByTestId('input')
|
|
|
|
expect(field).toHaveAccessibleErrorMessage()
|
|
expect(field).toHaveAccessibleErrorMessage(error)
|
|
})
|
|
|
|
// Failure Case
|
|
const {queryByTestId} = renderFieldWithState(validFieldState)
|
|
const field = queryByTestId('input')
|
|
const fieldWithoutAttribute = queryByTestId(noAriaInvalidAttribute)
|
|
|
|
expect(() => expect(fieldWithoutAttribute).toHaveAccessibleErrorMessage())
|
|
.toThrowErrorMatchingInlineSnapshot(`
|
|
[Error: expect(element).toHaveAccessibleErrorMessage()
|
|
|
|
Expected element to have accessible error message, but got nothing]
|
|
`)
|
|
|
|
expect(() => expect(field).toHaveAccessibleErrorMessage())
|
|
.toThrowErrorMatchingInlineSnapshot(`
|
|
[Error: expect(element).toHaveAccessibleErrorMessage()
|
|
|
|
Expected element to have accessible error message, but got nothing]
|
|
`)
|
|
|
|
// Assume the remaining error messages are the EXACT same as above
|
|
expect(() => expect(field).toHaveAccessibleErrorMessage(error)).toThrow()
|
|
expect(() =>
|
|
expect(field).toHaveAccessibleErrorMessage(new RegExp(error, 'i')),
|
|
).toThrow()
|
|
})
|
|
|
|
it('Passes the test if the target element has ANY recognized, non-empty error message', () => {
|
|
const {queryByTestId} = render(`
|
|
<div>
|
|
<${input} data-testid="${input}" aria-invalid="${strings.true}" aria-errormessage="${errorId}" />
|
|
<div data-testid="${errorId}" id="${errorId}" role="alert">${error}</div>
|
|
</div>
|
|
`)
|
|
|
|
const field = queryByTestId(input)
|
|
expect(field).toHaveAccessibleErrorMessage()
|
|
})
|
|
|
|
it('Fails the test if NO recognized, non-empty error message was found for the target element', () => {
|
|
const empty = 'empty'
|
|
const emptyErrorId = 'empty-error'
|
|
const missing = 'missing'
|
|
|
|
const {queryByTestId} = render(`
|
|
<div>
|
|
<input data-testid="${empty}" aria-invalid="${strings.true}" aria-errormessage="${emptyErrorId}" />
|
|
<div data-testid="${emptyErrorId}" id="${emptyErrorId}" role="alert"></div>
|
|
|
|
<input data-testid="${missing}" aria-invalid="${strings.true}" aria-errormessage="${missing}-error" />
|
|
</div>
|
|
`)
|
|
|
|
const fieldWithEmptyError = queryByTestId(empty)
|
|
const fieldMissingError = queryByTestId(missing)
|
|
|
|
expect(() => expect(fieldWithEmptyError).toHaveAccessibleErrorMessage())
|
|
.toThrowErrorMatchingInlineSnapshot(`
|
|
[Error: expect(element).toHaveAccessibleErrorMessage()
|
|
|
|
Expected element to have accessible error message, but got nothing]
|
|
`)
|
|
|
|
expect(() => expect(fieldMissingError).toHaveAccessibleErrorMessage())
|
|
.toThrowErrorMatchingInlineSnapshot(`
|
|
[Error: expect(element).toHaveAccessibleErrorMessage()
|
|
|
|
Expected element to have accessible error message, but got nothing]
|
|
`)
|
|
})
|
|
|
|
it('Passes the test if the target element has the error message that was SPECIFIED', () => {
|
|
const {queryByTestId} = render(`
|
|
<div>
|
|
<${input} data-testid="${input}" aria-invalid="${strings.true}" aria-errormessage="${errorId}" />
|
|
<div data-testid="${errorId}" id="${errorId}" role="alert">${error}</div>
|
|
</div>
|
|
`)
|
|
|
|
const field = queryByTestId(input)
|
|
const halfOfError = error.slice(0, Math.floor(error.length * 0.5))
|
|
|
|
expect(field).toHaveAccessibleErrorMessage(error)
|
|
expect(field).toHaveAccessibleErrorMessage(new RegExp(halfOfError, 'i'))
|
|
expect(field).toHaveAccessibleErrorMessage(
|
|
expect.stringContaining(halfOfError),
|
|
)
|
|
expect(field).toHaveAccessibleErrorMessage(
|
|
expect.stringMatching(new RegExp(halfOfError, 'i')),
|
|
)
|
|
})
|
|
|
|
it('Fails the test if the target element DOES NOT have the error message that was SPECIFIED', () => {
|
|
const {queryByTestId} = render(`
|
|
<div>
|
|
<${input} data-testid="${input}" aria-invalid="${strings.true}" aria-errormessage="${errorId}" />
|
|
<div data-testid="${errorId}" id="${errorId}" role="alert">${error}</div>
|
|
</div>
|
|
`)
|
|
|
|
const field = queryByTestId(input)
|
|
const msg = 'asdflkje2984fguyvb bnafdsasfa;lj'
|
|
|
|
expect(() => expect(field).toHaveAccessibleErrorMessage(''))
|
|
.toThrowErrorMatchingInlineSnapshot(`
|
|
[Error: expect(element).toHaveAccessibleErrorMessage()
|
|
|
|
Expected element to have accessible error message:
|
|
|
|
Received:
|
|
This field is invalid]
|
|
`)
|
|
|
|
// Assume this error is SIMILAR to the error above
|
|
expect(() => expect(field).toHaveAccessibleErrorMessage(msg)).toThrow()
|
|
expect(() =>
|
|
expect(field).toHaveAccessibleErrorMessage(
|
|
error.slice(0, Math.floor(error.length * 0.5)),
|
|
),
|
|
).toThrow()
|
|
|
|
expect(() =>
|
|
expect(field).toHaveAccessibleErrorMessage(new RegExp(msg, 'i')),
|
|
).toThrowErrorMatchingInlineSnapshot(`
|
|
[Error: expect(element).toHaveAccessibleErrorMessage()
|
|
|
|
Expected element to have accessible error message:
|
|
/asdflkje2984fguyvb bnafdsasfa;lj/i
|
|
Received:
|
|
This field is invalid]
|
|
`)
|
|
})
|
|
|
|
it('Normalizes the whitespace of the received error message', () => {
|
|
const {queryByTestId} = render(`
|
|
<div>
|
|
<${input} data-testid="${input}" aria-invalid="${strings.true}" aria-errormessage="${errorId}" />
|
|
<div data-testid="${errorId}" id="${errorId}" role="alert">
|
|
Step
|
|
1
|
|
of
|
|
9000
|
|
</div>
|
|
</div>
|
|
`)
|
|
|
|
const field = queryByTestId(input)
|
|
expect(field).toHaveAccessibleErrorMessage('Step 1 of 9000')
|
|
})
|
|
})
|
|
|
|
// These tests for the `.not` use cases will help us cover our bases and complete test coverage
|
|
describe('Negated Test Cases', () => {
|
|
it('Passes the test if the target element is valid according to the WAI-ARIA spec', () => {
|
|
const {queryByTestId} = render(`
|
|
<div>
|
|
<${input} data-testid="${input}" aria-errormessage="${errorId}" />
|
|
<div data-testid="${errorId}" id="${errorId}" role="alert">${error}</div>
|
|
</div>
|
|
`)
|
|
|
|
const field = queryByTestId(input)
|
|
expect(field).not.toHaveAccessibleErrorMessage()
|
|
expect(field).not.toHaveAccessibleErrorMessage(error)
|
|
expect(field).not.toHaveAccessibleErrorMessage(new RegExp(error[0]))
|
|
})
|
|
})
|
|
}) |