非同期メソッド
非同期コードを扱うためのいくつかのユーティリティが提供されています。これらは、イベント、ユーザーアクション、タイムアウト、またはPromiseに応答して要素の表示または非表示を待機する場合に役立ちます。(非表示のテストに関するガイドを参照してください。)
非同期メソッドはPromiseを返すため、呼び出す際には必ず`await`または`.then`を使用してください。
findBy
クエリ
findBy
メソッドは、getBy
クエリとwaitFor
を組み合わせたものです。最後の引数としてwaitForオプションを受け付けます(例:`await screen.findByText('text', queryOptions, waitForOptions)`)。
findBy
クエリは、要素が表示されることが予想されるが、DOMへの変更がすぐに起こらない場合に機能します。
const button = screen.getByRole('button', {name: 'Click Me'})
fireEvent.click(button)
await screen.findByText('Clicked once')
fireEvent.click(button)
await screen.findByText('Clicked twice')
waitFor
function waitFor<T>(
callback: () => T | Promise<T>,
options?: {
container?: HTMLElement
timeout?: number
interval?: number
onTimeout?: (error: Error) => Error
mutationObserverOptions?: MutationObserverInit
},
): Promise<T>
任意の期間待機する必要がある場合は、期待する条件が満たされるまで待機するためにwaitFor
を使用できます。偽の条件を返すだけでは再試行はトリガーされません。条件を再試行するには、コールバックがエラーをスローする必要があります。簡単な例を以下に示します。
// ...
// Wait until the callback does not throw an error. In this case, that means
// it'll wait until the mock function has been called once.
await waitFor(() => expect(mockAPI).toHaveBeenCalledTimes(1))
// ...
waitFor
は、タイムアウトに達するまでコールバックを複数回実行することがあります。コールバックの回数は、timeout
とinterval
オプションによって制限されていることに注意してください。
これは、API呼び出しをモックする単体テストがあり、すべてのモックPromiseが解決されるのを待機する必要がある場合に役立ちます。
waitFor
コールバックでPromiseを返す場合(`async`構文で明示的または暗黙的に)、waitFor
ユーティリティはそのPromiseが拒否されるまでコールバックを再度呼び出しません。これにより、非同期的に確認する必要があるものをwaitFor
できます。
デフォルトのcontainer
はグローバルなdocument
です。待機する要素がcontainer
の子孫であることを確認してください。
デフォルトのinterval
は50ms
です。ただし、間隔を開始する前にコールバックをすぐに実行します。
デフォルトのtimeout
は1000ms
です。
デフォルトのonTimeout
はエラーを受け取り、エラーメッセージにcontainer
の印刷された状態を追加します。これにより、タイムアウトの原因を特定しやすくなるはずです。
デフォルトのmutationObserverOptions
は{subtree: true, childList: true, attributes: true, characterData: true}
であり、container
とそのすべての子孫に追加および削除された子要素(テキストノードを含む)を検出します。属性の変更も検出します。これらの変更が発生すると、コールバックが再実行されます。
waitForElementToBeRemoved
function waitForElementToBeRemoved<T>(
callback: (() => T) | T,
options?: {
container?: HTMLElement
timeout?: number
interval?: number
onTimeout?: (error: Error) => Error
mutationObserverOptions?: MutationObserverInit
},
): Promise<void>
DOMから要素の削除を待機するには、waitForElementToBeRemoved
を使用できます。waitForElementToBeRemoved
関数は、waitFor
ユーティリティをラップした小さな関数です。
最初の引数は、要素、要素の配列、または要素または要素の配列を返すコールバックである必要があります。
要素が削除されるためPromiseが解決される例を以下に示します。
const el = document.querySelector('div.getOuttaHere')
waitForElementToBeRemoved(document.querySelector('div.getOuttaHere')).then(() =>
console.log('Element no longer in DOM'),
)
el.setAttribute('data-neat', true)
// other mutations are ignored...
el.parentElement.removeChild(el)
// logs 'Element no longer in DOM'
最初の引数がnull
または空の配列の場合、waitForElementToBeRemoved
はエラーをスローします。
waitForElementToBeRemoved(null).catch(err => console.log(err))
waitForElementToBeRemoved(queryByText(/not here/i)).catch(err =>
console.log(err),
)
waitForElementToBeRemoved(queryAllByText(/not here/i)).catch(err =>
console.log(err),
)
waitForElementToBeRemoved(() => getByText(/not here/i)).catch(err =>
console.log(err),
)
// Error: The element(s) given to waitForElementToBeRemoved are already removed. waitForElementToBeRemoved requires that the element(s) exist(s) before waiting for removal.
オプションオブジェクトはwaitFor
に転送されます。