Kas ta Playwright ir kodėl ji tapo tokia populiari
Jei dirbi su web aplikacijomis, tikriausiai jau girdėjai apie Playwright. Ši Microsoft sukurta testavimo biblioteka pastaruosius kelerius metus tiesiog sprogdina populiarumą. Ir ne be reikalo – ji iš tikrųjų sprendžia daugelį problemų, su kuriomis susidurdavome naudodami senesnius įrankius kaip Selenium ar net Puppeteer.
Playwright leidžia automatizuoti naršyklės veiksmus ir testuoti web aplikacijas visose pagrindinėse naršyklėse: Chrome, Firefox, Safari (WebKit). Bet svarbiausia – ji tai daro tikrai gerai. Kūrėjai iš Microsoft įdėjo daug pastangų, kad API būtų paprastas, greitis – žaibus, o patikimumas – aukščiausio lygio.
Kas ją išskiria? Visų pirma, tai modernus įrankis, sukurtas atsižvelgiant į šiuolaikinių web aplikacijų poreikius. Single Page Applications, dinaminiai komponentai, sudėtingi user flow’ai – visa tai Playwright tvarko be didesnių problemų. Be to, ji iš karto palaiko kelias programavimo kalbas: JavaScript, TypeScript, Python, C#, Java. Tai reiškia, kad galite naudoti tą kalbą, kurią jūsų komanda jau gerai moka.
Cross-browser testavimo iššūkiai realybėje
Teorijoje cross-browser testavimas skamba paprasta – tiesiog paleidi tuos pačius testus skirtingose naršyklėse. Praktikoje? Nu, čia prasideda tikrasis galvos skausmas.
Kiekviena naršyklė turi savo quirks. Chrome gali puikiai atvaizduoti tam tikrą CSS animaciją, o Firefox – šiek tiek kitaip. Safari (ypač senesni versijos) kartais elgiasi tarsi gyventų savo atskirame pasaulyje. Selenium laikais tai buvo tikra kančia – skirtingi driver’iai, skirtingi API, skirtingi bugai. Kartais jaučiaisi testuojantis ne savo aplikaciją, o pačius testavimo įrankius.
Playwright šią problemą sprendžia labai elegantiškai. Visi trys naršyklių engine’ai (Chromium, Firefox, WebKit) yra palaikomi per vieną vienodą API. Tas pats kodas veikia visose naršyklėse. Jokių if (browser === 'firefox') konstrukcijų. Jokių atskirų workaround’ų. Tiesiog parašai testą ir jis veikia.
Bet čia svarbu suprasti – Playwright nenaudoja standartinių naršyklių versijų. Ji ateina su savo bundled versijomis. Tai gali skambėti kaip trūkumas, bet iš tikrųjų tai yra privalumas. Jūs visada žinote, kokia tiksliai naršyklės versija bus naudojama testuose. Nėra staigmenų dėl to, kad kažkas komandoje atsinaujino Chrome į naują versiją.
Praktinis setup’as ir pirmieji žingsniai
Gerai, užteks teorijos. Pažiūrėkim, kaip realiai pradėti naudoti Playwright cross-browser testavimui. Instaliacija yra paprasta kaip du kart du:
npm init playwright@latest
Ši komanda ne tik įdiegs Playwright, bet ir sukurs pradinę projekto struktūrą, konfigūraciją ir net pavyzdinius testus. Labai patogu pradedantiesiems. Procesas taip pat automatiškai atsisiųs visas tris naršykles, tad pirmą kartą gali užtrukti kelias minutes.
Pagrindinis konfigūracijos failas yra playwright.config.ts (arba .js, jei nenaudojate TypeScript). Čia ir vyksta magija. Štai kaip atrodo bazinė konfigūracija cross-browser testavimui:
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
});
Matote tuos projects? Kiekvienas projektas – tai atskira naršyklė. Kai paleisite testus, Playwright automatiškai juos paleis visose trijose. Jokių papildomų komandų, jokių script’ų. Tiesiog npx playwright test ir viskas vyksta.
Kaip rašyti testus, kurie tikrai veikia visur
Dabar pats smagiausias dalykas – testų rašymas. Playwright API yra tikrai intuityvus. Štai paprastas pavyzdys:
import { test, expect } from '@playwright/test';
test('user can login successfully', async ({ page }) => {
await page.goto('https://example.com/login');
await page.fill('input[name="email"]', '[email protected]');
await page.fill('input[name="password"]', 'password123');
await page.click('button[type="submit"]');
await expect(page).toHaveURL(/.*dashboard/);
await expect(page.locator('.welcome-message')).toBeVisible();
});
Šis testas veiks visose trijose naršyklėse. Bet yra keletas dalykų, į kuriuos verta atkreipti dėmesį, kad testai būtų tikrai patikimi.
Pirma, naudokite await visur, kur reikia. Playwright yra visiškai asinchroninis, ir tai yra gerai – testai veikia greitai. Bet jei pamiršite await, gaunate race condition’us ir flaky testus.
Antra, naudokite Playwright auto-waiting mechanizmą. Jums nereikia rašyti waitFor... kiekvienam elementui. Playwright automatiškai laukia, kol elementas bus matomas, enabled, stable. Tai viena iš didžiausių Playwright privalumų – testai tiesiog veikia, be papildomų wait’ų.
Trečia, būkite atsargūs su timing-dependent testais. Skirtingos naršyklės gali skirtingai greitai atvaizduoti puslapį. Jei jūsų testas priklauso nuo tikslaus timing’o (pvz., animacijų), gali tekti pridėti specifinių wait’ų arba net disable’inti animacijas testavimo metu.
Selector strategijos, kurios išgelbės jūsų nervus
Viena didžiausių problemų automatiniame testavime – elementų radimas puslapyje. Selector’iai yra testų pagrindas, ir jei jie nestabilūs, jūsų testai bus flaky kaip croissant.
Playwright palaiko visus standartus selector’ius: CSS, XPath, text-based. Bet ji taip pat turi savo išplėtimus, kurie yra neįtikėtinai naudingi. Pavyzdžiui:
// Text selector - randa elementą pagal tekstą
await page.click('text=Login');
// Role-based selector - prieinamumo atributai
await page.click('role=button[name="Submit"]');
// Chaining selectors
await page.locator('div.modal >> button.confirm').click();
// Has-text pseudo-class
await page.locator('article:has-text("Important")').click();
Mano patirtis rodo, kad role-based selector’iai yra patikimiausi cross-browser testavimui. Kodėl? Nes jie remiasi semantine HTML struktūra, ne vizualine išvaizda ar specifinėmis CSS klasėmis. Jei jūsų aplikacija naudoja tinkamus ARIA atributus (o ji turėtų!), role-based selector’iai veiks puikiai visose naršyklėse.
Dar vienas patarimas – venkite XPath, jei tik įmanoma. Taip, kartais jis būtinas sudėtingoms situacijoms, bet paprastai CSS selector’iai yra greitesni ir lengviau skaitomi. O Playwright custom selector’iai dažnai leidžia išvengti XPath visiškai.
Mobile ir tablet testavimas be realių įrenginių
Štai kur Playwright tikrai šviečia. Jūs galite testuoti ne tik desktop naršykles, bet ir mobile viewport’us su visais specifiniais nustatymais. Ir tam nereikia jokių realių telefonų ar emulatorių.
Playwright ateina su daugybe pre-configured device descriptor’ių. Norite testuoti kaip atrodo jūsų aplikacija iPhone 13? Prašom:
import { devices } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'Mobile Chrome',
use: { ...devices['Pixel 5'] },
},
{
name: 'Mobile Safari',
use: { ...devices['iPhone 13'] },
},
{
name: 'Tablet',
use: { ...devices['iPad Pro'] },
},
],
});
Kiekvienas device descriptor’ius apima ne tik ekrano dydį, bet ir user agent, viewport, touch support, device scale factor. Tai reiškia, kad jūsų aplikacija mato „naršyklę” kaip tikrą mobilų įrenginį.
Galite net testuoti landscape ir portrait orientacijas, touch gestures, geolocation. Viskas, ko reikia moderniai mobile aplikacijai. Ir visa tai veikia jūsų development mašinoje, be jokių papildomų įrankių.
Bet atsiminkite – emulation nėra 100% tas pats kaip realus įrenginys. Jei kuriate labai kritinę aplikaciją, vis tiek verta periodiškai testuoti ant realių telefonų. Bet kasdieniam development’ui ir CI/CD, Playwright emulation yra daugiau nei pakankamas.
CI/CD integracija ir parallel execution
Testai, kurie veikia tik lokaliai jūsų kompiuteryje, yra beveik nenaudingi. Tikroji vertė atsiranda, kai testai veikia automatiškai kiekviename commit’e ar pull request’e. Playwright puikiai integruojasi su visais populiariais CI/CD įrankiais.
GitHub Actions pavyzdys:
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: npm ci
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Run Playwright tests
run: npx playwright test
- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: playwright-report/
Svarbu – CI environment’e naudokite --with-deps flag’ą. Tai įdiegs visas sistemos priklausomybes, kurių reikia naršyklėms veikti Linux serveryje.
Kalbant apie greitį – Playwright palaiko parallel execution out of the box. Jūsų testai automatiškai vykdomi lygiagrečiai, naudojant visus CPU core’us. Tai reiškia, kad net ir turėdami šimtus testų, visi gali būti įvykdyti per kelias minutes.
Galite kontroliuoti, kiek worker’ių naudoti:
// playwright.config.ts
export default defineConfig({
workers: process.env.CI ? 2 : 4,
});
CI environment’e dažnai verta naudoti mažiau worker’ių, nes serveriai gali turėti ribotus resursus. Lokaliai galite leisti visą galią.
Debugging ir troubleshooting, kai kas nors neveikia
Netgi su geriausiais įrankiais kartais testai feilinasi. Ir tada prasideda debugging’as. Playwright turi keletą puikių įrankių, kurie daro šį procesą daug malonesnį.
Pirmas ir svarbiausias – headed mode. Defaulte testai vyksta headless (be vizualios naršyklės), bet galite paleisti su --headed flag’u ir matyti, kas vyksta:
npx playwright test --headed
Dar geriau – debug mode su Playwright Inspector:
npx playwright test --debug
Tai atidaro specialią debug UI, kur galite step’inti per testą, matyti selector’ius, console output’ą, network requests. Tai kaip Chrome DevTools, bet specialiai pritaikytas testavimui.
Kitas naudingas dalykas – screenshots ir video įrašymas. Galite konfigūruoti, kad Playwright automatiškai darytų screenshot’us kai testas feilinasi:
export default defineConfig({
use: {
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
});
Tada CI environment’e galite upload’inti šiuos artifact’us ir tiksliai matyti, kas nutiko. Nebelieka spėliojimų „kodėl testas feilinasi CI, bet veikia lokaliai”.
Dar vienas patarimas – naudokite page.pause() development’e. Tai sustabdo testo vykdymą ir leidžia jums interaktyviai tyrinėti puslapį:
test('debug this flow', async ({ page }) => {
await page.goto('https://example.com');
await page.pause(); // Testas sustos čia
// Galite rankiniu būdu interaktuoti su puslapiu
});
Ką daryti, kai testai veikia vienoje naršyklėje, bet ne kitoje
Tai nutinka. Net su Playwright unified API, kartais susiduriate su browser-specific problemomis. Štai keletas dažniausių scenrijų ir kaip juos spręsti.
**Timing skirtumai**: Firefox kartais yra šiek tiek lėtesnis renderinant sudėtingus puslapius. Jei testas feilinasi tik Firefox, pabandykite padidinti timeout’us:
test('slow test', async ({ page }) => {
test.setTimeout(60000); // 60 sekundžių
// arba specifiniam action'ui
await page.click('button', { timeout: 10000 });
});
**WebKit quirks**: Safari (WebKit) kartais elgiasi kitaip su CSS transforms ar animations. Jei testas feilinasi tik WebKit, galite jį skip’inti arba pridėti browser-specific logic:
test('works everywhere except webkit', async ({ page, browserName }) => {
test.skip(browserName === 'webkit', 'Known WebKit issue');
// testas
});
Bet geriau nei skip’inimas – fix’inti problemą. Dažnai tai reiškia, kad jūsų aplikacijoje yra kažkas, kas nėra cross-browser compatible. Testai atskleidžia tikras problemas!
**Font rendering**: Skirtingos naršyklės skirtingai renderina fontus. Jei naudojate visual regression testing, gali tekti turėti atskirus baseline screenshot’us kiekvienai naršyklei.
**File uploads**: Visi browser’iai palaiko file upload’us, bet kartais skiriasi dialogo behavior. Playwright abstraktuoja tai, bet jei naudojate custom file picker’ius, gali prireikti papildomo testavimo.
Svarbiausia – nevenk problemų. Jei testas feilinasi vienoje naršyklėje, tai greičiausiai reiškia, kad ir realūs user’iai toje naršyklėje susidurs su problemomis. Tai yra cross-browser testavimo tikslas – rasti šias problemas prieš production.
Kai viskas sueina į vieną vietą
Playwright cross-browser testavimas nėra tik įrankis – tai būdas užtikrinti, kad jūsų aplikacija veikia visiems, nepriklausomai nuo jų naršyklės pasirinkimo. Ir tai tampa vis svarbiau, nes user’iai tikisi, kad viskas veiks sklandžiai, nesvarbu ar jie naudoja Chrome darbe, Firefox namuose, ar Safari savo iPhone.
Pradėti naudoti Playwright yra paprasta, bet tikroji vertė atsiranda, kai tai tampa jūsų development workflow dalimi. Kai testai vyksta automatiškai kiekviename commit’e. Kai komanda pasitiki testais ir gali refactorinti drąsiai. Kai bug’ai yra sugaunami development’e, ne production’e.
Taip, pradžioje reikia investuoti laiko. Setup’as, pirmųjų testų rašymas, CI/CD integracija. Bet šis investavimas atsipirksta labai greitai. Mažiau manual testing’o. Mažiau bug’ų production’e. Daugiau pasitikėjimo, kad jūsų kodas veikia.
Ir galiausiai – testai yra dokumentacija. Gerai parašyti Playwright testai parodo, kaip aplikacija turėtų veikti. Naujas team member gali perskaityti testus ir suprasti user flow’us. Tai yra gyvoji dokumentacija, kuri niekada nepasensta, nes ji turi veikti, kad CI praeitų.
Taigi, jei dar nenaudojate Playwright, dabar geras laikas pradėti. Jei jau naudojate, bet tik vienai naršyklei – išplėskite į visas tris. Jūsų user’iai jums padėkos. O jūs miegosite ramiau, žinodami, kad aplikacija veikia visur.
