非同期メソッド
非同期コードを扱うためのいくつかのユーティリティが提供されています。これらは、イベント、ユーザーアクション、タイムアウト、または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に転送されます。