Skip to content
Vitest 2
Main Navigation 指南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

Why Browser Mode?

Getting Started

Context API

Interactivity API

Locators

Assertion API

Commands API

本頁導覽

定位器 2.1.0+ ​

定位器代表一個或多個元素。每個定位器都由一個稱為選擇器的字串定義。Vitest 透過提供便捷的方法在幕後產生這些選擇器來抽象化此選擇器。

定位器 API 使用 Playwright 的定位器 的一個分支,稱為 Ivya。然而,Vitest 為每個 提供者 提供此 API。

getByRole ​

ts
function getByRole(
  role: ARIARole | string,
  options?: LocatorByRoleOptions
): Locator;

建立一種透過元素的 ARIA 角色、ARIA 屬性 和 可存取名稱 來定位元素的方法。

TIP

如果您只使用 getByText('The name') 查詢單一元素,通常最好使用 getByRole(expectedRole, { name: 'The name' })。可存取名稱查詢不會取代其他查詢,例如 *ByAltText 或 *ByTitle。雖然可存取名稱可以等於這些屬性,但它不會取代這些屬性的功能。

考慮以下 DOM 結構。

html
<h3>Sign up</h3>
<label>
  Login
  <input type="text" />
</label>
<label>
  Password
  <input type="password" />
</label>
<br />
<button>Submit</button>

您可以透過其隱含角色來定位每個元素:

ts
await expect
  .element(page.getByRole('heading', { name: 'Sign up' }))
  .toBeVisible();

await page.getByRole('textbox', { name: 'Login' }).fill('admin');
await page.getByRole('textbox', { name: 'Password' }).fill('admin');

await page.getByRole('button', { name: /submit/i }).click();

WARNING

角色是透過字串相等來匹配的,不繼承 ARIA 角色階層。因此,查詢超類別角色(例如 checkbox)不會包含具有子類別角色(例如 switch)的元素。

預設情況下,HTML 中的許多語義元素都有一個角色;例如,<input type="radio"> 具有「radio」角色。HTML 中的非語義元素沒有角色;沒有添加語義的 <div> 和 <span> 返回 null。role 屬性可以提供語義。

ARIA 指南強烈不鼓勵透過 role 或 aria-* 屬性為已經具有隱含角色的內建元素提供角色。

選項 ​
  • exact: boolean

    name 是否精確匹配:區分大小寫且完整字串。預設為停用。如果 name 是正規表達式,則忽略此選項。請注意,精確匹配仍會修剪空白字元。

    tsx
    <button>Hello World</button>;
    
    page.getByRole('button', { name: 'hello world' }); // ✅
    page.getByRole('button', { name: 'hello world', exact: true }); // ❌
    page.getByRole('button', { name: 'Hello World', exact: true }); // ✅
  • checked: boolean

    是否應包含已勾選的元素(由 aria-checked 或 <input type="checkbox"/> 設定)。預設情況下,不應用篩選器。

    有關更多資訊,請參閱 aria-checked

    tsx
    <>
      <button role="checkbox" aria-checked="true" />
      <input type="checkbox" checked />
    </>;
    
    page.getByRole('checkbox', { checked: true }); // ✅
    page.getByRole('checkbox', { checked: false }); // ❌
  • disabled: boolean

    是否應包含已停用的元素。預設情況下,不應用篩選器。請注意,與其他屬性不同,disable 狀態是繼承的。

    有關更多資訊,請參閱 aria-disabled

    tsx
    <input type="text" disabled />;
    
    page.getByRole('textbox', { disabled: true }); // ✅
    page.getByRole('textbox', { disabled: false }); // ❌
  • expanded: boolean

    是否應包含已展開的元素。預設情況下,不應用篩選器。

    有關更多資訊,請參閱 aria-expanded

    tsx
    <a aria-expanded="true" href="example.com">
      Link
    </a>;
    
    page.getByRole('link', { expanded: true }); // ✅
    page.getByRole('link', { expanded: false }); // ❌
  • includeHidden: boolean

    是否應查詢 通常從可存取性樹中排除 的元素。預設情況下,只有非隱藏元素會被角色選擇器匹配。

    請注意,角色 none 和 presentation 始終包含在內。

    tsx
    <button style="display: none" />;
    
    page.getByRole('button'); // ❌
    page.getByRole('button', { includeHidden: false }); // ❌
    page.getByRole('button', { includeHidden: true }); // ✅
  • level: number

    一個數字屬性,通常存在於 heading、listitem、row、treeitem 角色中,對於 <h1>-<h6> 元素具有預設值。預設情況下,不應用篩選器。

    有關更多資訊,請參閱 aria-level

    tsx
    <>
      <h1>Heading Level One</h1>
      <div role="heading" aria-level="1">
        Second Heading Level One
      </div>
    </>;
    
    page.getByRole('heading', { level: 1 }); // ✅
    page.getByRole('heading', { level: 2 }); // ❌
  • name: string | RegExp

    可存取名稱。預設情況下,匹配不區分大小寫並搜尋子字串。使用 exact 選項來控制此行為。

    tsx
    <button>Click Me!</button>;
    
    page.getByRole('button', { name: 'Click Me!' }); // ✅
    page.getByRole('button', { name: 'click me!' }); // ✅
    page.getByRole('button', { name: 'Click Me?' }); // ❌
  • pressed: boolean

    是否應包含已按下的元素。預設情況下,不應用篩選器。

    有關更多資訊,請參閱 aria-pressed

    tsx
    <button aria-pressed="true">👍</button>;
    
    page.getByRole('button', { pressed: true }); // ✅
    page.getByRole('button', { pressed: false }); // ❌
  • selected: boolean

    是否應包含已選取的元素。預設情況下,不應用篩選器。

    有關更多資訊,請參閱 aria-selected

    tsx
    <button role="tab" aria-selected="true">
      Vue
    </button>;
    
    page.getByRole('button', { selected: true }); // ✅
    page.getByRole('button', { selected: false }); // ❌
另請參閱 ​
  • MDN 上的 ARIA 角色列表
  • w3.org 上的 ARIA 角色列表
  • testing-library 的 ByRole

getByAltText ​

ts
function getByAltText(text: string | RegExp, options?: LocatorOptions): Locator;

建立一個能夠找到具有符合文字的 alt 屬性的元素的定位器。與 testing-library 的實作不同,Vitest 將匹配任何具有匹配 alt 屬性的元素。

tsx
<img alt="Incredibles 2 Poster" src="/incredibles-2.png" />;

page.getByAltText(/incredibles.*? poster/i); // ✅
page.getByAltText('non existing alt text'); // ❌

選項 ​

  • exact: boolean

    text 是否精確匹配:區分大小寫且完整字串。預設為停用。如果 text 是正規表達式,則忽略此選項。請注意,精確匹配仍會修剪空白字元。

另請參閱 ​

  • testing-library 的 ByAltText

getByLabelText ​

ts
function getByLabelText(
  text: string | RegExp,
  options?: LocatorOptions
): Locator;

建立一個能夠找到具有相關聯標籤的元素的定位器。

page.getByLabelText('Username') 定位器將找到以下範例中的每個輸入:

html
<!-- for/htmlFor 標籤與表單元素 id 之間的關係 -->
<label for="username-input">Username</label>
<input id="username-input" />

<!-- 具有表單元素的 aria-labelledby 屬性 -->
<label id="username-label">Username</label>
<input aria-labelledby="username-label" />

<!-- 包裝標籤 -->
<label>Username <input /></label>

<!-- 包裝標籤,其中標籤文字位於另一個子元素中 -->
<label>
  <span>Username</span>
  <input />
</label>

<!-- aria-label 屬性 -->
<!-- 請注意,這不是使用者可以在頁面上看到的標籤, -->
<!-- 因此您的輸入目的必須對視覺使用者顯而易見。 -->
<input aria-label="Username" />

選項 ​

  • exact: boolean

    text 是否精確匹配:區分大小寫且完整字串。預設為停用。如果 text 是正規表達式,則忽略此選項。請注意,精確匹配仍會修剪空白字元。

另請參閱 ​

  • testing-library 的 ByLabelText

getByPlaceholder ​

ts
function getByPlaceholder(
  text: string | RegExp,
  options?: LocatorOptions
): Locator;

建立一個能夠找到具有指定 placeholder 屬性的元素的定位器。Vitest 將匹配任何具有匹配 placeholder 屬性的元素,而不僅僅是 input。

tsx
<input placeholder="Username" />;

page.getByPlaceholder('Username'); // ✅
page.getByPlaceholder('not found'); // ❌

WARNING

通常最好依賴使用 getByLabelText 的標籤,而不是佔位符。

選項 ​

  • exact: boolean

    text 是否精確匹配:區分大小寫且完整字串。預設為停用。如果 text 是正規表達式,則忽略此選項。請注意,精確匹配仍會修剪空白字元。

另請參閱 ​

  • testing-library 的 ByPlaceholderText

getByText ​

ts
function getByText(text: string | RegExp, options?: LocatorOptions): Locator;

建立一個能夠找到包含指定文字的元素的定位器。文字將與 TextNode 的 nodeValue 或輸入的值(如果類型為 button 或 reset)進行匹配。即使是精確匹配,文字匹配也始終會正規化空白字元。例如,它會將多個空格變成一個,將換行符變成空格,並忽略開頭和結尾的空白字元。

tsx
<a href="/about">About ℹ️</a>;

page.getByText(/about/i); // ✅
page.getByText('about', { exact: true }); // ❌

TIP

此定位器對於定位非互動式元素很有用。如果您需要定位互動式元素,例如按鈕或輸入,請優先使用 getByRole。

選項 ​

  • exact: boolean

    text 是否精確匹配:區分大小寫且完整字串。預設為停用。如果 text 是正規表達式,則忽略此選項。請注意,精確匹配仍會修剪空白字元。

另請參閱 ​

  • testing-library 的 ByText

getByTitle ​

ts
function getByTitle(text: string | RegExp, options?: LocatorOptions): Locator;

建立一個能夠找到具有指定 title 屬性的元素的定位器。與 testing-library 的 getByTitle 不同,Vitest 無法在 SVG 中找到 title 元素。

tsx
<span title="Delete" id="2"></span>;

page.getByTitle('Delete'); // ✅
page.getByTitle('Create'); // ❌

選項 ​

  • exact: boolean

    text 是否精確匹配:區分大小寫且完整字串。預設為停用。如果 text 是正規表達式,則忽略此選項。請注意,精確匹配仍會修剪空白字元。

另請參閱 ​

  • testing-library 的 ByTitle

getByTestId ​

ts
function getByTestId(text: string | RegExp): Locator;

建立一個能夠找到符合指定測試 id 屬性的元素的定位器。您可以使用 browser.locators.testIdAttribute 設定屬性名稱。

tsx
<div data-testid="custom-element" />;

page.getByTestId('custom-element'); // ✅
page.getByTestId('non-existing-element'); // ❌

WARNING

建議僅在其他定位器不適用於您的使用案例時才使用此方法。使用 data-testid 屬性與您的軟體使用方式不符,應盡可能避免。

選項 ​

  • exact: boolean

    text 是否精確匹配:區分大小寫且完整字串。預設為停用。如果 text 是正規表達式,則忽略此選項。請注意,精確匹配仍會修剪空白字元。

另請參閱 ​

  • testing-library 的 ByTestId

方法 ​

所有方法都是非同步的,必須等待。自 Vitest 2.2 起,如果方法未等待,測試將失敗。

click ​

ts
function click(options?: UserEventClickOptions): Promise<void>;

點擊元素。您可以使用選項設定游標位置。

ts
import { page } from '@vitest/browser/context';

await page.getByRole('img', { name: 'Rose' }).click();
  • 更多資訊請參閱 userEvent.click

dblClick ​

ts
function dblClick(options?: UserEventDoubleClickOptions): Promise<void>;

觸發元素的雙擊事件。您可以使用選項設定游標位置。

ts
import { page } from '@vitest/browser/context';

await page.getByRole('img', { name: 'Rose' }).dblClick();
  • 更多資訊請參閱 userEvent.dblClick

tripleClick ​

ts
function tripleClick(options?: UserEventTripleClickOptions): Promise<void>;

觸發元素的三擊事件。由於瀏覽器 API 中沒有 tripleclick,此方法將連續觸發三次點擊事件。

ts
import { page } from '@vitest/browser/context';

await page.getByRole('img', { name: 'Rose' }).tripleClick();
  • 更多資訊請參閱 userEvent.tripleClick

clear ​

ts
function clear(): Promise<void>;

清除輸入元素的內容。

ts
import { page } from '@vitest/browser/context';

await page.getByRole('textbox', { name: 'Full Name' }).clear();
  • 更多資訊請參閱 userEvent.clear

hover ​

ts
function hover(options?: UserEventHoverOptions): Promise<void>;

將游標位置移動到選取的元素。

ts
import { page } from '@vitest/browser/context';

await page.getByRole('img', { name: 'Rose' }).hover();
  • 更多資訊請參閱 userEvent.hover

unhover ​

ts
function unhover(options?: UserEventHoverOptions): Promise<void>;

這與 locator.hover 的工作方式相同,但將游標移動到 document.body 元素。

ts
import { page } from '@vitest/browser/context';

await page.getByRole('img', { name: 'Rose' }).unhover();
  • 更多資訊請參閱 userEvent.unhover

fill ​

ts
function fill(text: string, options?: UserEventFillOptions): Promise<void>;

設定目前 input、textarea 或 conteneditable 元素的值。

ts
import { page } from '@vitest/browser/context';

await page.getByRole('input', { name: 'Full Name' }).fill('Mr. Bean');
  • 更多資訊請參閱 userEvent.fill

dropTo ​

ts
function dropTo(
  target: Locator,
  options?: UserEventDragAndDropOptions
): Promise<void>;

將目前元素拖曳到目標位置。

ts
import { page } from '@vitest/browser/context';

const paris = page.getByText('Paris');
const france = page.getByText('France');

await paris.dropTo(france);
  • 更多資訊請參閱 userEvent.dragAndDrop

selectOptions ​

ts
function selectOptions(
  values: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[],
  options?: UserEventSelectOptions
): Promise<void>;

從 <select> 元素中選擇一個或多個值。

ts
import { page } from '@vitest/browser/context';

const languages = page.getByRole('select', { name: 'Languages' });

await languages.selectOptions('EN');
await languages.selectOptions(['ES', 'FR']);
await languages.selectOptions([
  languages.getByRole('option', { name: 'Spanish' }),
  languages.getByRole('option', { name: 'French' }),
]);
  • 更多資訊請參閱 userEvent.selectOptions

screenshot ​

ts
function screenshot(
  options: LocatorScreenshotOptions & { base64: true }
): Promise<{
  path: string;
  base64: string;
}>;
function screenshot(
  options?: LocatorScreenshotOptions & { base64?: false }
): Promise<string>;

建立符合定位器選擇器的元素的螢幕截圖。

您可以使用 path 選項指定螢幕截圖的儲存位置,該位置相對於目前的測試檔案。如果未設定 path 選項,Vitest 將預設使用 browser.screenshotDirectory (預設為 __screenshot__),並結合檔案名稱和測試名稱來決定螢幕截圖的檔案路徑。

如果您還需要螢幕截圖的內容,您可以指定 base64: true 以在儲存螢幕截圖的檔案路徑旁傳回內容。

ts
import { page } from '@vitest/browser/context';

const button = page.getByRole('button', { name: 'Click Me!' });

const path = await button.screenshot();

const { path, base64 } = await button.screenshot({
  path: './button-click-me.png',
  base64: true, // 也傳回 base64 字串
});
// path - 螢幕截圖的完整路徑
// bas64 - 螢幕截圖的 base64 編碼字串

query ​

ts
function query(): Element | null;

此方法傳回符合定位器選擇器的單一元素,如果找不到元素則傳回 null。

如果有多個元素符合選擇器,此方法將拋出錯誤。當您需要所有符合的 DOM 元素時,請使用 .elements(),如果您需要符合選擇器的定位器陣列,請使用 .all()。

考慮以下 DOM 結構:

html
<div>Hello <span>World</span></div>
<div>Hello</div>

這些定位器不會拋出錯誤:

ts
page.getByText('Hello World').query(); // ✅ HTMLDivElement
page.getByText('Hello Germany').query(); // ✅ null
page.getByText('World').query(); // ✅ HTMLSpanElement
page.getByText('Hello', { exact: true }).query(); // ✅ HTMLSpanElement

這些定位器將拋出錯誤:

ts
// 傳回多個元素
page.getByText('Hello').query(); // ❌
page.getByText(/^Hello/).query(); // ❌

element ​

ts
function element(): Element;

此方法傳回符合定位器選擇器的單一元素。

如果沒有元素符合選擇器,則會拋出錯誤。當您只需要檢查元素是否存在時,請考慮使用 .query()。

如果多個元素符合選擇器,則會拋出錯誤。當您需要所有符合的 DOM 元素時,請使用 .elements(),如果您需要符合選擇器的定位器陣列,請使用 .all()。

TIP

如果您需要將此方法傳遞給外部函式庫,此方法會很有用。每次斷言 重試 時,當定位器與 expect.element 一起使用時,它會自動呼叫:

ts
await expect.element(page.getByRole('button')).toBeDisabled();

考慮以下 DOM 結構:

html
<div>Hello <span>World</span></div>
<div>Hello Germany</div>
<div>Hello</div>

這些定位器不會拋出錯誤:

ts
page.getByText('Hello World').element(); // ✅
page.getByText('Hello Germany').element(); // ✅
page.getByText('World').element(); // ✅
page.getByText('Hello', { exact: true }).element(); // ✅

這些定位器將拋出錯誤:

ts
// 傳回多個元素
page.getByText('Hello').element(); // ❌
page.getByText(/^Hello/).element(); // ❌

// 傳回沒有元素
page.getByText('Hello USA').element(); // ❌

elements ​

ts
function elements(): Element[];

此方法傳回符合定位器選擇器的元素陣列。

此函式永遠不會拋出錯誤。如果沒有元素符合選擇器,此方法將傳回空陣列。

考慮以下 DOM 結構:

html
<div>Hello <span>World</span></div>
<div>Hello</div>

這些定位器將始終成功:

ts
page.getByText('Hello World').elements(); // ✅ [HTMLElement]
page.getByText('World').elements(); // ✅ [HTMLElement]
page.getByText('Hello', { exact: true }).elements(); // ✅ [HTMLElement]
page.getByText('Hello').element(); // ✅ [HTMLElement, HTMLElement]
page.getByText('Hello USA').elements(); // ✅ []

all ​

ts
function all(): Locator[];

此方法傳回符合選擇器的新定位器陣列。

在內部,此方法呼叫 .elements 並使用 page.elementLocator 包裝每個元素。

  • 請參閱 locator.elements()
Pager
上一頁Interactivity API
下一頁Assertion API

以 MIT 授權條款 發布。

版權所有 (c) 2021-Present Vitest Team

https://v2.vitest.dev/guide/browser/locators

以 MIT 授權條款 發布。

版權所有 (c) 2021-Present Vitest Team