跳至主要內容

ByRole

getByRole、queryByRole、getAllByRole、queryAllByRole、findByRole、findAllByRole

API

getByRole(
// If you're using `screen`, then skip the container argument:
container: HTMLElement,
role: string,
options?: {
hidden?: boolean = false,
name?: TextMatch,
description?: TextMatch,
selected?: boolean,
busy?: boolean,
checked?: boolean,
pressed?: boolean,
suggest?: boolean,
current?: boolean | string,
expanded?: boolean,
queryFallbacks?: boolean,
level?: number,
value?: {
min?: number,
max?: number,
now?: number,
text?: TextMatch,
}
}): HTMLElement

查詢具有給定角色(並且也接受 TextMatch)的元素。預設角色會被納入考量,例如 <button /> 具有 button 角色,而無需明確設定 role 屬性。您可以在此處查看 具有其預設和所需角色的 HTML 元素表格

請注意,設定與隱含 ARIA 語意相符的 role 和/或 aria-* 屬性是不必要的,而且不建議這麼做,因為這些屬性已經由瀏覽器設定,而且我們不得以與描述的語意衝突的方式使用 rolearia-* 屬性。例如,button 元素不能具有 headingrole 屬性,因為 button 元素具有與 heading 角色衝突的預設特性。

角色會以字串相等的方式逐字比對,而不會從 ARIA 角色階層繼承。因此,查詢像 checkbox 這樣的超類別角色不會包含像 switch 這樣的子類別角色的元素。

您可以透過它們的可存取名稱或描述來查詢返回的元素。可存取名稱在簡單的情況下等於表單元素的標籤,或按鈕的文字內容,或 aria-label 屬性的值。如果呈現的內容上存在多個具有相同角色的元素,則可以使用它來查詢特定元素。如需深入的指南,請查看 TPGi 的「什麼是可存取名稱?」。如果您只使用 getByText('The name') 查詢單個元素,通常最好使用 getByRole(expectedRole, { name: 'The name' })。可存取名稱查詢不會取代其他查詢,例如 *ByAlt*ByTitle。雖然可存取名稱可能等於這些屬性,但它不會取代這些屬性的功能。例如,如果 fancy.jpg 無法載入,則 <img aria-label="fancy image" src="fancy.jpg" /> 將會針對 getByRole('img', { name: 'fancy image' }) 返回。您是否要在測試中斷言此功能取決於您。

輸入類型密碼

遺憾的是,規格定義 <input type="password" /> 沒有隱含角色。這表示為了查詢此類型的元素,我們必須退而求其次使用較弱的查詢,例如 ByLabelText

選項

hidden

如果您將 hidden 設定為 true,則通常會從輔助功能樹中排除的元素也會納入查詢的考量。預設行為遵循 https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion,但 role="none"role="presentation" 除外,它們在任何情況下都會在查詢中被考慮。例如,在

<body>
<main aria-hidden="true">
<button>Open dialog</button>
</main>
<div role="dialog">
<button>Close dialog</button>
</div>
</body>

getByRole('button') 只會返回「關閉對話方塊」按鈕。若要對「開啟對話方塊」按鈕進行斷言,您需要使用 getAllByRole('button', { hidden: true })

hidden 的預設值可以進行設定

selected

您可以透過設定 selected: trueselected: false 來依其選取狀態篩選返回的元素。

例如,在

<body>
<div role="tablist">
<button role="tab" aria-selected="true">Native</button>
<button role="tab" aria-selected="false">React</button>
<button role="tab" aria-selected="false">Cypress</button>
</div>
</body>

您可以透過呼叫 getByRole('tab', { selected: true }) 來取得「原生」索引標籤。若要進一步了解選取狀態以及哪些元素可以具有此狀態,請參閱 ARIA aria-selected

busy

您可以透過設定 busy: truebusy: false 來依其忙碌狀態篩選返回的元素。

例如,在

<body>
<section>
<div role="alert" aria-busy="false">Login failed</div>
<div role="alert" aria-busy="true">Error: Loading message...</div>
</section>
</body>

您可以透過呼叫 getByRole('alert', { busy: false }) 來取得「登入失敗」警示。若要進一步了解忙碌狀態,請參閱 ARIA aria-busyMDN aria-busy 屬性

checked

您可以透過設定 checked: truechecked: false 來依其勾選狀態篩選返回的元素。

例如,在

<body>
<section>
<button role="checkbox" aria-checked="true">Sugar</button>
<button role="checkbox" aria-checked="false">Gummy bears</button>
<button role="checkbox" aria-checked="false">Whipped cream</button>
</section>
</body>

您可以透過呼叫 getByRole('checkbox', { checked: true }) 來取得「糖」選項。若要進一步了解勾選狀態以及哪些元素可以具有此狀態,請參閱 ARIA aria-checked

注意

核取方塊具有「混合」狀態,既不視為已勾選也不視為未勾選(詳細資訊請參閱 此處)。

current

您可以透過設定 current: boolean | string 來依其目前狀態篩選返回的元素。請注意,由於 falsearia-current 的預設值,因此沒有 aria-current 屬性會符合 current: false

例如,在

<body>
<nav>
<a href="current/page" aria-current="page">👍</a>
<a href="another/page">👎</a>
</nav>
</body>

您可以透過呼叫 getByRole('link', { current: 'page' }) 來取得「👍」連結,並透過呼叫 getByRole('link', { current: false }) 來取得「👎」連結。若要進一步了解目前狀態,請參閱 ARIA aria-current

pressed

按鈕可以具有按下狀態。您可以透過設定 pressed: truepressed: false 來依其按下狀態篩選返回的元素。

例如,在

<body>
<section>
<button aria-pressed="true">👍</button>
<button aria-pressed="false">👎</button>
</section>
</body>

您可以透過呼叫 getByRole('button', { pressed: true }) 來取得「👍」按鈕。若要進一步了解按下狀態,請參閱 ARIA aria-pressed

suggest

您可以透過將此值設定為 false,來停用 針對特定查詢擲回建議 的能力。
將此值設定為 true 將會針對特定查詢擲回建議。

expanded

您可以透過設定 expanded: trueexpanded: false 來依其展開狀態篩選返回的元素。

例如,在

<body>
<nav>
<ul>
<li>
<a aria-expanded="false" aria-haspopup="true" href="..."
>Expandable Menu Item</a
>
<ul>
<li><a href="#">Submenu Item 1</a></li>
<li><a href="#">Submenu Item 1</a></li>
</ul>
</li>
<li><a href="#">Regular Menu Item</a></li>
</ul>
</nav>
</body>

您可以透過呼叫 getByRole('link', { expanded: false }) 來取得「可展開的功能表項目」連結。若要進一步了解展開狀態以及哪些元素可以具有此狀態,請參閱 ARIA aria-expanded

<div role="dialog">...</div>
import {screen} from '@testing-library/dom'

const dialogContainer = screen.getByRole('dialog')

queryFallbacks

根據預設,假設每個元素的第一個角色都受支援,因此只能查詢第一個角色。如果您需要改為依任何其回退角色查詢元素,您可以使用 queryFallbacks: true

例如,getByRole('switch') 會永遠比對 <div role="switch checkbox" />,因為它是第一個角色,而 getByRole('checkbox') 則不會。但是,getByRole('checkbox', { queryFallbacks: true }) 會啟用所有回退角色,因此會比對相同的元素。

元素在給定環境中沒有多個角色。它只有一個。屬性中的多個角色會從左到右評估,直到環境找到它理解的第一個角色。當引入新角色時,並且您想要開始支援這些角色以及不理解該角色(尚未)的舊環境時,這非常有用。

level

可以使用任何標題層級 getByRole('heading') 或使用 level 選項 getByRole('heading', { level: 2 }) 來查詢具有 heading 角色的元素。

level 選項會查詢具有 heading 角色的元素,並比對由語意 HTML 標題元素 <h1>-<h6> 或比對 aria-level 屬性所判定的指示層級。

以下面的範例為例,

<body>
<section>
<h1>Heading Level One</h1>
<h2>First Heading Level Two</h2>
<h3>Heading Level Three</h3>
<div role="heading" aria-level="2">Second Heading Level Two</div>
</section>
</body>

您可以使用 getByRole('heading', { level: 3 }) 來查詢 Heading Level Three 標題。

getByRole('heading', {level: 1})
// <h1>Heading Level One</h1>

getAllByRole('heading', {level: 2})
// [
// <h2>First Heading Level Two</h2>,
// <div role="heading" aria-level="2">Second Heading Level Two</div>
// ]

雖然可以在元素上明確設定 role="heading"aria-level 屬性,但強烈建議使用語意 HTML 標題 <h1>-<h6>

若要深入了解 aria-level 屬性,請參閱 ARIA aria-level

level 選項適用於 heading 角色。若用於其他任何角色,則會拋出錯誤。

value

範圍小工具可以使用任何值 getByRole('spinbutton') 查詢,也可以使用 level 選項指定特定值,例如 getByRole('spinbutton', { value: { now: 5, min: 0, max: 10, text: 'medium' } })

請注意,您不必指定 value 中的所有屬性。指定子集就足夠了,例如 getByRole('spinbutton', { value: { now: 5, text: 'medium' } })

以下面的範例為例,

<body>
<section>
<button
role="spinbutton"
aria-valuenow="5"
aria-valuemin="0"
aria-valuemax="10"
aria-valuetext="medium"
>
Volume
</button>
<button
role="spinbutton"
aria-valuenow="3"
aria-valuemin="0"
aria-valuemax="10"
aria-valuetext="medium"
>
Pitch
</button>
</section>
</body>

您可以使用以下查詢來查詢特定的微調按鈕 (spinbutton),

getByRole('spinbutton', {value: {now: 5}})
// <button>Volume</button>

getAllByRole('spinbutton', {value: {min: 0}})
// [
// <button>Volume</button>,
// <button>Pitch</button>
// ]

value 中每個指定的屬性都必須符合。例如,如果您查詢 {value: {min: 0, now: 3}},則 aria-valuemin 必須等於 0 aria-valuenow 必須等於 3。

value 選項適用於某些角色(請查看下方連結的 MDN 頁面以了解適用角色)。若用於其他任何角色,則會拋出錯誤。

若要深入了解 aria-value* 屬性,請參閱 MDN aria-valueminMDN aria-valuemaxMDN aria-valuenowMDN aria-valuetext

description

您可以根據元素的無障礙描述來篩選返回的元素。這種情況適用於當您有多個具有相同角色且沒有無障礙名稱但有描述的元素時。
例如,具有 alertdialog 角色的元素就是這種情況,其中 aria-describedby 屬性用於描述元素的內容。

例如,在

<body>
<ul>
<li role="alertdialog" aria-describedby="notification-id-1">
<div><button>Close</button></div>
<div id="notification-id-1">You have unread emails</div>
</li>
<li role="alertdialog" aria-describedby="notification-id-2">
<div><button>Close</button></div>
<div id="notification-id-2">Your session is about to expire</div>
</li>
</ul>
</body>

您可以像這樣查詢特定的元素

getByRole('alertdialog', {description: 'Your session is about to expire'})

效能

getByRole 是最常用的查詢,因為它最接近使用者體驗,但是為了提供這種準確性,它必須執行的計算可能會很耗費資源(尤其是在大型 DOM 樹中)。

當測試效能是一個考量因素時,可能需要犧牲一些準確性來換取更高的效能。

可以通過將 hidden 選項設為 true 來提高 getByRole 的效能,從而避免耗費資源的可見性檢查。請注意,這樣做會將無法訪問的元素包含在結果中。

另一種選擇可能是將 getByRole 替換為更簡單的 getByLabelTextgetByText 查詢,這些查詢速度明顯更快,但健壯性較低。