user-event / utility APIs
Testing Library의 짝꿍 user-event 이해하기 - utility APIs편
Dec 01, 2023
다음 API는 실제 사용자 상호 작용에는 없는 동작을 제공한다.
따라서 다음 API가 제공하는 동작은 "인지된" 사용자 상호 작용이 DOM의 실제 이벤트로 어떻게 변환될 수 있는지를 보여준다.
clear()
clear(element: Element): Promise<void>이 API를 사용하여 편집 가능한 요소를 쉽게 지울 수 있다.
- 요소 포커싱
- 브라우저 메뉴에 따라 모든 내용 선택
- 브라우저 메뉴에 따라 내용 삭제
test('clear', async () => {
const user = userEvent.setup()
render(<textarea defaultValue="Hello, World!" />)
await user.clear(screen.getByRole('textbox'))
expect(screen.getByRole('textbox')).toHaveValue('')
})요소가 포커싱 되지 않거나 컨텐츠가 선택되지 않는경우
Promise 는 reject된다.selectOptions(), deselectOptions()
selectOptions(
element: Element,
values: HTMLElement | HTMLElement[] | string[] | string,
): Promise<void>
deselectOptions(
element: Element,
values: HTMLElement | HTMLElement[] | string[] | string,
): Promise<void>HTMLSelectElement 또는 listbox 에 주어진 옵션을 선택하거나 선택취소 한다.
values 매개변수는 옵션의 값과 HTML 컨텐츠를 참조하거나 요소를 받는다. 또한 이 두 가지 타입에 대한 배열(HTMLElement[] | string[])을 받을 수 있다.HTMLSelectElement 의 복수의 옵션을 선택 및 선택해제 하는 것은multiple이 지정된 경우에만 가능하다.
test('selectOptions', async () => {
const user = userEvent.setup()
render(
<select multiple>
<option value="1">A</option>
<option value="2">B</option>
<option value="3">C</option>
</select>
)
await user.selectOptions(screen.getByRole('listbox'), ['1', 'C'])
expect(screen.getByRole('option', {name: 'A'}).selected).tobe(true)
expect(screen.getByRole('option', {name: 'B'}).selected).toBe(false)
expect(screen.getByRole('option', {name: 'C'}).selected).toBe(true)
})test('deselectOptions', async () => {
const user = userEvent.setup()
render(
<select multiple>
<option value="1">A</option>
<option value="2" selected>
B
</option>
<option value="3">C</option>
</select>,
)
await user.deselectOptions(screen.getByRole('listbox'), '2')
expect(screen.getByText('B').selected).toBe(false)
})이 API는 포인터 이벤트를 트리거하므로 pointerEventsCheck 적용 대상이다.
type()
type(
element: Element,
text: KeyboardInput,
options?: {
skipClick?: boolean
skipAutoClose?: boolean
initialSelectionStart?: number
initialSelectionEnd?: number
}
): Promise<void>입력 가능 요소에 입력한다.
키보드의 버튼을 누르는 시뮬레이션을 하려면keyboard()를 사용해야 한다. 일부 텍스트를 입력 필드 또는 텍스트 영역에 편리하게 삽입하고자 할 경우type()을 사용한다.
skipClick이true가 아니라면, 요소를 클릭한다.
initialSelectionStart가 설정되어 있으면 요소에서 선택을 설정하고initialSelectionEnd가 설정되어 있지 않으면 결과적으로 선택이 해제된다.
keyboard()에 할당된 텍스트를 입력한다.
skipAutoClose가true가 아니라면, 눌려진 키를 해제한다.
test('type into an input field', async () => {
const user = userEvent.setup()
render(<input defaultValue="Hello, "/>)
const input = screen.getByRole('textbox')
await user.type(input, ' World!')
expect(input).toHaveValue('Hello, World!')
})upload()
upload(
element: HTMLElement,
fileOrFiles: File | File[],
): Promise<void>파일 업로드 대화상자에서 사용자가 파일 입력을 클릭하고 파일을 선택하는 것처럼 파일 입력을 변경한다.
test('upload file', async () => {
const user = userEvent.setup()
render(
<div>
<label htmlFor="file-uploader">Upload file:</label>
<input id="file-uploader" type="file" />
</div>
)
const file = new File(['hello'], 'hello.png', {type: 'image/png'})
const input = screen.getByLabelText(/upload file/i)
await user.upload(input, file)
expect(input.files[0]).toBe(file)
expect(input.files.item(0)).toBe(file)
expect(input.files).toHaveLength(1)
})
test('upload multiple files', async () => {
const user = userEvent.setup()
render(
<div>
<label htmlFor="file-uploader">Upload file:</label>
<input id="file-uploader" type="file" multiple />
</div>,
)
const files = [
new File(['hello'], 'hello.png', {type: 'image/png'}),
new File(['there'], 'there.png', {type: 'image/png'}),
]
const input = screen.getByLabelText(/upload file/i)
await user.upload(input, files)
expect(input.files).toHaveLength(2)
expect(input.files[0]).toBe(files[0])
expect(input.files[1]).toBe(files[1])
})Share article