Skip to content
Vitest 3
Main Navigation 가이드 & API구성브라우저 모드고급 API
3.2.0
2.1.9
1.6.1
0.34.6

한국어

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
Italiano
Polski
Türkçe
čeština
magyar

한국어

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
Italiano
Polski
Türkçe
čeština
magyar

외관

Sidebar Navigation

소개

브라우저 모드를 사용하는 이유

브라우저 모드

구성

브라우저 설정 참조

Playwright 구성

WebdriverIO 구성

API

Context API

상호작용 API

로케이터

Assertion API

명령어

가이드

다중 설정

Vitest 구성하기

테스트 API 참조

고급 API

이 페이지에서

Assertion API ​

Vitest는 @testing-library/jest-dom 라이브러리에서 파생된 광범위한 DOM 어설션을 기본으로 제공하며, 로케이터 및 내장된 재시도 기능을 추가로 지원합니다.

TypeScript 지원

TypeScript를 사용하거나 expect에서 올바른 타입 힌트를 얻으려면 @vitest/browser/context가 어딘가에 참조되어 있는지 확인해야 합니다. 만약 해당 모듈을 한 번도 임포트하지 않았다면, tsconfig.json에 포함된 아무 파일에나 reference 주석을 추가할 수 있습니다:

ts
/// <reference types="@vitest/browser/context" />

브라우저에서의 테스트는 비동기적 특성으로 인해 일관성 없이 실패할 수 있습니다. 이 때문에 조건이 지연되더라도(예: 타임아웃, 네트워크 요청 또는 애니메이션) 어설션이 성공하도록 보장하는 방법이 중요합니다. 이를 위해 Vitest는 expect.poll 및 expect.element API를 통해 재시도 가능한 어설션을 기본으로 제공합니다:

ts
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는 두 번째 옵션을 허용합니다:

ts
interface ExpectPollOptions {
  // 어설션을 재시도할 간격 (밀리초)
  // 기본값은 "expect.poll.interval" 설정 옵션입니다.
  interval?: number;
  // 어설션을 재시도할 시간 (밀리초)
  // 기본값은 "expect.poll.timeout" 설정 옵션입니다.
  timeout?: number;
  // 어설션 실패 시 출력되는 메시지
  message?: string;
}

TIP

expect.element는 expect.poll(() => element)의 약어이며 정확히 동일하게 작동합니다.

toHaveTextContent 및 다른 모든 어설션은 내장된 재시도 메커니즘 없이 일반 expect에서도 여전히 사용할 수 있습니다:

ts
// .textContent가 `'Error!'`가 아니면 즉시 실패합니다.
expect(banner).toHaveTextContent('Error!');

toBeDisabled ​

ts
function toBeDisabled(): Promise<void>;

사용자 관점에서 요소가 비활성화되었는지 확인하는 데 사용됩니다.

요소가 폼 컨트롤이고 이 요소에 disabled 속성이 지정되었거나, disabled 속성을 가진 폼 요소의 자손인 경우 일치합니다.

참고로 HTML button, input, select, textarea, option, optgroup과 같은 네이티브 컨트롤 요소만 "disabled" 속성을 설정하여 비활성화할 수 있습니다. 다른 요소의 "disabled" 속성은 커스텀 요소가 아닌 한 무시됩니다.

html
<button data-testid="button" type="submit" disabled>submit</button>
ts
await expect.element(getByTestId('button')).toBeDisabled(); // ✅
await expect.element(getByTestId('button')).not.toBeDisabled(); // ❌

toBeEnabled ​

ts
function toBeEnabled(): Promise<void>;

사용자 관점에서 요소가 비활성화되지 않았는지 확인하는 데 사용됩니다.

not.toBeDisabled()와 동일하게 동작합니다. 테스트에서 이중 부정을 피하려면 이 매처를 사용하세요.

html
<button data-testid="button" type="submit" disabled>submit</button>
ts
await expect.element(getByTestId('button')).toBeEnabled(); // ✅
await expect.element(getByTestId('button')).not.toBeEnabled(); // ❌

toBeEmptyDOMElement ​

ts
function toBeEmptyDOMElement(): Promise<void>;

이는 요소에 사용자에게 보이는 내용이 없는지 확인할 수 있도록 합니다. 주석은 무시하지만, 요소에 공백이 포함되어 있으면 실패합니다.

html
<span data-testid="not-empty"><span data-testid="empty"></span></span>
<span data-testid="with-whitespace"> </span>
<span data-testid="with-comment"><!-- comment --></span>
ts
await expect.element(getByTestId('empty')).toBeEmptyDOMElement();
await expect.element(getByTestId('not-empty')).not.toBeEmptyDOMElement();
await expect.element(getByTestId('with-whitespace')).not.toBeEmptyDOMElement();

toBeInTheDocument ​

ts
function toBeInTheDocument(): Promise<void>;

요소가 문서에 존재하는지 여부를 어설션합니다.

html
<svg data-testid="svg-element"></svg>
ts
await expect.element(getByTestId('svg-element')).toBeInTheDocument();
await expect.element(getByTestId('does-not-exist')).not.toBeInTheDocument();

WARNING

이 매처는 연결 해제된 요소를 찾지 않습니다. toBeInTheDocument로 찾으려면 요소가 문서에 추가되어야 합니다. 분리된 요소에서 검색하려면 toContainElement를 사용하십시오.

toBeInvalid ​

ts
function toBeInvalid(): Promise<void>;

이는 요소가 현재 유효하지 않은지 확인할 수 있도록 합니다.

요소는 aria-invalid 속성이 없거나 "true" 값인 경우, 또는 checkValidity()의 결과가 false인 경우 유효하지 않습니다.

html
<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>
ts
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 ​

ts
function toBeRequired(): Promise<void>;

이는 폼 요소가 현재 필수인지 확인할 수 있도록 합니다.

요소는 required 또는 aria-required="true" 속성을 가지고 있는 경우 필수입니다.

html
<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>
ts
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 ​

ts
function toBeValid(): Promise<void>;

이는 요소의 값이 현재 유효한지 확인할 수 있도록 합니다.

요소는 aria-invalid 속성이 없거나 해당 속성 값이 "false"인 경우 유효합니다. 폼 요소인 경우 checkValidity()의 결과도 true여야 합니다.

html
<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>
ts
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 ​

ts
function toBeVisible(): Promise<void>;

이는 요소가 현재 사용자에게 보이는지 확인할 수 있도록 합니다.

요소는 비어 있지 않은 경계 상자를 가지며 visibility:hidden 계산된 스타일을 가지고 있지 않을 때 보이는 것으로 간주됩니다.

이 정의에 따르면:

  • 크기가 0인 요소는 보이지 않는 것으로 간주됩니다.
  • display:none인 요소는 보이지 않는 것으로 간주됩니다.
  • opacity:0인 요소는 보이는 것으로 간주됩니다.

목록에서 적어도 하나의 요소가 보이는지 확인하려면 locator.first()를 사용하십시오.

ts
// 특정 요소가 보입니다.
await expect.element(page.getByText('Welcome')).toBeVisible();

// 목록의 적어도 하나의 항목이 보입니다.
await expect.element(page.getByTestId('todo-item').first()).toBeVisible();

// 두 요소 중 적어도 하나가 보이며, 둘 다 보일 수도 있습니다.
await expect
  .element(
    page
      .getByRole('button', { name: 'Sign in' })
      .or(page.getByRole('button', { name: 'Sign up' }))
      .first()
  )
  .toBeVisible();

toContainElement ​

ts
function toContainElement(
  element: HTMLElement | SVGElement | null
): Promise<void>;

이는 요소가 다른 요소를 자손으로 포함하는지 여부를 어설션할 수 있도록 합니다.

html
<span data-testid="ancestor"><span data-testid="descendant"></span></span>
ts
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 ​

ts
function toContainHTML(htmlText: string): Promise<void>;

HTML 요소를 나타내는 문자열이 다른 요소에 포함되어 있는지 어설션할 수 있습니다. 문자열은 유효한 HTML을 포함해야 하며, 불완전한 HTML은 포함하지 않아야 합니다.

html
<span data-testid="parent"><span data-testid="child"></span></span>
ts
// 유효한 사용법
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 ​

ts
function toHaveAccessibleDescription(
  description?: string | RegExp
): Promise<void>;

이는 요소가 예상되는 접근 가능한 설명을 가지고 있는지 어설션할 수 있도록 합니다.

예상되는 접근 가능한 설명의 정확한 문자열을 전달하거나, 정규 표현식을 사용하거나 expect.stringContaining 또는 expect.stringMatching을 통해 부분 일치를 수행할 수 있습니다.

html
<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"
/>
ts
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 ​

ts
function toHaveAccessibleErrorMessage(message?: string | RegExp): Promise<void>;

이는 요소가 예상되는 접근 가능한 오류 메시지를 가지고 있는지 어설션할 수 있도록 합니다.

예상되는 접근 가능한 오류 메시지의 정확한 문자열을 전달할 수 있습니다. 또는 정규 표현식을 사용하거나 expect.stringContaining 또는 expect.stringMatching을 통해 부분 일치를 수행할 수 있습니다.

html
<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"
/>
ts
// 유효한 오류 메시지를 가진 입력 필드
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 ​

ts
function toHaveAccessibleName(name?: string | RegExp): Promise<void>;

이는 요소가 예상되는 접근 가능한 이름을 가지고 있는지 어설션할 수 있도록 합니다. 예를 들어, 폼 요소와 버튼이 올바르게 레이블링되었는지 어설션하는 데 유용합니다.

예상되는 접근 가능한 이름의 정확한 문자열을 전달하거나, 정규 표현식을 사용하거나 expect.stringContaining 또는 expect.stringMatching을 통해 부분 일치를 수행할 수 있습니다.

html
<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" />
javascript
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 ​

ts
function toHaveAttribute(attribute: string, value?: unknown): Promise<void>;

이는 주어진 요소가 속성을 가지고 있는지 여부를 확인할 수 있도록 합니다. 또한 선택적으로 속성이 특정 예상 값을 가지고 있는지 또는 expect.stringContaining 또는 expect.stringMatching을 사용하여 부분 일치를 수행하는지 확인할 수 있습니다.

html
<button data-testid="ok-button" type="submit" disabled>ok</button>
ts
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 ​

ts
function toHaveClass(
  ...classNames: string[],
  options?: { exact: boolean }
): Promise<void>;
function toHaveClass(...classNames: (string | RegExp)[]): Promise<void>;

이는 주어진 요소가 class 속성 내에 특정 클래스를 가지고 있는지 확인할 수 있도록 합니다. 적어도 하나의 클래스를 제공해야 합니다. 단, 요소에 클래스가 전혀 없는지 어설션하는 경우는 예외입니다.

클래스 이름 목록에는 문자열과 정규 표현식이 포함될 수 있습니다. 정규 표현식은 대상 요소의 각 개별 클래스와 일치하며, 전체 class 속성 값과 일치하지 않습니다.

WARNING

참고로 정규 표현식만 제공된 경우에는 exact: true 옵션을 사용할 수 없습니다.

html
<button data-testid="delete-button" class="btn extra btn-danger">
  Delete item
</button>
<button data-testid="no-classes">No Classes</button>
ts
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 ​

ts
function toHaveFocus(): Promise<void>;

이는 요소가 포커스를 가지고 있는지 여부를 어설션할 수 있도록 합니다.

html
<div><input type="text" data-testid="element-to-focus" /></div>
ts
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 ​

ts
function toHaveFormValues(
  expectedValues: Record<string, unknown>
): Promise<void>;

이는 폼 또는 필드셋이 주어진 이름마다 폼 컨트롤을 포함하고 지정된 값을 가지고 있는지 확인할 수 있도록 합니다.

TIP

중요한 점은 이 매처는 폼 또는 필드셋 요소에서만 호출할 수 있다는 것입니다.

이를 통해 form 및 fieldset의 .elements 속성을 활용하여 그 안에 있는 모든 폼 컨트롤을 안정적으로 가져올 수 있습니다.

또한, 사용자가 둘 이상의 form을 포함하는 컨테이너를 제공하여 관련 없는 폼 컨트롤을 혼합하거나 심지어 서로 충돌할 수 있는 가능성을 방지합니다.

이 매처는 폼 컨트롤 유형에 따라 폼 컨트롤 값이 얻어지는 특정 방식의 차이점을 추상화합니다. 예를 들어, <input> 요소는 value 속성을 가지지만, <select> 요소는 그렇지 않습니다. 다음은 다루는 모든 경우의 목록입니다:

  • <input type="number"> 요소는 값을 문자열 대신 숫자로 반환합니다.
  • <input type="checkbox"> 요소:
    • 주어진 name 속성을 가진 단일 요소인 경우, 체크박스가 체크되면 true, 체크되지 않으면 false를 반환하는 불리언으로 처리됩니다.
    • 동일한 name 속성을 가진 체크박스가 두 개 이상인 경우, 모두 단일 폼 컨트롤로 집합적으로 처리되어 컬렉션에서 선택된 체크박스의 모든 값을 포함하는 배열로 값을 반환합니다.
  • <input type="radio"> 요소는 모두 name 속성으로 그룹화되며, 이러한 그룹은 단일 폼 컨트롤로 처리됩니다. 이 폼 컨트롤은 그룹 내에서 선택된 라디오 버튼의 value 속성에 해당하는 문자열로 값을 반환합니다.
  • <input type="text"> 요소는 값을 문자열로 반환합니다. 이는 위에 명시적으로 다루지 않은 다른 type 속성(예: search, email, date, password, hidden 등)을 가진 <input> 요소에도 적용됩니다.
  • multiple 속성이 없는 <select> 요소는 선택된 option의 value 속성에 해당하는 문자열로 값을 반환하거나, 선택된 옵션이 없으면 undefined를 반환합니다.
  • <select multiple> 요소는 선택된 옵션의 모든 값을 포함하는 배열로 값을 반환합니다.
  • <textarea> 요소는 값을 문자열로 반환합니다. 값은 노드 내용에 해당합니다.

위 규칙은 예를 들어, 단일 선택 컨트롤에서 라디오 버튼 그룹으로 전환하거나, 다중 선택 컨트롤에서 체크박스 그룹으로 전환하는 것을 쉽게 만듭니다. 이 매처가 비교하는 데 사용하는 결과 폼 값 세트는 동일합니다.

html
<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>
ts
await expect.element(getByTestId('login-form')).toHaveFormValues({
  username: 'jane.doe',
  rememberMe: true,
});

toHaveStyle ​

ts
function toHaveStyle(css: string | Partial<CSSStyleDeclaration>): Promise<void>;

이는 특정 요소에 특정 CSS 속성이 특정 값으로 적용되었는지 확인할 수 있도록 합니다. 요소가 예상되는 모든 속성을 가지고 있을 때만 일치하며, 일부만 가지고 있을 때는 일치하지 않습니다.

html
<button
  data-testid="delete-button"
  style="display: none; background-color: red"
>
  Delete item
</button>
ts
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 ​

ts
function toHaveTextContent(
  text: string | RegExp,
  options?: { normalizeWhitespace: boolean }
): Promise<void>;

이는 주어진 노드가 텍스트 내용을 가지고 있는지 여부를 확인할 수 있도록 합니다. 요소뿐만 아니라 텍스트 노드 및 프래그먼트도 지원합니다.

string 인수가 전달되는 경우 노드 내용에 대해 부분적인 대소문자 구분 일치를 수행합니다.

대소문자를 구분하지 않는 일치를 수행하려면 /i 수정자를 가진 RegExp를 사용할 수 있습니다.

전체 내용을 일치시키려면 RegExp를 사용할 수 있습니다.

html
<span data-testid="text-content">Text Content</span>
ts
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 ​

ts
function toHaveValue(value: string | string[] | number | null): Promise<void>;

이는 주어진 폼 요소가 지정된 값을 가지고 있는지 확인할 수 있도록 합니다. <input>, <select>, <textarea> 요소를 허용하며, toBeChecked 또는 toHaveFormValues를 통해서만 의미 있게 일치시킬 수 있는 <input type="checkbox"> 및 <input type="radio">는 예외입니다.

또한, meter, progressbar, slider, spinbutton 역할을 가진 요소를 허용하며, 해당 aria-valuenow 속성(숫자)을 확인합니다.

다른 모든 폼 요소의 경우, 값은 toHaveFormValues와 동일한 알고리즘을 사용하여 일치합니다.

html
<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>
ts
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 ​

typescript
function toHaveDisplayValue(
  value: string | RegExp | (string | RegExp)[]
): Promise<void>;

이는 주어진 폼 요소가 지정된 표시 값(최종 사용자가 보게 될 값)을 가지고 있는지 확인할 수 있도록 합니다. <input>, <select>, <textarea> 요소를 허용하며, toBeChecked 또는 toHaveFormValues를 통해서만 의미 있게 일치시킬 수 있는 <input type="checkbox"> 및 <input type="radio">는 예외입니다.

html
<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>
ts
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 ​

ts
function toBeChecked(): Promise<void>;

이는 주어진 요소가 체크되었는지 확인할 수 있도록 합니다. checkbox 또는 radio 타입의 input과 유효한 aria-checked 속성 값이 "true" 또는 "false"인 checkbox, radio, switch 역할을 가진 요소를 허용합니다.

html
<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" />
ts
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 ​

typescript
function toBePartiallyChecked(): Promise<void>;

이는 주어진 요소가 부분적으로 체크되었는지 확인할 수 있도록 합니다. checkbox 타입의 input과 aria-checked="mixed"를 가진 checkbox 역할을 가진 요소, 또는 indeterminate가 true로 설정된 checkbox 타입의 input을 허용합니다.

html
<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" />
ts
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 ​

ts
function toHaveRole(role: ARIARole): Promise<void>;

이는 요소가 예상되는 역할을 가지고 있는지 어설션할 수 있도록 합니다.

이는 역할 자체 외의 다른 쿼리를 통해 이미 요소에 접근할 수 있는 경우에 유용하며, 접근성에 대한 추가적인 어설션을 만들고자 할 때 활용됩니다.

역할은 role 속성을 통해 지정된 명시적인 역할 또는 암시적 ARIA 의미론을 통한 암시적인 역할과 일치할 수 있습니다.

html
<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/>
ts
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의 동작을 따라 첫 번째 유효한 사용자 정의 역할을 제외한 모든 사용자 정의 역할을 무시합니다:

jsx
<div data-testid="switch" role="switch alert"></div>;

await expect.element(getByTestId('switch')).toHaveRole('switch'); // ✅
await expect.element(getByTestId('switch')).toHaveRole('alert'); // ❌

toHaveSelection ​

ts
function toHaveSelection(selection?: string): Promise<void>;

이는 요소가 텍스트 선택을 가지고 있는지 어설션할 수 있도록 합니다.

이는 요소 내에서 텍스트 또는 텍스트의 일부가 선택되었는지 확인하는 데 유용합니다. 요소는 텍스트 타입의 input 요소, 텍스트 영역, 또는 단락, 스팬, div 등 텍스트를 포함하는 다른 요소일 수 있습니다.

WARNING

예상되는 선택은 문자열이며, 선택 범위 인덱스는 확인할 수 없습니다.

html
<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>
ts
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();

// 자식 일부, 부모 텍스트(자식 이후), next 요소 일부에 적용되는 선택.
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');
Pager
이전로케이터
다음명령어

MIT 라이선스 하에 배포되었습니다.

Copyright (c) 2021-Present Vitest Team

https://vitest.dev/guide/browser/assertion-api

MIT 라이선스 하에 배포되었습니다.

Copyright (c) 2021-Present Vitest Team