Məzmuna keç

CSS seçiciləri

CSS seçicisi səhifədəki bir və ya bir neçə elementə işarə edən bir şablondur. CSS elementləri stilizə etmək üçün icad edilib (“hər .btn-i mavi et”), amma məhz eyni şablonlar Playwright-in page.locator()-unun elementləri tapma üsuludur. Kurs CSS seçicilərini son çarə kimi istifadə edir (getByRole və onun yoldaşlarından sonra), ona görə də onları rahat oxumaq faydalıdır.

Aşağıdakı hər nümunə kursun məşq tətbiqi olan TestMarket Lab-dan götürülmüş real seçicidir.

SeçiciNəyə uyğun gəlirReal nümunə
taghəmin növün hər elementibutton, input, tr
.classhəmin sinfə malik elementlər.product-card, .alert
#idhəmin id-yə malik tək element#email, #shipping_name
[attr=val]həmin atribut dəyərinə malik elementlər[type="submit"]
page.locator('button') // səhifədəki hər <button>
page.locator('.product-card') // class="product-card" olan hər element
page.locator('#email') // id="email" olan element
page.locator('[name="quantity"]') // name="quantity" olan hər element

id unikaldır — bir səhifədə yalnız bir #email olmalıdır. Sinif paylaşılır.product-card mağaza səhifəsindəki hər məhsula uyğun gəlir. Məhz bu fərq id seçicisini sabit, sinif seçicisini isə tez-tez bir neçə elementə uyğun gələn edir (strict-mode tələsi, Modul 2-də əhatə olunub).

Bir elementdə seçiciləri birləşdirmək

Bölmə: “Bir elementdə seçiciləri birləşdirmək”

Eyni elementdə hamısını tələb etmək üçün seçiciləri boşluq olmadan yığ:

// type="submit" də olan bir <input>
page.locator('input[type="submit"]')
// class="table-row" da olan bir <tr>
page.locator('tr.table-row')
// HƏR İKİ sinfə malik element (TestMarket-in uğur flash-ı)
page.locator('.alert.alert-success')

.alert.alert-success “həm alert, həm də alert-success sinfinə malik” deməkdir — hər ikisi eyni <div>-də. Diqqət et ki, aralarında boşluq yoxdur.

[attr="value"]-dən əlavə, mövcudluğa və ya qismən dəyərə görə uyğunlaşa bilərsən:

ŞablonNəyə uyğun gəlir
[disabled]atribut ümumiyyətlə mövcuddur (hər hansı dəyər)
[name="quantity"]dəqiq dəyər
[href^="/products"]dəyər /products ilə başlayır
[href$=".pdf"]dəyər .pdf ilə bitir
[class*="badge"]dəyər badge ehtiva edir
// TestMarket-in səbət miqdar daxiletməsi
page.locator('input[name="quantity"]')
// Admin sifarişlər cədvəlindəki status açılan siyahısı
page.locator('select[name="status"]')
// Test id ilə işarələnmiş istənilən element
page.locator('[data-testid="product-card"]')

[data-testid="…"] sadəcə bir atribut seçicisidir — buna görə getByTestId('product-card')locator('[data-testid="product-card"]') eyni elementi tapır.

Kombinatorlar — elementlər arasındakı əlaqələr

Bölmə: “Kombinatorlar — elementlər arasındakı əlaqələr”

Kombinatorlar iki elementin DOM ağacında necə əlaqəli olduğunu təsvir edir.

KombinatorAdıMənası
A B (boşluq)nəsilA-nın içində istənilən yerdə bir B
A > BuşaqA-nın birbaşa uşağı olan bir B
A + Bqonşu qardaşA-dan dərhal sonra gələn B
A ~ Bümumi qardaşA-dan sonra gələn istənilən B, eyni valideyn
// Nəsil: cədvəl gövdəsinin içindəki istənilən <tr> (TestMarket admin cədvəlləri)
page.locator('table tbody tr')
// Uşaq: .login-form-un birbaşa uşağı olan bir <button>
page.locator('.login-form > button')
// Nəsil: məhsul kartının içindəki qiymət <p>-si
page.locator('.product-card .price')

Ən çox istifadə edəcəyin boşluqdur (nəsil): .cart-table .table-row.cart-table-ın içində istənilən yerdə olan hər .table-row” deməkdir.

Psevdo-siniflər atributa görə deyil, vəziyyət və ya mövqeyə görə uyğunlaşır.

Psevdo-sinifNəyə uyğun gəlir
:first-childvalideyninin ilk uşağı olan element
:last-childson uşaq
:nth-child(2)2-ci uşaq (CSS-də 1-dən başlayır)
:hover, :checked, :disabledinteraktiv vəziyyətə görə
// Birinci sıranın ikinci xanası — diqqət et, CSS 1-dən sayır
page.locator('tr.table-row:first-child td:nth-child(2)')

Spesifiklik (hansı qayda qalib gəlir)

Bölmə: “Spesifiklik (hansı qayda qalib gəlir)”

Seçicilər rəqabət etdikdə daha spesifik olan qalib gəlir. Təxmini sıralama, zəifdən güclüyə:

  1. tag (button) — ən zəif
  2. sinif / atribut / psevdo-sinif (.btn, [type=submit], :first-child)
  3. id (#email) — ən güclü

Test üçün bu, stilizasiyaya görə daha az əhəmiyyət daşıyır — Playwright hansı qaydanın “qalib gəldiyinə” əhəmiyyət vermir, sadəcə uyğunluqları tapır. Amma bu, niyə #email-in ən dəqiq hook, xalis tag-ın isə ən az dəqiq olduğunu izah edir.

Playwright-in CSS üzərinə əlavə etdikləri

Bölmə: “Playwright-in CSS üzərinə əlavə etdikləri”

Playwright standart CSS-i, üstəlik xalis CSS-də olmayan bir neçə seçici mühərrikini və psevdo-sinfini başa düşür. Onları birbaşa locator() sətrinə qarışdıra bilərsən:

GenişlənməNə edir
:has-text("Add to Cart")mətni (ya da nəslinin mətni) sətri ehtiva edən element
:visibleyalnız həqiqətən render olunan/görünən elementlər
text="Log In"mətn mühərriki — görünən mətnə görə uyğunlaşma
css=.product-cardCSS mühərrikini açıq məcbur et
xpath=//buttonCSS əvəzinə XPath ifadəsi istifadə et
:near(), :right-of(), :below()layout seçiciləri — ekran mövqeyinə görə uyğunlaşma
>> / pierce/Shadow DOM sərhədini keç
// CSS genişlənməsi: "Add to Cart" mətnini ehtiva edən düymə
page.locator('button:has-text("Add to Cart")')
// Yalnız görünən flash mesajı
page.locator('.alert:visible')
// Layout: "Email" label-ının sağındakı daxiletmə
page.locator('input:right-of(:text("Email"))')

Bunlar rahatlıqlardır. Əksər elementlər üçün kurs sənə əvəzində getByRole / getByLabel / getByText API-ni üstün tutmağı öyrədir — o, xalis seçicilərdən daha oxunaqlı və davamlıdır. Hər birinə nə vaxt müraciət edəcəyini Modul 2 — Lokatorlar-da gör.

button hər <button>
.product-card class="product-card"
#email id="email"
[name="quantity"] atribut bərabərdir
tr.table-row <tr> VƏ class="table-row" (boşluq yox)
.alert.alert-success bir elementdə iki sinif (boşluq yox)
table tbody tr nəsil (boşluq)
.login-form > button birbaşa uşaq
td:nth-child(2) 2-ci xana (CSS 1-dən sayır)
:has-text("…") Playwright: mətni ehtiva edir
text="…" xpath=… Playwright: digər mühərriklər