Konumlandırıcılar
Konumlandırıcılar, bir veya birden fazla web öğesini temsil eder. Her konumlandırıcı, bir seçici dizesi ile tanımlanır. Vitest, bu seçiciyi arka planda oluşturan kullanışlı yöntemler sunarak soyutlama sağlar.
Konumlandırıcı API'si, Playwright'ın konumlandırıcılarının bir çatalı olan Ivya kütüphanesini kullanır. Ancak Vitest, bu API'yi yalnızca Playwright'a özgü değil, tüm tarayıcı sağlayıcılarına sunar.
TIP
Bu sayfa, API kullanımını detaylandırmaktadır. Konumlandırıcıları ve kullanımlarını daha iyi anlamak için Playwright'ın "Konumlandırıcılar" belgelerini okumanız önerilir.
getByRole
function getByRole(
role: ARIARole | string,
options?: LocatorByRoleOptions
): Locator;
Bir öğeyi ARIA rolü, ARIA nitelikleri ve erişilebilir adı ile bulmayı sağlar.
TIP
getByText('Ad')
ile yalnızca tek bir öğeyi sorguluyorsanız, çoğu zaman getByRole(beklenenRol, { name: 'Ad' })
kullanmak daha iyi bir yaklaşımdır. Erişilebilir ad araması, *ByAltText
veya *ByTitle
gibi diğer sorguların yerini tutmaz. Erişilebilir ad bu niteliklere eşit olsa bile, bu niteliklerin işlevselliğini değiştirmez.
Aşağıdaki DOM yapısını göz önünde bulundurun:
<h3>Sign up</h3>
<label>
Login
<input type="text" />
</label>
<label>
Password
<input type="password" />
</label>
<br />
<button>Submit</button>
Her öğeyi örtük rolüyle bulabilirsiniz:
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
Roller, ARIA rol hiyerarşisinden miras alınmadan, dize eşitliğiyle eşleştirilir. Sonuç olarak, checkbox
gibi bir üst sınıf rolünü sorgulamak, switch
gibi bir alt sınıf rolüne sahip öğeleri içermeyecektir.
Varsayılan olarak, HTML'deki birçok anlamsal öğenin bir rolü vardır; örneğin, <input type="radio">
"radio" rolünü taşır. HTML'deki anlamsal olmayan öğelerin bir rolü yoktur; ek anlamsal özellikler eklenmemiş <div>
ve <span>
null
döndürür. role
niteliği anlamsal özellikler sağlayabilir.
ARIA yönergeleri, zaten örtük bir role sahip yerleşik öğelere role
veya aria-*
nitelikleri aracılığıyla rol sağlamayı şiddetle tavsiye etmez.
Seçenekler
exact: boolean
name
öğesinin tam olarak eşleşip eşleşmediğini belirler: büyük/küçük harfe duyarlı ve tüm dize. Varsayılan olarak kapalıdır.name
bir düzenli ifade ise bu seçenek göz ardı edilir. Tam eşleşme durumunda bile boşlukların kırpıldığını unutmayın.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
İşaretli öğelerin (
aria-checked
veya<input type="checkbox"/>
ile ayarlanmış) dahil edilip edilmeyeceğini belirler. Varsayılan olarak bu filtre etkin değildir.Daha fazla bilgi için
aria-checked
bölümüne bakın.tsx<> <button role="checkbox" aria-checked="true" /> <input type="checkbox" checked /> </>; page.getByRole('checkbox', { checked: true }); // ✅ page.getByRole('checkbox', { checked: false }); // ❌
disabled: boolean
Devre dışı bırakılmış öğelerin dahil edilip edilmeyeceğini belirler. Varsayılan olarak, filtre uygulanmaz. Diğer niteliklerden farklı olarak,
disabled
durumunun kalıtsal olduğunu unutmayın.Daha fazla bilgi için
aria-disabled
bölümüne bakın.tsx<input type="text" disabled />; page.getByRole('textbox', { disabled: true }); // ✅ page.getByRole('textbox', { disabled: false }); // ❌
expanded: boolean
Genişletilmiş öğelerin dahil edilip edilmeyeceğini belirler. Varsayılan olarak, filtre uygulanmaz.
Daha fazla bilgi için
aria-expanded
bölümüne bakın.tsx<a aria-expanded="true" href="example.com"> Link </a>; page.getByRole('link', { expanded: true }); // ✅ page.getByRole('link', { expanded: false }); // ❌
includeHidden: boolean
Erişilebilirlik ağacından normalde hariç tutulan öğelerin sorgulanıp sorgulanmayacağını belirler. Varsayılan olarak, rol seçici yalnızca gizli olmayan öğeleri eşleştirir.
none
vepresentation
rolleri her zaman bu kapsama dahildir.tsx<button style="display: none" />; page.getByRole('button'); // ❌ page.getByRole('button', { includeHidden: false }); // ❌ page.getByRole('button', { includeHidden: true }); // ✅
level: number
heading
,listitem
,row
,treeitem
rolleri için genellikle bulunan ve<h1>-<h6>
öğeleri için varsayılan değerlere sahip bir sayı niteliği. Varsayılan olarak, filtre uygulanmaz.Daha fazla bilgi için
aria-level
bölümüne bakın.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
Erişilebilir bir ad. Varsayılan olarak, eşleştirme büyük/küçük harfe duyarsızdır ve bir alt dize arar. Bu davranışı kontrol etmek için
exact
seçeneğini kullanın.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
Basılı öğelerin dahil edilip edilmeyeceğini belirler. Varsayılan olarak, filtre uygulanmaz.
Daha fazla bilgi için
aria-pressed
bölümüne bakın.tsx<button aria-pressed="true">👍</button>; page.getByRole('button', { pressed: true }); // ✅ page.getByRole('button', { pressed: false }); // ❌
selected: boolean
Seçili öğelerin dahil edilip edilmeyeceğini belirler. Varsayılan olarak, filtre uygulanmaz.
Daha fazla bilgi için
aria-selected
bölümüne bakın.tsx<button role="tab" aria-selected="true"> Vue </button>; page.getByRole('button', { selected: true }); // ✅ page.getByRole('button', { selected: false }); // ❌
Ayrıca bakınız
getByAltText
function getByAltText(text: string | RegExp, options?: LocatorOptions): Locator;
Metinle eşleşen bir alt
niteliğine sahip bir öğeyi bulabilen bir konumlandırıcı oluşturur. testing-library'nin uygulamasından farklı olarak, Vitest eşleşen bir alt
niteliğine sahip herhangi bir öğeyi eşleştirecektir.
<img alt="Incredibles 2 Poster" src="/incredibles-2.png" />;
page.getByAltText(/incredibles.*? poster/i); // ✅
page.getByAltText('non existing alt text'); // ❌
Seçenekler
exact: boolean
text
öğesinin tam olarak eşleşip eşleşmediğini belirler: büyük/küçük harfe duyarlı ve tüm dize. Varsayılan olarak kapalıdır.text
bir düzenli ifade ise bu seçenek göz ardı edilir. Tam eşleşme durumunda bile boşluklar temizlenir.
Ayrıca bakınız
getByLabelText
function getByLabelText(
text: string | RegExp,
options?: LocatorOptions
): Locator;
İlişkili bir etiketi olan bir öğeyi bulabilen bir konumlandırıcı oluşturur.
page.getByLabelText('Kullanıcı Adı')
konumlandırıcısı, aşağıdaki örnekteki her girişi bulacaktır:
// etiket ve form öğesi kimliği arasındaki for/htmlFor ilişkisi
<label for="username-input">Username</label>
<input id="username-input" />
// Form öğeleriyle aria-labelledby niteliği
<label id="username-label">Username</label>
<input aria-labelledby="username-label" />
// Sarmalayıcı etiketler
<label>Username <input /></label>
// Etiket metninin başka bir alt öğede olduğu sarmalayıcı etiketler
<label>
<span>Username</span>
<input />
</label>
// aria-label nitelikleri
// Kullanıcıların sayfada doğrudan göremediği bir etiket olduğundan dikkatli olun; bu nedenle girişinizin amacı görsel kullanıcılar için açık olmalıdır.
<input aria-label="Username" />
Seçenekler
exact: boolean
text
öğesinin tam olarak eşleşip eşleşmediğini belirler: büyük/küçük harfe duyarlı ve tüm dize. Varsayılan olarak kapalıdır.text
bir düzenli ifade ise bu seçenek göz ardı edilir. Tam eşleşme durumunda bile boşluklar temizlenir.
Ayrıca bakınız
getByPlaceholder
function getByPlaceholder(
text: string | RegExp,
options?: LocatorOptions
): Locator;
Belirtilen placeholder
niteliğine sahip bir öğeyi bulabilen bir konumlandırıcı oluşturur. Vitest, yalnızca input
değil, eşleşen bir placeholder
niteliğine sahip herhangi bir öğeyi eşleştirecektir.
<input placeholder="Username" />;
page.getByPlaceholder('Username'); // ✅
page.getByPlaceholder('not found'); // ❌
WARNING
Genellikle bir yer tutucuya güvenmek yerine getByLabelText
kullanarak bir etikete güvenmek daha iyidir.
Seçenekler
exact: boolean
text
öğesinin tam olarak eşleşip eşleşmediğini belirler: büyük/küçük harfe duyarlı ve tüm dize. Varsayılan olarak kapalıdır.text
bir düzenli ifade ise bu seçenek göz ardı edilir. Tam eşleşme durumunda bile boşluklar temizlenir.
Ayrıca bakınız
getByText
function getByText(text: string | RegExp, options?: LocatorOptions): Locator;
Belirtilen metni içeren bir öğeyi bulabilen bir konumlandırıcı oluşturur. Metin, TextNode'un nodeValue
değeriyle veya türü button
ya da reset
ise girişin değeriyle eşleştirilecektir. Metin eşleştirmesi, tam eşleşme durumunda bile boşlukları her zaman normalleştirir. Örneğin, birden fazla boşluğu tek bir boşluğa dönüştürür, satır sonlarını boşluklara çevirir ve baştaki ve sondaki boşlukları yok sayar.
<a href="/about">About ℹ️</a>;
page.getByText(/about/i); // ✅
page.getByText('about', { exact: true }); // ❌
TIP
Bu konumlandırıcı, etkileşimli olmayan öğeleri bulmak için kullanışlıdır. Bir düğme veya giriş gibi etkileşimli bir öğeyi bulmanız gerekiyorsa, getByRole
tercih edin.
Seçenekler
exact: boolean
text
öğesinin tam olarak eşleşip eşleşmediğini belirler: büyük/küçük harfe duyarlı ve tüm dize. Varsayılan olarak kapalıdır.text
bir düzenli ifade ise bu seçenek göz ardı edilir. Tam eşleşme durumunda bile boşluklar temizlenir.
Ayrıca bakınız
getByTitle
function getByTitle(text: string | RegExp, options?: LocatorOptions): Locator;
Belirtilen title
niteliğine sahip bir öğeyi bulabilen bir konumlandırıcı oluşturur. testing-library'nin getByTitle
'ından farklı olarak, Vitest bir SVG içindeki title
öğelerini bulamaz.
<span title="Delete" id="2"></span>;
page.getByTitle('Delete'); // ✅
page.getByTitle('Create'); // ❌
Seçenekler
exact: boolean
text
öğesinin tam olarak eşleşip eşleşmediğini belirler: büyük/küçük harfe duyarlı ve tüm dize. Varsayılan olarak kapalıdır.text
bir düzenli ifade ise bu seçenek göz ardı edilir. Tam eşleşme durumunda bile boşluklar temizlenir.
Ayrıca bakınız
getByTestId
function getByTestId(text: string | RegExp): Locator;
Belirtilen test kimliği niteliğiyle eşleşen bir öğeyi bulabilen bir konumlandırıcı oluşturur. Nitelik adını browser.locators.testIdAttribute
ile yapılandırabilirsiniz.
<div data-testid="custom-element" />;
page.getByTestId('custom-element'); // ✅
page.getByTestId('non-existing-element'); // ❌
WARNING
Bunu yalnızca diğer konumlandırıcılar kullanım durumunuz için çalışmadığında kullanmanız önerilir. data-testid
niteliklerini kullanmak, yazılımınızın nasıl kullanıldığına benzemez ve mümkünse kaçınılmalıdır.
Seçenekler
exact: boolean
text
öğesinin tam olarak eşleşip eşleşmediğini belirler: büyük/küçük harfe duyarlı ve tüm dize. Varsayılan olarak kapalıdır.text
bir düzenli ifade ise bu seçenek göz ardı edilir. Tam eşleşme durumunda bile boşluklar temizlenir.
Ayrıca bakınız
nth
function nth(index: number): Locator;
Bu yöntem, çoklu öğe sorgu sonucunda yalnızca belirli bir dizini eşleştiren yeni bir konumlandırıcı döndürür. Sıfır tabanlıdır; nth(0)
ilk öğeyi seçer. elements()[n]
'den farklı olarak, nth
konumlandırıcısı öğe mevcut olana kadar yeniden denenecektir.
<div aria-label="one"><input /><input /><input /></div>
<div aria-label="two"><input /></div>
page.getByRole('textbox').nth(0); // ✅
page.getByRole('textbox').nth(4); // ❌
TIP
nth
'ye başvurmadan önce, aramanızı daraltmak için zincirleme konumlandırıcıları kullanmak faydalı olabilir. Bazen öğeleri konumlarına göre ayırt etmekten daha iyi bir yol yoktur; bu durum kararsızlığa yol açabilse de, hiç olmamasından iyidir.
page.getByLabel('two').getByRole('input'); // ✅ page.getByRole('textbox').nth(3) için daha iyi alternatif
page.getByLabel('one').getByRole('input'); // ❌ çok belirsiz
page.getByLabel('one').getByRole('input').nth(1); // ✅ pragmatik uzlaşma
first
function first(): Locator;
Bu yöntem, çoklu öğe sorgu sonucunun yalnızca ilk dizinini eşleştiren yeni bir konumlandırıcı döndürür. nth(0)
için bir kısaltmadır.
<input /> <input /> <input />
page.getByRole('textbox').first(); // ✅
last
function last(): Locator;
Bu yöntem, çoklu öğe sorgu sonucunun yalnızca son dizinini eşleştiren yeni bir konumlandırıcı döndürür. nth(-1)
için bir kısaltmadır.
<input /> <input /> <input />
page.getByRole('textbox').last(); // ✅
and
function and(locator: Locator): Locator;
Bu yöntem, hem üst öğeyi hem de sağlanan konumlandırıcıyı eşleştiren yeni bir konumlandırıcı oluşturur. Aşağıdaki örnek, belirli bir başlığa sahip bir düğmeyi bulur:
page.getByRole('button').and(page.getByTitle('Subscribe'));
or
function or(locator: Locator): Locator;
Bu yöntem, konumlandırıcılardan birini veya her ikisini eşleştiren yeni bir konumlandırıcı oluşturur.
WARNING
Konumlandırıcı birden fazla öğeyi eşleştirirse, tek bir öğe bekleyen başka bir yöntemi çağırmak bir hata fırlatabilir:
<>
<button>Click me</button>
<a href="https://vitest.dev">Error happened!</a>
</>;
page.getByRole('button').or(page.getByRole('link')).click(); // ❌ birden fazla öğeyi eşleştirir
filter
function filter(options: LocatorOptions): Locator;
Bu yöntem, metne göre filtreleme gibi seçeneklerle konumlandırıcıyı daraltır. Birden fazla filtre uygulamak için zincirlenebilir.
has
- Tip:
Locator
Bu seçenek, seçiciyi, sağlanan konumlandırıcıyla eşleşen diğer öğeleri içeren öğeleri eşleştirecek şekilde daraltır. Örneğin, bu HTML ile:
<article>
<div>Vitest</div>
</article>
<article>
<div>Rolldown</div>
</article>
Konumlandırıcıyı, içinde Vitest
metni olan article
öğesini bulacak şekilde daraltabiliriz:
page.getByRole('article').filter({ has: page.getByText('Vitest') }); // ✅
WARNING
Sağlanan konumlandırıcı (örnekte page.getByText('Vitest')
), üst konumlandırıcıya (örnekte page.getByRole('article')
) göreli olmalıdır. Belge kökünden değil, üst konumlandırıcıdan başlayarak sorgulanır.
Yani, üst konumlandırıcının dışındaki bir öğeyi sorgulayan bir konumlandırıcıyı geçemezsiniz:
page.getByText('Vitest').filter({ has: page.getByRole('article') }); // ❌
Bu örnek başarısız olacaktır çünkü article
öğesi Vitest
metnine sahip öğenin dışındadır.
TIP
Bu yöntem, öğeyi daha da daraltmak için zincirlenebilir:
page
.getByRole('article')
.filter({ has: page.getByRole('button', { name: 'delete row' }) })
.filter({ has: page.getByText('Vitest') });
hasNot
- Tip:
Locator
Bu seçenek, seçiciyi, sağlanan konumlandırıcıyla eşleşen diğer öğeleri içermeyen öğeleri eşleştirecek şekilde daraltır. Örneğin, bu HTML ile:
<article>
<div>Vitest</div>
</article>
<article>
<div>Rolldown</div>
</article>
Konumlandırıcıyı, içinde Rolldown
bulunmayan article
öğesini bulacak şekilde daraltabiliriz.
page.getByRole('article').filter({ hasNot: page.getByText('Rolldown') }); // ✅
page.getByRole('article').filter({ hasNot: page.getByText('Vitest') }); // ❌
WARNING
Sağlanan konumlandırıcının, has
seçeneğinde olduğu gibi, belge köküne değil, üst öğeye göre sorgulandığını unutmayın.
hasText
- Tip:
string | RegExp
Bu seçenek, seçiciyi, içinde belirtilen metni içeren öğeleri eşleştirecek şekilde daraltır. string
olarak geçirildiğinde, eşleştirme büyük/küçük harfe duyarsızdır ve bir alt dize arar.
<article>
<div>Vitest</div>
</article>
<article>
<div>Rolldown</div>
</article>
Arama büyük/küçük harfe duyarsız olduğu için her iki konumlandırıcı da aynı öğeyi bulacaktır:
page.getByRole('article').filter({ hasText: 'Vitest' }); // ✅
page.getByRole('article').filter({ hasText: 'Vite' }); // ✅
hasNotText
- Tip:
string | RegExp
Bu seçenek, seçiciyi, içinde belirtilen metni içermeyen öğeleri eşleştirecek şekilde daraltır. string
geçirildiğinde, eşleştirme büyük/küçük harfe duyarsızdır ve bir alt dize arar.
Yöntemler
Tüm yöntemler eşzamansızdır ve beklenmelidir (await
kullanılmalıdır). Vitest 3'ten itibaren, bir yöntem beklenmezse (await
kullanılmazsa) testler başarısız olacaktır.
click
function click(options?: UserEventClickOptions): Promise<void>;
Bir öğeye tıklayın. Seçenekleri kullanarak imleç konumunu ayarlayabilirsiniz.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).click();
dblClick
function dblClick(options?: UserEventDoubleClickOptions): Promise<void>;
Bir öğede çift tıklama olayını tetikler. Seçenekleri kullanarak imleç konumunu ayarlayabilirsiniz.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).dblClick();
tripleClick
function tripleClick(options?: UserEventTripleClickOptions): Promise<void>;
Bir öğede üçlü tıklama olayını tetikler. Tarayıcı API'sinde tripleclick
olmadığı için, bu yöntem art arda üç tıklama olayı tetikleyecektir.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).tripleClick();
clear
function clear(options?: UserEventClearOptions): Promise<void>;
Giriş öğesi içeriğini temizler.
import { page } from '@vitest/browser/context';
await page.getByRole('textbox', { name: 'Full Name' }).clear();
hover
function hover(options?: UserEventHoverOptions): Promise<void>;
İmleç konumunu seçilen öğeye taşır.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).hover();
unhover
function unhover(options?: UserEventHoverOptions): Promise<void>;
Bu, locator.hover
ile aynı şekilde çalışır, ancak imleci document.body
öğesine taşır.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).unhover();
fill
function fill(text: string, options?: UserEventFillOptions): Promise<void>;
Geçerli input
, textarea
veya contenteditable
öğesinin değerini ayarlar.
import { page } from '@vitest/browser/context';
await page.getByRole('input', { name: 'Full Name' }).fill('Mr. Bean');
dropTo
function dropTo(
target: Locator,
options?: UserEventDragAndDropOptions
): Promise<void>;
Geçerli öğeyi hedef konuma sürükler.
import { page } from '@vitest/browser/context';
const paris = page.getByText('Paris');
const france = page.getByText('France');
await paris.dropTo(france);
selectOptions
function selectOptions(
values: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[],
options?: UserEventSelectOptions
): Promise<void>;
Bir <select>
öğesinden bir veya daha fazla değer seçin.
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' }),
]);
screenshot
function screenshot(
options: LocatorScreenshotOptions & { save: false }
): Promise<string>;
function screenshot(
options: LocatorScreenshotOptions & { base64: true }
): Promise<{
path: string;
base64: string;
}>;
function screenshot(
options?: LocatorScreenshotOptions & { base64?: false }
): Promise<string>;
Konumlandırıcının seçicisiyle eşleşen öğenin ekran görüntüsünü oluşturur.
Ekran görüntüsünün kaydedileceği konumu, geçerli test dosyasına göreli olan path
seçeneğiyle belirtebilirsiniz. path
seçeneği ayarlanmazsa, Vitest varsayılan olarak browser.screenshotDirectory
(__screenshot__
varsayılan olarak) ile birlikte dosya ve test adlarını kullanarak ekran görüntüsünün dosya yolunu belirleyecektir.
Ekran görüntüsünün içeriğine de ihtiyacınız varsa, base64: true
belirterek ekran görüntüsünün kaydedildiği dosya yoluyla birlikte döndürülmesini sağlayabilirsiniz.
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, // ayrıca base64 dizesini de döndür
});
// path - ekran görüntüsünün tam yolu
// base64 - ekran görüntüsünün base64 kodlu dizesi
UYARI 3.2.0+
Unutmayın ki, save
değeri false
olarak ayarlandığında screenshot
her zaman bir base64 dizesi döndürecektir. Bu durumda path
de göz ardı edilir.
query
function query(): Element | null;
Bu metot, konumlandırıcının seçicisiyle eşleşen tek bir öğeyi döndürür veya hiçbir öğe bulunamazsa null
döndürür.
Birden fazla öğe seçiciyle eşleşirse, bu yöntem bir hata fırlatır. Tüm eşleşen DOM öğelerine ihtiyacınız olduğunda .elements()
kullanın veya seçiciyle eşleşen konumlandırıcı dizisine ihtiyacınız olduğunda .all()
kullanın.
Aşağıdaki DOM yapısını göz önünde bulundurun:
<div>Hello <span>World</span></div>
<div>Hello</div>
Bu konumlandırıcılar hata fırlatmayacaktır:
page.getByText('Hello World').query(); // ✅ HTMLDivElement
page.getByText('Hello Germany').query(); // ✅ null
page.getByText('World').query(); // ✅ HTMLSpanElement
page.getByText('Hello', { exact: true }).query(); // ✅ HTMLSpanElement
Bu konumlandırıcılar hata fırlatacaktır:
// birden fazla öğe döndürür
page.getByText('Hello').query(); // ❌
page.getByText(/^Hello/).query(); // ❌
element
function element(): Element;
Bu metot, konumlandırıcının seçicisiyle eşleşen tek bir öğeyi döndürür.
Seçiciyle hiçbir öğe eşleşmezse, bir hata fırlatılır. Öğenin var olup olmadığını kontrol etmeniz gerektiğinde .query()
kullanmayı düşünün.
Seçiciyle birden fazla öğe eşleşirse, bir hata fırlatılır. Tüm eşleşen DOM öğelerine ihtiyacınız olduğunda .elements()
kullanın veya seçiciyle eşleşen konumlandırıcı dizisine ihtiyacınız olduğunda .all()
kullanın.
TIP
Bu yöntem, dış bir kütüphaneye aktarmanız gerektiğinde faydalı olabilir. Konumlandırıcı expect.element
ile her kullanıldığında, onay yeniden denendiğinde otomatik olarak çağrılır:
await expect.element(page.getByRole('button')).toBeDisabled();
Aşağıdaki DOM yapısını göz önünde bulundurun:
<div>Hello <span>World</span></div>
<div>Hello Germany</div>
<div>Hello</div>
Bu konumlandırıcılar hata fırlatmayacaktır:
page.getByText('Hello World').element(); // ✅
page.getByText('Hello Germany').element(); // ✅
page.getByText('World').element(); // ✅
page.getByText('Hello', { exact: true }).element(); // ✅
Bu konumlandırıcılar hata fırlatacaktır:
// birden fazla öğe döndürür
page.getByText('Hello').element(); // ❌
page.getByText(/^Hello/).element(); // ❌
// hiçbir öğe döndürmez
page.getByText('Hello USA').element(); // ❌
elements
function elements(): Element[];
Bu metot, konumlandırıcının seçicisiyle eşleşen bir öğe dizisi döndürür.
Bu işlev asla hata fırlatmaz. Seçiciyle eşleşen hiçbir öğe yoksa, bu yöntem boş bir dizi döndürür.
Aşağıdaki DOM yapısını göz önünde bulundurun:
<div>Hello <span>World</span></div>
<div>Hello</div>
Bu konumlandırıcılar her zaman başarılı olacaktır:
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
function all(): Locator[];
Bu yöntem, seçiciyle eşleşen yeni konumlandırıcıların bir dizisini döndürür.
Dahili olarak, bu yöntem .elements
'i çağırır ve her öğeyi page.elementLocator
kullanarak sarmalar.
locator.elements()
bölümüne bakın
Özellikler
selector
selector
, öğeyi tarayıcı sağlayıcısı tarafından bulmak için kullanılacak bir dizedir. Playwright bir playwright
konumlandırıcı sözdizimi kullanırken, preview
ve webdriverio
CSS kullanır.
DANGER
Bu dizeyi test kodunuzda doğrudan kullanmamalısınız. selector
dizesi yalnızca Komutlar API'si ile çalışırken kullanılmalıdır:
import type { BrowserCommand } from 'vitest/node';
const test: BrowserCommand<string> = function test(context, selector) {
// playwright
await context.iframe.locator(selector).click();
// webdriverio
await context.browser.$(selector).click();
};
import { test } from 'vitest';
import { commands, page } from '@vitest/browser/context';
test('works correctly', async () => {
await commands.test(page.getByText('Hello').selector); // ✅
// vitest otomatik olarak bir dizeye dönüştürecektir
await commands.test(page.getByText('Hello')); // ✅
});
Özel Konumlandırıcılar 3.2.0+ gelişmiş
Yerleşik konumlandırıcılar API'sini, konumlandırıcı fabrikalarının bir nesnesini tanımlayarak genişletebilirsiniz. Bu yöntemler, page
nesnesinde ve oluşturulan herhangi bir konumlandırıcıda yöntem olarak bulunacaktır.
Yerleşik konumlandırıcılar yeterli olmadığında bu konumlandırıcılar faydalı olabilir. Örneğin, kullanıcı arayüzünüz için özel bir çerçeve kullandığınızda.
Konumlandırıcı fabrikası bir seçici dizesi veya bir konumlandırıcının kendisini döndürmelidir.
TIP
Seçici sözdizimi Playwright konumlandırıcılarıyla aynıdır. Onlarla nasıl çalışılacağını daha iyi anlamak için lütfen kılavuzlarını okuyun.
import { locators } from '@vitest/browser/context';
locators.extend({
getByArticleTitle(title) {
return `[data-title="${title}"]`;
},
getByArticleCommentsCount(count) {
return `.comments :text("${count} comments")`;
},
async previewComments() {
// "this" aracılığıyla mevcut konumlandırıcıya erişiminiz var
// yöntemin `page` üzerinde çağrılması durumunda, `this`'in `page` olacağını unutmayın,
// konumlandırıcı değil!
if (this !== page) {
await this.click();
}
// ...
},
});
// typescript kullanıyorsanız, LocatorSelectors arayüzünü genişletebilirsiniz
// locators.extend, page.* ve locator.* yöntemlerinde otomatik tamamlama için
declare module '@vitest/browser/context' {
interface LocatorSelectors {
// özel yöntem bir dize döndürürse, bir konumlandırıcıya dönüştürülecektir;
// başka bir şey döndürürse, olduğu gibi döndürülecektir.
getByArticleTitle(title: string): Locator;
getByArticleCommentsCount(count: number): Locator;
// Vitest bir Promise döndürecek ve onu bir konumlandırıcıya dönüştürmeye çalışmayacaktır
previewComments(this: Locator): Promise<void>;
}
}
Yöntem genel page
nesnesinde çağrılırsa, seçici tüm sayfaya uygulanır. Aşağıdaki örnekte, getByArticleTitle
data-title
niteliğine sahip tüm öğeleri title
değeriyle bulur. Ancak, yöntem konumlandırıcı üzerinde çağrılırsa, o konumlandırıcıya göre kapsamlandırılır.
<article data-title="Hello, World!">
Hello, World!
<button id="comments">2 comments</button>
</article>
<article data-title="Hello, Vitest!">
Hello, Vitest!
<button id="comments">0 comments</button>
</article>
const articles = page.getByRole('article');
const worldArticle = page.getByArticleTitle('Hello, World!'); // ✅
const commentsElement = worldArticle.getByArticleCommentsCount(2); // ✅
const wrongCommentsElement = worldArticle.getByArticleCommentsCount(0); // ❌
const wrongElement = page.getByArticleTitle('No Article!'); // ❌
await commentsElement.previewComments(); // ✅
await wrongCommentsElement.previewComments(); // ❌