API asercji
Vitest zapewnia szeroki zakres asercji DOM dostępnych od razu po instalacji, zaczerpniętych z biblioteki @testing-library/jest-dom, z dodatkowym wsparciem dla lokatorów oraz wbudowaną ponawialnością.
Wsparcie dla TypeScript
Jeśli używasz TypeScript lub chcesz mieć poprawne podpowiedzi typów w expect, upewnij się, że masz odwołanie do @vitest/browser/context w swoim projekcie. Jeśli nigdy stamtąd nie importowałeś, możesz dodać komentarz reference w dowolnym pliku, który jest objęty twoim tsconfig.json:
/// <reference types="@vitest/browser/context" />Testy w przeglądarce mogą czasami nie powodzić się niespójnie ze względu na ich asynchroniczną naturę. Z tego powodu ważne jest, aby mieć sposób na zagwarantowanie, że asercje powiodą się, nawet jeśli warunek jest opóźniony (na przykład z powodu limitu czasu, żądania sieciowego lub animacji). W tym celu Vitest oferuje asercje z możliwością ponawiania prób, dostępne od razu po zainstalowaniu, za pośrednictwem API expect.poll i expect.element:
import { expect, test } from 'vitest';
import { page } from '@vitest/browser/context';
test('error banner is rendered', async () => {
triggerError();
// To tworzy lokator, który spróbuje znaleźć element gdy wywołana zostanie którakolwiek z jego metod.
// To wywołanie samo w sobie nie sprawdza istnienia elementu.
const banner = page.getByRole('alert', {
name: /error/i,
});
// Vitest zapewnia `expect.element` z wbudowaną ponawialnością.
// Będzie on wielokrotnie sprawdzał, czy element istnieje w DOM i czy zawartość `element.textContent` jest równa "Error!" aż wszystkie warunki zostaną spełnione
await expect.element(banner).toHaveTextContent('Error!');
});Zalecamy, aby zawsze używać expect.element podczas pracy z lokatorami page.getBy*, aby zredukować niestabilność testów. Należy zauważyć, że expect.element akceptuje drugi argument:
interface ExpectPollOptions {
// Interwał ponawiania asercji (w milisekundach)
// Domyślnie: opcja konfiguracyjna "expect.poll.interval"
interval?: number;
// Czas ponawiania asercji (w milisekundach)
// Domyślnie: opcja konfiguracyjna "expect.poll.timeout"
timeout?: number;
// Wiadomość, która zostanie wyświetlona, gdy asercja się nie powiedzie
message?: string;
}TIP
expect.element to skrót dla expect.poll(() => element) i działa dokładnie w ten sam sposób.
toHaveTextContent i wszystkie inne asercje są nadal dostępne w zwykłym expect bez wbudowanego mechanizmu ponawiania prób:
// natychmiast zawiedzie, jeśli .textContent nie jest równe `'Error!'`
expect(banner).toHaveTextContent('Error!');toBeDisabled
function toBeDisabled(): Promise<void>;Pozwala sprawdzić, czy element jest wyłączony z perspektywy użytkownika.
Pasuje, jeśli element jest kontrolką formularza, a atrybut disabled jest ustawiony dla tego elementu lub element jest potomkiem elementu formularza z atrybutem disabled.
Zauważ, że tylko natywne elementy sterujące, takie jak HTML button, input, select, textarea, option, optgroup, mogą być wyłączone poprzez ustawienie atrybutu "disabled". Atrybut "disabled" na innych elementach jest ignorowany, chyba że są to elementy niestandardowe.
<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>;Pozwala sprawdzić, czy element nie jest wyłączony z perspektywy użytkownika.
Działa jak not.toBeDisabled(). Użyj tego dopasowania, aby uniknąć podwójnego zaprzeczenia w testach.
<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>;Pozwala sprawdzić, czy element nie ma widocznej zawartości dla użytkownika. Ignoruje komentarze, ale zawiedzie, jeśli element zawiera białe znaki.
<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>;Sprawdź, czy element jest obecny w dokumencie.
<svg data-testid="svg-element"></svg>await expect.element(getByTestId('svg-element')).toBeInTheDocument();
await expect.element(getByTestId('does-not-exist')).not.toBeInTheDocument();WARNING
Ta funkcja dopasowująca nie znajduje odłączonych elementów. Element musi być dodany do dokumentu, aby został znaleziony przez toBeInTheDocument. Jeśli chcesz wyszukać w odłączonym elemencie, użyj: toContainElement.
toBeInvalid
function toBeInvalid(): Promise<void>;Pozwala sprawdzić, czy element jest obecnie nieprawidłowy.
Element jest nieprawidłowy, jeśli ma atrybut aria-invalid bez wartości lub z wartością "true", lub jeśli wynik checkValidity() jest 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>;Pozwala sprawdzić, czy element formularza jest obecnie wymagany.
Element jest wymagany, jeśli posiada atrybut required lub 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>;Pozwala sprawdzić, czy wartość elementu jest obecnie prawidłowa.
Element jest prawidłowy, jeśli nie ma atrybutu aria-invalid lub ma wartość atrybutu "false". Wynik checkValidity() musi być również true, jeśli jest to element formularza.
<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>;Pozwala sprawdzić, czy element jest obecnie widoczny dla użytkownika.
Element uznaje się za widoczny, gdy ma niepuste pole ograniczające i nie ma obliczonego stylu visibility:hidden.
Zauważ, że zgodnie z tą definicją:
- Elementy o zerowym rozmiarze nie są uważane za widoczne.
- Elementy z
display:nonenie są uważane za widoczne. - Elementy z
opacity:0są uważane za widoczne.
Aby sprawdzić, czy co najmniej jeden element z listy jest widoczny, użyj locator.first().
// Określony element jest widoczny.
await expect.element(page.getByText('Welcome')).toBeVisible();
// Co najmniej jeden element na liście jest widoczny.
await expect.element(page.getByTestId('todo-item').first()).toBeVisible();
// Co najmniej jeden z dwóch elementów jest widoczny, być może oba.
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>;Pozwala sprawdzić, czy element zawiera inny element jako potomka.
<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>;Sprawdź, czy ciąg znaków reprezentujący element HTML jest zawarty w innym elemencie. Ciąg powinien być prawidłowym, kompletnym kodem HTML.
<span data-testid="parent"><span data-testid="child"></span></span>// To są prawidłowe użycia
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 />');
// To nie zadziała
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
Prawdopodobnie nie musisz używać tej funkcji dopasowującej. Zachęcamy do testowania z perspektywy tego, jak użytkownik postrzega aplikację w przeglądarce. Dlatego testowanie w oparciu o konkretną strukturę DOM nie jest zalecane.
Może być przydatne w sytuacjach, gdy testowany kod renderuje HTML uzyskany ze źródła zewnętrznego, a chcesz sprawdzić, czy ten kod HTML został wykorzystany zgodnie z zamierzeniem.
Nie należy go używać do sprawdzania struktury DOM, którą kontrolujesz. Zamiast tego użyj toContainElement.
toHaveAccessibleDescription
function toHaveAccessibleDescription(
description?: string | RegExp
): Promise<void>;Pozwala sprawdzić, czy element ma oczekiwany dostępny opis.
Możesz przekazać dokładny ciąg znaków oczekiwanego dostępnego opisu, dokonać częściowego dopasowania, przekazując wyrażenie regularne, lub używając expect.stringContaining lub 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>;Pozwala sprawdzić, czy element ma oczekiwany dostępny komunikat o błędzie.
Możesz przekazać dokładny ciąg znaków oczekiwanego dostępnego komunikatu o błędzie. Alternatywnie, możesz dopasować częściowo, przekazując wyrażenie regularne lub używając expect.stringContaining lub 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"
/>// Pola wejściowe z prawidłowymi komunikatami o błędach
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!');
// Pola wejściowe bez prawidłowych komunikatów o błędach
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>;Pozwala sprawdzić, czy element ma oczekiwaną dostępną nazwę. Jest to przydatne, na przykład, do sprawdzenia, czy elementy formularza i przyciski są prawidłowo etykietowane.
Możesz przekazać dokładny ciąg znaków oczekiwanej dostępnej nazwy, lub możesz dokonać częściowego dopasowania, przekazując wyrażenie regularne, lub używając expect.stringContaining lub 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>;Pozwala sprawdzić, czy dany element ma atrybut, czy nie. Możesz również opcjonalnie sprawdzić, czy atrybut ma określoną oczekiwaną wartość lub czy częściowo pasuje za pomocą expect.stringContaining lub 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>;Pozwala sprawdzić, czy dany element ma określone klasy w swoim atrybucie class. Musisz podać co najmniej jedną klasę, chyba że chcesz sprawdzić, czy element nie ma żadnych klas.
Lista nazw klas może zawierać ciągi znaków i wyrażenia regularne. Wyrażenia regularne są dopasowywane do każdej pojedynczej klasy w elemencie docelowym i nie dopasowują się do całej wartości atrybutu class.
WARNING
Zauważ, że nie możesz użyć opcji exact: true, gdy podane są tylko wyrażenia regularne.
<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/);
// ⚠️ wyrażenie regularne pasuje do pojedynczych klas, a nie do całej listy klas
await expect.element(deleteButton).not.toHaveClass(/btn extra/);
// element ma DOKŁADNIE zestaw klas (w dowolnej kolejności)
await expect.element(deleteButton).toHaveClass('btn-danger extra btn', {
exact: true,
});
// jeśli ma więcej niż oczekiwano, to zawiedzie
await expect.element(deleteButton).not.toHaveClass('btn-danger extra', {
exact: true,
});
await expect.element(noClasses).not.toHaveClass();toHaveFocus
function toHaveFocus(): Promise<void>;Pozwala sprawdzić, czy element ma fokus, czy nie.
<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>;Pozwala sprawdzić, czy formularz lub fieldset zawiera kontrolki formularza dla każdej podanej nazwy i ma określoną wartość.
TIP
Ważne jest, aby podkreślić, że ta funkcja dopasowująca może być wywołana tylko na elemencie formularza lub fieldset.
Pozwala to wykorzystać właściwość .elements w form i fieldset do niezawodnego pobierania wszystkich kontrolek formularza w ich obrębie.
Zapobiega to również sytuacji, w której użytkownicy dostarczają kontener zawierający więcej niż jeden form, co mogłoby prowadzić do pomieszania niepowiązanych ze sobą kontrolek formularza, a nawet do ich kolizji.
Ta funkcja dopasowująca abstrahuje od specyfiki sposobu uzyskiwania wartości kontrolki formularza, w zależności od jej typu. Na przykład, elementy <input> mają atrybut value, ale elementy <select> nie. Oto lista wszystkich objętych przypadków:
- Elementy
<input type="number">zwracają wartość jako liczbę, a nie ciąg znaków. - Elementy
<input type="checkbox">:- jeśli istnieje tylko jeden z danym atrybutem
name, jest traktowany jako boolean, zwracającytrue, jeśli pole wyboru jest zaznaczone,false, jeśli odznaczone. - jeśli istnieje więcej niż jedno pole wyboru z tym samym atrybutem
name, są one traktowane zbiorowo jako pojedyncza kontrolka formularza, która zwraca wartość jako tablicę zawierającą wszystkie wartości zaznaczonych pól wyboru.
- jeśli istnieje tylko jeden z danym atrybutem
- Elementy
<input type="radio">są grupowane według atrybutuname, a taka grupa jest traktowana jako pojedyncza kontrolka formularza, która zwraca wartość jako ciąg znaków odpowiadający atrybutowivaluezaznaczonego przycisku radiowego w grupie. - Elementy
<input type="text">zwracają wartość jako ciąg znaków. Dotyczy to również elementów<input>posiadających dowolny inny atrybuttype, który nie jest wyraźnie objęty powyższymi regułami (np.search,email,date,password,hiddenitp.) - Elementy
<select>bez atrybutumultiplezwracają wartość jako ciąg znaków odpowiadający atrybutowivaluewybranejoption, lubundefined, jeśli żadna opcja nie jest wybrana. - Elementy
<select multiple>zwracają wartość jako tablicę zawierającą wszystkie wartości zaznaczonych opcji. - Elementy
<textarea>zwracają swoją wartość jako ciąg znaków. Wartość odpowiada ich zawartości węzła.
Powyższe zasady ułatwiają, na przykład, przełączanie się z używania pojedynczego elementu select na używanie grupy przycisków radiowych. Lub przełączanie się z elementu select multiple na używanie grupy pól wyboru. Wynikowy zestaw wartości formularza używany przez ten matcher do porównania byłby taki sam.
<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>;Pozwala sprawdzić, czy dany element posiada zastosowane określone właściwości CSS z określonymi wartościami. Dopasowuje tylko wtedy, gdy element posiada wszystkie oczekiwane właściwości, a nie tylko niektóre z nich.
<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',
});Działa to również w przypadku reguł CSS, które są stosowane do elementu za pośrednictwem nazwy klasy, a które są zdefiniowane w aktualnie aktywnym arkuszu stylów w dokumencie. Obowiązują zwykłe zasady pierwszeństwa CSS.
toHaveTextContent
function toHaveTextContent(
text: string | RegExp,
options?: { normalizeWhitespace: boolean }
): Promise<void>;Pozwala sprawdzić, czy dany węzeł ma zawartość tekstową. Obsługuje elementy, ale także węzły tekstowe i fragmenty.
Gdy przekazany zostanie argument string, zostanie on częściowo dopasowany z uwzględnieniem wielkości liter do zawartości węzła.
Aby dopasować bez uwzględniania wielkości liter, możesz użyć RegExp z modyfikatorem /i.
Jeśli chcesz dopasować całą zawartość, możesz użyć RegExp.
<span data-testid="text-content">Text Content</span>const element = getByTestId('text-content');
await expect.element(element).toHaveTextContent('Content');
// aby dopasować całą zawartość
await expect.element(element).toHaveTextContent(/^Text Content$/);
// aby użyć dopasowania bez uwzględniania wielkości liter
await expect.element(element).toHaveTextContent(/content$/i);
await expect.element(element).not.toHaveTextContent('content');toHaveValue
function toHaveValue(value: string | string[] | number | null): Promise<void>;Pozwala sprawdzić, czy dany element formularza ma określoną wartość. Akceptuje elementy <input>, <select> i <textarea>, z wyjątkiem <input type="checkbox> i <input type="radio>, które można skutecznie dopasować tylko za pomocą toBeChecked lub toHaveFormValues.
Akceptuje również elementy z rolami meter, progressbar, slider lub spinbutton i sprawdza ich atrybut aria-valuenow (traktowany jako liczba).
Dla wszystkich innych elementów formularza wartość jest dopasowywana przy użyciu tego samego algorytmu, co w 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>;Pozwala sprawdzić, czy dany element formularza ma określoną wyświetlaną wartość (widoczną dla użytkownika). Akceptuje elementy <input>, <select> i <textarea>, z wyjątkiem <input type="checkbox> i <input type="radio>, które mogą być sensownie dopasowane tylko za pomocą toBeChecked lub 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>;Pozwala sprawdzić, czy dany element jest zaznaczony. Akceptuje input typu checkbox lub radio oraz elementy z rolą checkbox, radio lub switch posiadające prawidłowy atrybut aria-checked o wartości "true" lub "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>;Pozwala sprawdzić, czy dany element jest częściowo zaznaczony. Akceptuje input typu checkbox i elementy z rolą checkbox z aria-checked="mixed", lub input typu checkbox z ustawionym na true atrybutem indeterminate.
<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>;Pozwala sprawdzić, czy element ma oczekiwaną rolę.
Jest to przydatne w przypadkach, gdy masz już dostęp do elementu za pomocą innego zapytania niż sama rola i chcesz wykonać dodatkowe asercje dotyczące jego dostępności.
Rola może odpowiadać zarówno roli jawnej (poprzez atrybut role), jak i roli niejawnej, zgodnie z niejawną semantyką 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
Role są dopasowywane dosłownie, na podstawie równości ciągów znaków, bez dziedziczenia z hierarchii ról ARIA. W rezultacie zapytanie o rolę nadrzędną, taką jak checkbox, nie obejmie elementów z rolą podrzędną, taką jak switch.
Zauważ również, że w przeciwieństwie do testing-library, Vitest ignoruje wszystkie niestandardowe role z wyjątkiem pierwszej prawidłowej, co jest zgodne z zachowaniem 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>;Pozwala sprawdzić, czy element ma selekcję tekstu.
Jest to przydatne do sprawdzenia, czy tekst lub jego część jest zaznaczona w elemencie. Elementem może być input typu tekstowego, textarea lub dowolny inny element zawierający tekst, taki jak p, span, div itp.
WARNING
Oczekiwane zaznaczenie to ciąg znaków; nie pozwala na sprawdzenie indeksów zakresu selekcji.
<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);
// zaznaczenie dziecka wpływa również na rodzica
range.selectNodeContents(getByTestId('child').element());
await expect.element(getByTestId('child')).toHaveSelection('selected');
await expect.element(getByTestId('parent')).toHaveSelection('selected');
// zaznaczenie obejmujące cały poprzedni element, tekst rodzica przed dzieckiem i część dziecka.
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();
// zaznaczenie obejmujące część dziecka, tekst rodzica po dziecku i część następnego elementu.
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');