アサーション API
Vitest は、@testing-library/jest-dom
ライブラリから派生した、幅広い DOM アサーションを標準で提供しています。これらのアサーションは、ロケーターと組み込みのリトライ機能をサポートしています。
TypeScript のサポート
TypeScript を使用している場合、または expect
で適切な型ヒントが必要な場合は、@vitest/browser/context
がどこかで参照されていることを確認してください。一度もインポートしていない場合は、tsconfig.json
の対象となる任意のファイルに reference
コメントを追加できます。
/// <reference types="@vitest/browser/context" />
ブラウザでのテストは、非同期の性質上、不安定になる可能性があります。そのため、タイムアウト、ネットワークリクエスト、アニメーションなどによって条件が遅延しても、アサーションが成功することを保証する方法を持つことが重要です。この目的のために、Vitest は expect.poll
および expect.element
API を介して、最初から利用できるリトライ可能なアサーションを提供します。
import { expect, test } from 'vitest';
import { page } from '@vitest/browser/context';
test('error banner is rendered', async () => {
triggerError();
// このロケーターは、メソッドが呼び出されたときに要素を見つけようとします。
// この呼び出し自体は、要素の存在をチェックしません。
const banner = page.getByRole('alert', {
name: /error/i,
});
// Vitest は組み込みのリトライ機能を持つ `expect.element` を提供します。
// これは、要素が DOM に存在し、かつ `element.textContent` の内容が "Error!" と等しいことを、すべての条件が満たされるまで繰り返しチェックします。
await expect.element(banner).toHaveTextContent('Error!');
});
page.getBy*
ロケーターを使用する場合は、テストの不安定さを軽減するために常に expect.element
を使用することをお勧めします。expect.element
は以下のオプションを2番目の引数として受け取ります。
interface ExpectPollOptions {
// アサーションを再試行する間隔(ミリ秒単位)
// デフォルトは "expect.poll.interval" 設定オプション
interval?: number;
// アサーションを再試行する最大時間(ミリ秒単位)
// デフォルトは "expect.poll.timeout" 設定オプション
timeout?: number;
// アサーションが失敗したときに表示されるメッセージ
message?: string;
}
TIP
expect.element
は expect.poll(() => element)
の短縮形であり、まったく同じように機能します。
toHaveTextContent
およびその他のすべてのアサーションは、組み込みのリトライメカニズムなしで通常の expect
でも引き続き利用できます。
// .textContent が `'Error!'` でない場合、すぐに失敗します。
expect(banner).toHaveTextContent('Error!');
toBeDisabled
function toBeDisabled(): Promise<void>;
要素がユーザーの視点から無効になっているかどうかをチェックします。
このマッチャーは、要素がフォームコントロールであり、disabled
属性が指定されているか、または disabled
属性を持つフォーム要素の子孫である場合に一致します。
HTML の button
、input
、select
、textarea
、option
、optgroup
などのネイティブコントロール要素のみが disabled
属性によって無効にできることに注意してください。カスタム要素でない限り、他の要素の disabled
属性は無視されます。
<button data-testid="button" type="submit" disabled>submit</button>
await expect.element(getByTestId('button')).toBeDisabled(); // ✅
await expect.element(getByTestId('button')).not.toBeDisabled(); // ❌
toBeEnabled
function toBeEnabled(): Promise<void>;
要素がユーザーの視点から無効になっていないかどうかをチェックします。
not.toBeDisabled()
と同じように機能します。テストで二重否定を避けるために、このマッチャーを使用してください。
<button data-testid="button" type="submit" disabled>submit</button>
await expect.element(getByTestId('button')).toBeEnabled(); // ✅
await expect.element(getByTestId('button')).not.toBeEnabled(); // ❌
toBeEmptyDOMElement
function toBeEmptyDOMElement(): Promise<void>;
要素にユーザーに表示されるコンテンツがないことをアサートします。コメントは無視しますが、要素に空白が含まれている場合は失敗します。
<span data-testid="not-empty"><span data-testid="empty"></span></span>
<span data-testid="with-whitespace"> </span>
<span data-testid="with-comment"><!-- comment --></span>
await expect.element(getByTestId('empty')).toBeEmptyDOMElement();
await expect.element(getByTestId('not-empty')).not.toBeEmptyDOMElement();
await expect.element(getByTestId('with-whitespace')).not.toBeEmptyDOMElement();
toBeInTheDocument
function toBeInTheDocument(): Promise<void>;
要素がドキュメントに存在するかどうかをアサートします。
<svg data-testid="svg-element"></svg>
await expect.element(getByTestId('svg-element')).toBeInTheDocument();
await expect.element(getByTestId('does-not-exist')).not.toBeInTheDocument();
WARNING
このマッチャーは、切り離された要素を見つけません。要素は toBeInTheDocument
で見つけられるよう、ドキュメントに追加されている必要があります。切り離された要素を検索したい場合は、toContainElement
を使用してください。
toBeInvalid
function toBeInvalid(): Promise<void>;
要素が現在無効であるかどうかをチェックします。
要素は、aria-invalid
属性に値がない場合、または値が "true"
である場合、あるいは checkValidity()
の結果が false
である場合に無効と見なされます。
<input data-testid="no-aria-invalid" />
<input data-testid="aria-invalid" aria-invalid />
<input data-testid="aria-invalid-value" aria-invalid="true" />
<input data-testid="aria-invalid-false" aria-invalid="false" />
<form data-testid="valid-form">
<input />
</form>
<form data-testid="invalid-form">
<input required />
</form>
await expect.element(getByTestId('no-aria-invalid')).not.toBeInvalid();
await expect.element(getByTestId('aria-invalid')).toBeInvalid();
await expect.element(getByTestId('aria-invalid-value')).toBeInvalid();
await expect.element(getByTestId('aria-invalid-false')).not.toBeInvalid();
await expect.element(getByTestId('valid-form')).not.toBeInvalid();
await expect.element(getByTestId('invalid-form')).toBeInvalid();
toBeRequired
function toBeRequired(): Promise<void>;
フォーム要素が現在必須であるかどうかをチェックします。
要素は、required
または aria-required="true"
属性を持つ場合に必須と見なされます。
<input data-testid="required-input" required />
<input data-testid="aria-required-input" aria-required="true" />
<input data-testid="conflicted-input" required aria-required="false" />
<input data-testid="aria-not-required-input" aria-required="false" />
<input data-testid="optional-input" />
<input data-testid="unsupported-type" type="image" required />
<select data-testid="select" required></select>
<textarea data-testid="textarea" required></textarea>
<div data-testid="supported-role" role="tree" required></div>
<div data-testid="supported-role-aria" role="tree" aria-required="true"></div>
await expect.element(getByTestId('required-input')).toBeRequired();
await expect.element(getByTestId('aria-required-input')).toBeRequired();
await expect.element(getByTestId('conflicted-input')).toBeRequired();
await expect.element(getByTestId('aria-not-required-input')).not.toBeRequired();
await expect.element(getByTestId('optional-input')).not.toBeRequired();
await expect.element(getByTestId('unsupported-type')).not.toBeRequired();
await expect.element(getByTestId('select')).toBeRequired();
await expect.element(getByTestId('textarea')).toBeRequired();
await expect.element(getByTestId('supported-role')).not.toBeRequired();
await expect.element(getByTestId('supported-role-aria')).toBeRequired();
toBeValid
function toBeValid(): Promise<void>;
要素の値が現在有効であるかどうかをチェックします。
要素は、aria-invalid
属性がない場合、または属性値が "false"
である場合に有効と見なされます。フォーム要素の場合は、checkValidity()
の結果も true
である必要があります。
<input data-testid="no-aria-invalid" />
<input data-testid="aria-invalid" aria-invalid />
<input data-testid="aria-invalid-value" aria-invalid="true" />
<input data-testid="aria-invalid-false" aria-invalid="false" />
<form data-testid="valid-form">
<input />
</form>
<form data-testid="invalid-form">
<input required />
</form>
await expect.element(getByTestId('no-aria-invalid')).toBeValid();
await expect.element(getByTestId('aria-invalid')).not.toBeValid();
await expect.element(getByTestId('aria-invalid-value')).not.toBeValid();
await expect.element(getByTestId('aria-invalid-false')).toBeValid();
await expect.element(getByTestId('valid-form')).toBeValid();
await expect.element(getByTestId('invalid-form')).not.toBeValid();
toBeVisible
function toBeVisible(): Promise<void>;
要素が現在ユーザーに表示されているかどうかをチェックします。
要素は、空でないバウンディングボックスを持ち、visibility:hidden
の計算スタイルを持たない場合に表示されていると見なされます。
この定義によると、次の点に注意してください。
- サイズがゼロの要素は表示されているとは見なされません。
display:none
の要素は表示されているとは見なされません。opacity:0
の要素は表示されていると見なされます。
リスト内の少なくとも1つの要素が表示されていることを確認するには、locator.first()
を使用します。
// 特定の要素が表示されている。
await expect.element(page.getByText('Welcome')).toBeVisible();
// リスト内の少なくとも1つの項目が表示されている。
await expect.element(page.getByTestId('todo-item').first()).toBeVisible();
// 2つの要素のうち少なくとも1つが表示されている(両方の場合もある)。
await expect
.element(
page
.getByRole('button', { name: 'Sign in' })
.or(page.getByRole('button', { name: 'Sign up' }))
.first()
)
.toBeVisible();
toContainElement
function toContainElement(
element: HTMLElement | SVGElement | null
): Promise<void>;
ある要素が別の要素を子孫として含んでいるかどうかをアサートします。
<span data-testid="ancestor"><span data-testid="descendant"></span></span>
const ancestor = getByTestId('ancestor');
const descendant = getByTestId('descendant');
const nonExistantElement = getByTestId('does-not-exist');
await expect.element(ancestor).toContainElement(descendant);
await expect.element(descendant).not.toContainElement(ancestor);
await expect.element(ancestor).not.toContainElement(nonExistantElement);
toContainHTML
function toContainHTML(htmlText: string): Promise<void>;
HTML 要素を表す文字列が別の要素に含まれているかどうかをアサートします。文字列は有効な HTML である必要があり、不完全な HTML を含んではいけません。
<span data-testid="parent"><span data-testid="child"></span></span>
// これらは有効な使用例です
await expect
.element(getByTestId('parent'))
.toContainHTML('<span data-testid="child"></span>');
await expect
.element(getByTestId('parent'))
.toContainHTML('<span data-testid="child" />');
await expect.element(getByTestId('parent')).not.toContainHTML('<br />');
// これらは機能しません
await expect
.element(getByTestId('parent'))
.toContainHTML('data-testid="child"');
await expect.element(getByTestId('parent')).toContainHTML('data-testid');
await expect.element(getByTestId('parent')).toContainHTML('</span>');
WARNING
このマッチャーは、ほとんどの場合、使用する必要がないでしょう。ブラウザでユーザーがアプリをどのように認識するかという観点からテストすることをお勧めします。そのため、特定の DOM 構造に対してテストすることは推奨されません。
テスト対象のコードが外部ソースから取得した HTML をレンダリングし、その HTML コードが意図したとおりに使用されたことを検証したい場合に役立つことがあります。
制御している DOM 構造をチェックするために使用すべきではありません。代わりに toContainElement
を使用してください。
toHaveAccessibleDescription
function toHaveAccessibleDescription(
description?: string | RegExp
): Promise<void>;
要素が期待されるアクセシブルな説明を持っていることをアサートします。
期待されるアクセシブルな説明の正確な文字列を渡すこともできますし、正規表現を渡すか、expect.stringContaining
または expect.stringMatching
を使用して部分一致させることも可能です。
<a
data-testid="link"
href="/"
aria-label="Home page"
title="A link to start over"
>Start</a
>
<a data-testid="extra-link" href="/about" aria-label="About page">About</a>
<img src="avatar.jpg" data-testid="avatar" alt="User profile pic" />
<img
src="logo.jpg"
data-testid="logo"
alt="Company logo"
aria-describedby="t1"
/>
<span id="t1" role="presentation">The logo of Our Company</span>
<img
src="logo.jpg"
data-testid="logo2"
alt="Company logo"
aria-description="The logo of Our Company"
/>
await expect.element(getByTestId('link')).toHaveAccessibleDescription();
await expect
.element(getByTestId('link'))
.toHaveAccessibleDescription('A link to start over');
await expect
.element(getByTestId('link'))
.not.toHaveAccessibleDescription('Home page');
await expect
.element(getByTestId('extra-link'))
.not.toHaveAccessibleDescription();
await expect.element(getByTestId('avatar')).not.toHaveAccessibleDescription();
await expect
.element(getByTestId('logo'))
.not.toHaveAccessibleDescription('Company logo');
await expect
.element(getByTestId('logo'))
.toHaveAccessibleDescription('The logo of Our Company');
await expect
.element(getByTestId('logo2'))
.toHaveAccessibleDescription('The logo of Our Company');
toHaveAccessibleErrorMessage
function toHaveAccessibleErrorMessage(message?: string | RegExp): Promise<void>;
要素が期待されるアクセシブルなエラーメッセージを持っていることをアサートします。
期待されるアクセシブルなエラーメッセージの正確な文字列を渡すことができます。 あるいは、正規表現を渡すか、expect.stringContaining
または expect.stringMatching
を使用して部分一致を実行することも可能です。
<input
aria-label="Has Error"
aria-invalid="true"
aria-errormessage="error-message"
/>
<div id="error-message" role="alert">This field is invalid</div>
<input aria-label="No Error Attributes" />
<input
aria-label="Not Invalid"
aria-invalid="false"
aria-errormessage="error-message"
/>
// 有効なエラーメッセージを持つ入力
await expect
.element(getByRole('textbox', { name: 'Has Error' }))
.toHaveAccessibleErrorMessage();
await expect
.element(getByRole('textbox', { name: 'Has Error' }))
.toHaveAccessibleErrorMessage('This field is invalid');
await expect
.element(getByRole('textbox', { name: 'Has Error' }))
.toHaveAccessibleErrorMessage(/invalid/i);
await expect
.element(getByRole('textbox', { name: 'Has Error' }))
.not.toHaveAccessibleErrorMessage('This field is absolutely correct!');
// 有効なエラーメッセージを持たない入力
await expect
.element(getByRole('textbox', { name: 'No Error Attributes' }))
.not.toHaveAccessibleErrorMessage();
await expect
.element(getByRole('textbox', { name: 'Not Invalid' }))
.not.toHaveAccessibleErrorMessage();
toHaveAccessibleName
function toHaveAccessibleName(name?: string | RegExp): Promise<void>;
要素が期待されるアクセシブルな名前を持っていることをアサートします。これは、たとえば、フォーム要素やボタンが適切にラベル付けされていることを確認するのに役立ちます。
期待されるアクセシブルな名前の正確な文字列を渡すこともできますし、正規表現を渡すか、expect.stringContaining
または expect.stringMatching
を使用して部分一致させることも可能です。
<img data-testid="img-alt" src="" alt="Test alt" />
<img data-testid="img-empty-alt" src="" alt="" />
<svg data-testid="svg-title"><title>Test title</title></svg>
<button data-testid="button-img-alt"><img src="" alt="Test" /></button>
<p><img data-testid="img-paragraph" src="" alt="" /> Test content</p>
<button data-testid="svg-button"><svg><title>Test</title></svg></p>
<div><svg data-testid="svg-without-title"></svg></div>
<input data-testid="input-title" title="test" />
await expect.element(getByTestId('img-alt')).toHaveAccessibleName('Test alt');
await expect.element(getByTestId('img-empty-alt')).not.toHaveAccessibleName();
await expect
.element(getByTestId('svg-title'))
.toHaveAccessibleName('Test title');
await expect.element(getByTestId('button-img-alt')).toHaveAccessibleName();
await expect.element(getByTestId('img-paragraph')).not.toHaveAccessibleName();
await expect.element(getByTestId('svg-button')).toHaveAccessibleName();
await expect
.element(getByTestId('svg-without-title'))
.not.toHaveAccessibleName();
await expect.element(getByTestId('input-title')).toHaveAccessibleName();
toHaveAttribute
function toHaveAttribute(attribute: string, value?: unknown): Promise<void>;
指定された要素が属性を持っているかどうかをチェックします。また、オプションで、属性が特定の期待値を持つか、expect.stringContaining
または expect.stringMatching
を使用して部分一致するかどうかをチェックすることもできます。
<button data-testid="ok-button" type="submit" disabled>ok</button>
const button = getByTestId('ok-button');
await expect.element(button).toHaveAttribute('disabled');
await expect.element(button).toHaveAttribute('type', 'submit');
await expect.element(button).not.toHaveAttribute('type', 'button');
await expect
.element(button)
.toHaveAttribute('type', expect.stringContaining('sub'));
await expect
.element(button)
.toHaveAttribute('type', expect.not.stringContaining('but'));
toHaveClass
function toHaveClass(
...classNames: string[],
options?: { exact: boolean }
): Promise<void>;
function toHaveClass(...classNames: (string | RegExp)[]): Promise<void>;
指定された要素が class
属性内に特定のクラスを持っているかどうかをチェックします。要素がクラスを持っていないことを確認する場合を除き、少なくとも1つのクラスを指定する必要があります。
クラス名のリストには、文字列と正規表現を含めることができます。正規表現は、ターゲット要素の個々のクラスごとに照合され、class
属性値全体に対しては照合されません。
WARNING
正規表現のみが提供されている場合、exact: true
オプションを使用できないことに注意してください。
<button data-testid="delete-button" class="btn extra btn-danger">
Delete item
</button>
<button data-testid="no-classes">No Classes</button>
const deleteButton = getByTestId('delete-button');
const noClasses = getByTestId('no-classes');
await expect.element(deleteButton).toHaveClass('extra');
await expect.element(deleteButton).toHaveClass('btn-danger btn');
await expect.element(deleteButton).toHaveClass(/danger/, 'btn');
await expect.element(deleteButton).toHaveClass('btn-danger', 'btn');
await expect.element(deleteButton).not.toHaveClass('btn-link');
await expect.element(deleteButton).not.toHaveClass(/link/);
// ⚠️ 正規表現は個々のクラスに対して一致し、classList 全体に対しては一致しません
await expect.element(deleteButton).not.toHaveClass(/btn extra/);
// 要素は(任意の順序で)クラスのセットを正確に持っています
await expect.element(deleteButton).toHaveClass('btn-danger extra btn', {
exact: true,
});
// 期待以上の場合は失敗します
await expect.element(deleteButton).not.toHaveClass('btn-danger extra', {
exact: true,
});
await expect.element(noClasses).not.toHaveClass();
toHaveFocus
function toHaveFocus(): Promise<void>;
要素がフォーカスを持っているかどうかをアサートします。
<div><input type="text" data-testid="element-to-focus" /></div>
const input = page.getByTestId('element-to-focus');
input.element().focus();
await expect.element(input).toHaveFocus();
input.element().blur();
await expect.element(input).not.toHaveFocus();
toHaveFormValues
function toHaveFormValues(
expectedValues: Record<string, unknown>
): Promise<void>;
フォームまたはフィールドセットが、指定された名前ごとにフォームコントロールを含み、指定された値を持っているかをチェックします。
TIP
このマッチャーは、フォームまたはフィールドセット要素に対してのみ呼び出すことができる点に注意してください。
これにより、form
および fieldset
の elements
プロパティを利用して、それらの中のすべてのフォームコントロールを確実に取得できます。
また、ユーザーが複数の form
を含むコンテナを提供することで、関連性のない、あるいは互いに競合する可能性のあるフォームコントロールが混在するのを回避できます。
このマッチャーは、フォームコントロールのタイプに応じてフォームコントロールの値が取得される特定の詳細を抽象化します。たとえば、<input>
要素には value
属性がありますが、<select>
要素にはありません。以下に、カバーされているすべてのケースのリストを示します。
<input type="number">
要素は、値を文字列ではなく数値として返します。<input type="checkbox">
要素:- 指定された
name
属性を持つものが1つだけの場合、それはブール値として扱われ、チェックボックスがチェックされていればtrue
、チェックされていなければfalse
を返します。 - 同じ
name
属性を持つチェックボックスが複数ある場合、それらはすべてまとめて単一のフォームコントロールとして扱われ、コレクション内で選択されたチェックボックスのすべての値を含む配列として値を返します。
- 指定された
<input type="radio">
要素はすべてname
属性でグループ化され、そのようなグループは単一のフォームコントロールとして扱われます。このフォームコントロールは、グループ内で選択されたラジオボタンのvalue
属性に対応する文字列として値を返します。<input type="text">
要素は、値を文字列として返します。これは、上記の異なるルールで明示的にカバーされていない他の可能なtype
属性を持つ<input>
要素(例:search
、email
、date
、password
、hidden
など)にも適用されます。multiple
属性を持たない<select>
要素は、選択されたoption
のvalue
属性に対応する文字列として値を返します。選択されたオプションがない場合はundefined
を返します。<select multiple>
要素は、選択されたオプションのすべての値を含む配列として値を返します。<textarea>
要素は、値を文字列として返します。値はノードの内容に対応します。
上記のルールにより、たとえば、単一の選択コントロールからラジオボタンのグループに切り替えたり、複数選択コントロールからチェックボックスのグループに切り替えたりすることが容易になります。このマッチャーが比較に使用するフォーム値のセットは同じです。
<form data-testid="login-form">
<input type="text" name="username" value="jane.doe" />
<input type="password" name="password" value="12345678" />
<input type="checkbox" name="rememberMe" checked />
<button type="submit">Sign in</button>
</form>
await expect.element(getByTestId('login-form')).toHaveFormValues({
username: 'jane.doe',
rememberMe: true,
});
toHaveStyle
function toHaveStyle(css: string | Partial<CSSStyleDeclaration>): Promise<void>;
特定の要素に特定の CSS プロパティが特定の値で適用されているかどうかをチェックします。要素が期待されるすべてのプロパティを適用している場合にのみ一致し、一部だけでは一致しません。
<button
data-testid="delete-button"
style="display: none; background-color: red"
>
Delete item
</button>
const button = getByTestId('delete-button');
await expect.element(button).toHaveStyle('display: none');
await expect.element(button).toHaveStyle({ display: 'none' });
await expect.element(button).toHaveStyle(`
background-color: red;
display: none;
`);
await expect.element(button).toHaveStyle({
backgroundColor: 'red',
display: 'none',
});
await expect.element(button).not.toHaveStyle(`
background-color: blue;
display: none;
`);
await expect.element(button).not.toHaveStyle({
backgroundColor: 'blue',
display: 'none',
});
これは、ドキュメントで現在アクティブなスタイルシートで一部のルールが定義されているクラス名を通じて要素に適用されるルールでも機能します。通常の CSS 優先順位ルールが適用されます。
toHaveTextContent
function toHaveTextContent(
text: string | RegExp,
options?: { normalizeWhitespace: boolean }
): Promise<void>;
指定されたノードがテキストコンテンツを持っているかどうかをチェックします。これは要素だけでなく、テキストノードやフラグメントもサポートします。
string
引数が渡されると、ノードコンテンツに対して部分的な大文字小文字を区別する一致を実行します。
大文字小文字を区別しない一致を実行するには、/i
修飾子を持つ RegExp
を使用できます。
コンテンツ全体を一致させたい場合は、RegExp
を使用してそれを行うことができます。
<span data-testid="text-content">Text Content</span>
const element = getByTestId('text-content');
await expect.element(element).toHaveTextContent('Content');
// コンテンツ全体を一致させるには
await expect.element(element).toHaveTextContent(/^Text Content$/);
// 大文字小文字を区別しない一致を使用するには
await expect.element(element).toHaveTextContent(/content$/i);
await expect.element(element).not.toHaveTextContent('content');
toHaveValue
function toHaveValue(value: string | string[] | number | null): Promise<void>;
指定されたフォーム要素が指定された値を持っているかどうかをチェックします。 これは、<input type="checkbox">
と <input type="radio">
を除く <input>
、<select>
、<textarea>
要素を受け入れます。これらの要素は、toBeChecked
または toHaveFormValues
を使用してのみ意味のある一致が可能です。
また、meter
、progressbar
、slider
、または spinbutton
のロールを持つ要素を受け入れ、それらの aria-valuenow
属性(数値として)をチェックします。
他のすべてのフォーム要素については、toHaveFormValues
と同じアルゴリズムを使用して値が一致します。
<input type="text" value="text" data-testid="input-text" />
<input type="number" value="5" data-testid="input-number" />
<input type="text" data-testid="input-empty" />
<select multiple data-testid="select-number">
<option value="first">First Value</option>
<option value="second" selected>Second Value</option>
<option value="third" selected>Third Value</option>
</select>
const textInput = getByTestId('input-text');
const numberInput = getByTestId('input-number');
const emptyInput = getByTestId('input-empty');
const selectInput = getByTestId('select-number');
await expect.element(textInput).toHaveValue('text');
await expect.element(numberInput).toHaveValue(5);
await expect.element(emptyInput).not.toHaveValue();
await expect.element(selectInput).toHaveValue(['second', 'third']);
toHaveDisplayValue
function toHaveDisplayValue(
value: string | RegExp | (string | RegExp)[]
): Promise<void>;
指定されたフォーム要素が指定された表示値(エンドユーザーが見る値)を持っているかどうかをチェックします。これは、<input type="checkbox">
と <input type="radio">
を除く <input>
、<select>
、<textarea>
要素を受け入れます。これらの要素は、toBeChecked
または toHaveFormValues
を使用してのみ意味のある一致が可能です。
<label for="input-example">First name</label>
<input type="text" id="input-example" value="Luca" />
<label for="textarea-example">Description</label>
<textarea id="textarea-example">An example description here.</textarea>
<label for="single-select-example">Fruit</label>
<select id="single-select-example">
<option value="">Select a fruit...</option>
<option value="banana">Banana</option>
<option value="ananas">Ananas</option>
<option value="avocado">Avocado</option>
</select>
<label for="multiple-select-example">Fruits</label>
<select id="multiple-select-example" multiple>
<option value="">Select a fruit...</option>
<option value="banana" selected>Banana</option>
<option value="ananas">Ananas</option>
<option value="avocado" selected>Avocado</option>
</select>
const input = page.getByLabelText('First name');
const textarea = page.getByLabelText('Description');
const selectSingle = page.getByLabelText('Fruit');
const selectMultiple = page.getByLabelText('Fruits');
await expect.element(input).toHaveDisplayValue('Luca');
await expect.element(input).toHaveDisplayValue(/Luc/);
await expect
.element(textarea)
.toHaveDisplayValue('An example description here.');
await expect.element(textarea).toHaveDisplayValue(/example/);
await expect.element(selectSingle).toHaveDisplayValue('Select a fruit...');
await expect.element(selectSingle).toHaveDisplayValue(/Select/);
await expect.element(selectMultiple).toHaveDisplayValue([/Avocado/, 'Banana']);
toBeChecked
function toBeChecked(): Promise<void>;
指定された要素がチェックされているかどうかをチェックします。これは、checkbox
または radio
型の input
、および checkbox
、radio
、または switch
のロールを持ち、有効な aria-checked
属性が "true"
または "false"
である要素を受け入れます。
<input type="checkbox" checked data-testid="input-checkbox-checked" />
<input type="checkbox" data-testid="input-checkbox-unchecked" />
<div role="checkbox" aria-checked="true" data-testid="aria-checkbox-checked" />
<div
role="checkbox"
aria-checked="false"
data-testid="aria-checkbox-unchecked"
/>
<input type="radio" checked value="foo" data-testid="input-radio-checked" />
<input type="radio" value="foo" data-testid="input-radio-unchecked" />
<div role="radio" aria-checked="true" data-testid="aria-radio-checked" />
<div role="radio" aria-checked="false" data-testid="aria-radio-unchecked" />
<div role="switch" aria-checked="true" data-testid="aria-switch-checked" />
<div role="switch" aria-checked="false" data-testid="aria-switch-unchecked" />
const inputCheckboxChecked = getByTestId('input-checkbox-checked');
const inputCheckboxUnchecked = getByTestId('input-checkbox-unchecked');
const ariaCheckboxChecked = getByTestId('aria-checkbox-checked');
const ariaCheckboxUnchecked = getByTestId('aria-checkbox-unchecked');
await expect.element(inputCheckboxChecked).toBeChecked();
await expect.element(inputCheckboxUnchecked).not.toBeChecked();
await expect.element(ariaCheckboxChecked).toBeChecked();
await expect.element(ariaCheckboxUnchecked).not.toBeChecked();
const inputRadioChecked = getByTestId('input-radio-checked');
const inputRadioUnchecked = getByTestId('input-radio-unchecked');
const ariaRadioChecked = getByTestId('aria-radio-checked');
const ariaRadioUnchecked = getByTestId('aria-radio-unchecked');
await expect.element(inputRadioChecked).toBeChecked();
await expect.element(inputRadioUnchecked).not.toBeChecked();
await expect.element(ariaRadioChecked).toBeChecked();
await expect.element(ariaRadioUnchecked).not.toBeChecked();
const ariaSwitchChecked = getByTestId('aria-switch-checked');
const ariaSwitchUnchecked = getByTestId('aria-switch-unchecked');
await expect.element(ariaSwitchChecked).toBeChecked();
await expect.element(ariaSwitchUnchecked).not.toBeChecked();
toBePartiallyChecked
function toBePartiallyChecked(): Promise<void>;
指定された要素が部分的にチェックされているかどうかをチェックします。これは、checkbox
型の input
、および aria-checked="mixed"
を持つ checkbox
ロールの要素、または indeterminate
が true
に設定された checkbox
型の input
を受け入れます。
<input type="checkbox" aria-checked="mixed" data-testid="aria-checkbox-mixed" />
<input type="checkbox" checked data-testid="input-checkbox-checked" />
<input type="checkbox" data-testid="input-checkbox-unchecked" />
<div role="checkbox" aria-checked="true" data-testid="aria-checkbox-checked" />
<div
role="checkbox"
aria-checked="false"
data-testid="aria-checkbox-unchecked"
/>
<input type="checkbox" data-testid="input-checkbox-indeterminate" />
const ariaCheckboxMixed = getByTestId('aria-checkbox-mixed');
const inputCheckboxChecked = getByTestId('input-checkbox-checked');
const inputCheckboxUnchecked = getByTestId('input-checkbox-unchecked');
const ariaCheckboxChecked = getByTestId('aria-checkbox-checked');
const ariaCheckboxUnchecked = getByTestId('aria-checkbox-unchecked');
const inputCheckboxIndeterminate = getByTestId('input-checkbox-indeterminate');
await expect.element(ariaCheckboxMixed).toBePartiallyChecked();
await expect.element(inputCheckboxChecked).not.toBePartiallyChecked();
await expect.element(inputCheckboxUnchecked).not.toBePartiallyChecked();
await expect.element(ariaCheckboxChecked).not.toBePartiallyChecked();
await expect.element(ariaCheckboxUnchecked).not.toBePartiallyChecked();
inputCheckboxIndeterminate.element().indeterminate = true;
await expect.element(inputCheckboxIndeterminate).toBePartiallyChecked();
toHaveRole
function toHaveRole(role: ARIARole): Promise<void>;
要素が期待されるロールを持っていることをアサートします。
これは、ロール自体以外のクエリを通じて要素にすでにアクセスしている場合に、アクセシビリティに関する追加の確認を行うのに役立ちます。
ロールは、明示的なロール(role
属性経由)または暗黙的な ARIA セマンティクス経由の暗黙的なロールのいずれかに一致します。
<button data-testid="button">Continue</button>
<div role="button" data-testid="button-explicit">Continue</button>
<button role="switch button" data-testid="button-explicit-multiple">Continue</button>
<a href="/about" data-testid="link">About</a>
<a data-testid="link-invalid">Invalid link<a/>
await expect.element(getByTestId('button')).toHaveRole('button');
await expect.element(getByTestId('button-explicit')).toHaveRole('button');
await expect
.element(getByTestId('button-explicit-multiple'))
.toHaveRole('button');
await expect
.element(getByTestId('button-explicit-multiple'))
.toHaveRole('switch');
await expect.element(getByTestId('link')).toHaveRole('link');
await expect.element(getByTestId('link-invalid')).not.toHaveRole('link');
await expect.element(getByTestId('link-invalid')).toHaveRole('generic');
WARNING
ロールは文字列の等価性によって文字通り一致し、ARIA ロール階層から継承されません。その結果、checkbox
のようなスーパークラスロールをクエリしても、switch
のようなサブクラスロールを持つ要素は含まれません。
また、testing-library
とは異なり、Vitest は Playwright の動作に従い、最初の有効なカスタムロールを除くすべてのカスタムロールを無視することにも注意してください。
<div data-testid="switch" role="switch alert"></div>;
await expect.element(getByTestId('switch')).toHaveRole('switch'); // ✅
await expect.element(getByTestId('switch')).toHaveRole('alert'); // ❌
toHaveSelection
function toHaveSelection(selection?: string): Promise<void>;
要素がテキスト選択を持っていることをアサートします。
これは、要素内でテキストまたはテキストの一部が選択されているかどうかをチェックするのに役立ちます。要素は、テキスト型の入力、テキストエリア、または段落、スパン、div などのテキストを含むその他の要素のいずれかです。
WARNING
期待される選択は文字列であり、選択範囲のインデックスをチェックすることはできません。
<div>
<input type="text" value="text selected text" data-testid="text" />
<textarea data-testid="textarea">text selected text</textarea>
<p data-testid="prev">prev</p>
<p data-testid="parent">
text <span data-testid="child">selected</span> text
</p>
<p data-testid="next">next</p>
</div>
getByTestId('text').element().setSelectionRange(5, 13);
await expect.element(getByTestId('text')).toHaveSelection('selected');
getByTestId('textarea').element().setSelectionRange(0, 5);
await expect.element('textarea').toHaveSelection('text ');
const selection = document.getSelection();
const range = document.createRange();
selection.removeAllRanges();
selection.empty();
selection.addRange(range);
// 子の選択は親にも適用されます
range.selectNodeContents(getByTestId('child').element());
await expect.element(getByTestId('child')).toHaveSelection('selected');
await expect.element(getByTestId('parent')).toHaveSelection('selected');
// prev 全体、子の前の親テキスト、および子の一部に適用される選択。
range.setStart(getByTestId('prev').element(), 0);
range.setEnd(getByTestId('child').element().childNodes[0], 3);
await expect.element(queryByTestId('prev')).toHaveSelection('prev');
await expect.element(queryByTestId('child')).toHaveSelection('sel');
await expect.element(queryByTestId('parent')).toHaveSelection('text sel');
await expect.element(queryByTestId('next')).not.toHaveSelection();
// 子の一部、子の後の親テキスト、および次の一部に適用される選択。
range.setStart(getByTestId('child').element().childNodes[0], 3);
range.setEnd(getByTestId('next').element().childNodes[0], 2);
await expect.element(queryByTestId('child')).toHaveSelection('ected');
await expect.element(queryByTestId('parent')).toHaveSelection('ected text');
await expect.element(queryByTestId('prev')).not.toHaveSelection();
await expect.element(queryByTestId('next')).toHaveSelection('ne');