本文へスキップ

ユーティリティAPI

以下のAPIには、実際のユーザーインタラクションとの一対一の対応がありません。
そのため、その動作は「認識された」ユーザーインタラクションがDOM上の実際のイベントにどのように変換されるかの解釈です。

clear()

clear(element: Element): Promise<void>

このAPIを使用すると、編集可能な要素を簡単にクリアできます。

  1. 要素にフォーカス
  2. ブラウザメニューのようにすべてのコンテンツを選択
  3. ブラウザメニューのようにコンテンツを削除
test('clear', async () => {
const user = userEvent.setup()

render(<textarea defaultValue="Hello, World!" />)

await user.clear(screen.getByRole('textbox'))

expect(screen.getByRole('textbox')).toHaveValue('')
})

要素にフォーカスできない場合、またはコンテンツを選択できない場合、`Promise` は拒否されます。

selectOptions(), deselectOptions()

selectOptions(
element: Element,
values: HTMLElement | HTMLElement[] | string[] | string,
): Promise<void>
deselectOptions(
element: Element,
values: HTMLElement | HTMLElement[] | string[] | string,
): Promise<void>

HTMLSelectElementまたはリストボックスで指定されたオプションを選択/選択解除します。

`values`パラメータは、値、HTMLコンテンツ、または要素自体をオプションとして参照できます。これらの配列も受け付けます。

`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()`を使用できます。

  1. `skipClick`が`true`でない限り、要素をクリックします。
  2. `initialSelectionStart`が設定されている場合、要素の選択範囲を設定します。`initialSelectionEnd`が設定されていない場合、これは縮小された選択範囲になります。
  3. `keyboard()`に従って指定された`text`を入力します。
  4. `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>

ユーザーがファイル入力をクリックして、結果として表示されるファイルアップロードダイアログでファイルを選択した場合のように、ファイル入力を変更します。

`applyAccept`が`false`に設定されていない限り、`accept`プロパティと一致しないファイルは自動的に破棄されます。

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])
})