# Playwright

## Vad det är

Playwright är ett ramverk med öppen källkod från Microsoft för att automatisera webbläsare, med ett
och samma programmeringsgränssnitt för Chromium, Firefox och WebKit. Playwright Test, publicerat på
npm som `@playwright/test`, är testköraren som är byggd ovanpå det, och det är den som de flesta
menar när de använder namnet. Samma projekt levererar också det rena biblioteket för skript som inte
är tester, ett kommandoradsverktyg och en MCP-server riktad till AI-agenter, och ett tillägg för
Visual Studio Code, allt under Apache License 2.0.

Utöver JavaScript och TypeScript går samma styrning av webbläsaren att nå från Python, där projektet
rekommenderar sitt plugin för pytest, från Java, med valfritt testramverk som JUnit, och från .NET,
med basklasser för MSTest, NUnit och xUnit.

Kommandot `npx playwright install` laddar ned projektets egna byggen av de tre motorerna, och
eftersom varje release flyttar fram de versionerna kan kommandot behöva köras igen efter en
uppgradering. Playwright kan också styra Google Chrome och Microsoft Edge där de redan finns på
maskinen. Som standard körs testerna headless, utan synligt fönster, och parallellt över alla tre
motorerna. Varje test får en ny webbläsarkontext, motsvarigheten till en ny webbläsarprofil, så att
kakor och lagring från ett test aldrig följer med till nästa.

Ett test läses som de steg en person skulle ta:

```js
import { test, expect } from "@playwright/test";

test("signing in opens the inbox", async ({ page }) => {
    await page.goto("https://example.com/sign-in");
    await page.getByLabel("Email").fill("reader@example.com");
    await page.getByRole("button", { name: "Sign in" }).click();
    await expect(page.getByRole("heading", { name: "Inbox" })).toBeVisible();
});
```

Två mekanismer bär det mesta av tyngden. Före en handling kör Playwright kontroller av att elementet
går att agera på, i dokumentationen kallade actionability checks, och väntar tills alla har gått
igenom. För ett klick måste locatorn peka ut exakt ett element, och det elementet måste vara
synligt, stabilt, vilket betyder samma omgivande ruta under minst två animationsbildrutor i följd,
kunna ta emot klicket i stället för att ligga under ett annat element, och aktiverat. Om
kontrollerna inte går igenom inom tidsgränsen slutar handlingen i ett `TimeoutError`. Påståenden,
assertions, som skrivs som `await expect(locator)` beter sig på samma sätt: de hämtar elementet om
och om igen tills villkoret är uppfyllt eller tidsgränsen för påståendet, fem sekunder som standard,
löper ut.

## Varför det spelar roll

Beslutet som Playwright tjänar är vilket beteende som måste kontrolleras i en riktig webbläsare, och
hur de kontrollerna blir tillräckligt pålitliga för att ett rött bygge ska bli trott. Vissa fel
uppstår först när sidan är ihopsatt: en dialog som täcker knappen den skulle visa, en layout som
döljer ett fält vid en viss bredd, ett skript som fungerar i en motor och kastar ett fel i en annan.
Tester som kör kodbitar isolerat ser dem aldrig.

Webbläsartester blir opålitliga, flaky, när testet och sidan tävlar med varandra. Sidan hämtar data,
animerar och renderar om, och ett test som klickar i samma ögonblick som raden körs klickar ibland
för tidigt. Det vanliga botemedlet var en fast paus, för kort på en långsam maskin och bortkastad
tid på en snabb. Automatisk väntan och påståenden som försöker igen ersätter pausen med det villkor
som testet faktiskt beror på. Guiden om assertions säger det rakt ut: webbsidor visar information
asynkront, och påståenden som bara kontrollerar en gång leder till flaky tester.

Det andra valet är hur ett test hittar saker. Guiden om locators rekommenderar i första hand
attribut som användaren möter, och rollocators framför allt, eftersom `getByRole` med ett
tillgängligt namn är det närmaste ett test kommer hur användare och hjälpmedel uppfattar sidan. Det
har en bieffekt som är värd att ha: ett test som klickar på knappen med namnet ”Sign in” går sönder
om knappen förlorar sitt namn, vilket är samma defekt som den som använder skärmläsare skulle möta.
Guiden säger också att rollocators varken ersätter granskningar av tillgänglighet eller tester av
överensstämmelse. Test-id är reservlösningen. Guiden kallar dem det mest motståndskraftiga
alternativet och samtidigt något som användaren aldrig ser, så en svit som hittar allt via id
bevisar mindre om vad en besökare upplever. Selektorer i CSS och XPath avråder guiden från, eftersom
DOM ändras ofta.

Kostnaden är tid. Att starta en webbläsare och läsa in en sida gör webbläsartester till den
långsammaste sorten ett projekt har. När ett av dem går sönder på en byggserver är Trace Viewer
vägen tillbaka in. Standardkonfigurationen spelar in en trace vid första omförsöket av ett
misslyckat test, med två omförsök på CI och noll lokalt, och tracen stegar igenom varje handling med
sidan före och efter den, nätverksanropen och konsolen.

## Så ser det ut i praktiken

En plattform här har sin affärslogik i databasen, och arbetet var att
[bygga en skiktad testsvit över fyra lager](/sv/portfolio/built-a-layered-automated-test-suite-across-four-layers-94/).
Den uttalade uppgiften var att verifiera varje lagers beteende där beteendet faktiskt finns, ”i
stället för att allt verifierades utifrån genom en webbläsare”. Go-API:t har 981 testfunktioner.
Databasen har 494 beteendetestfiler, så att en lagrad funktion testas i databasen i stället för
genom tre lager applikation ovanför. Frontenden har 543 testspecifikationer i Vitest och Playwright,
däribland 48 end-to-end-filer och 30 webbläsarspecifikationer, och sidan ger ett och samma tal för
båda verktygen. Hela sviten körs som 10 jobb i ett arbetsflöde på 612 rader, och sidan är rak om
priset: sviten är långsam, den belastar varje ändring, och i den här storleken behöver den eget
underhåll.

Den här webbplatsen styr sina egna webbläsarkontroller med ett annat bibliotek, Puppeteer, och
[kolofonen](/sv/credits/) visar samma avvägning. De kontrollerna täcker det som en validator inte
kan göra, som uppmätt kontrast, fokusordning, målstorlek, överflöd utanför viewport och
sidbrytningar vid utskrift. De tar ungefär tjugo minuter, så de körs vid behov snarare än vid varje
incheckning: spärren håller den snabba halvan, och en människa kör den långsamma.

## Var det går fel

De flesta problem med Playwright kommer från tester som kontrollerar mindre än deras namn påstår.

**En fast paus står i stället för ett villkor.** Ett test väntar två sekunder och läser sedan sidan,
eller läser ett värde en gång och jämför det med ett allmänt påstående. På en upptagen byggserver är
två sekunder ibland för kort. Gör påståendet om det en besökare skulle se, med ett så kallat
web-first-påstående som `toHaveText`, och låt det försöka igen.

**Element hittas via sin märkning.** En selektor genom tre nästlade `div`-element eller en stilklass
går sönder vid nästa omdesign medan sidan fortfarande fungerar. Hitta elementet efter roll och
tillgängligt namn, eller efter etikett eller text, och lägg till ett test-id bara när en användare
annars skulle sakna något att känna igen elementet på.

**En godkänd rollocator tas för en tillgänglighetskontroll.** `getByRole` bevisar att ett element
har den roll och det namn som testet bad om. Om kontrast, fokusordning eller resten av sidan säger
det ingenting. För det behövs en regelmotor som axe, körd från testet, så som
[guiden](https://playwright.dev/docs/accessibility-testing) från Playwright själva gör genom
`@axe-core/playwright`. Skanningen täcker sidan i det tillstånd den har när den anropas, så öppna
menyn eller dialogen först.

**Ett klick tvingas igenom.** Alternativet `force` stänger av de kontroller som inte är nödvändiga,
och för ett klick slutar Playwright kontrollera att målet faktiskt tar emot händelsen. Ett test som
behöver det går ofta runt något som en besökare också skulle möta, som en banner över knappen.
Behandla det ursprungliga felet som ett fynd, och stäng antingen bannern så som en besökare skulle
göra eller rätta överlappningen.

**Ett flaky test körs om tills det går igenom.** Med omförsök påslagna markeras ett test som
fallerar vid första körningen och går igenom vid ett omförsök som flaky i stället för misslyckat.
Ett test som är flaky vecka efter vecka tävlar antingen med sidan eller fångar ett verkligt fel som
kommer och går, och den trace som spelades in vid dess första omförsök är stället att börja leta.

**Allt kontrolleras genom webbläsaren.** En regel om priser eller behörigheter som testas genom att
klicka sig igenom tre skärmar är långsam och går sönder av skäl som saknar samband med regeln. Testa
regeln där den finns, och behåll webbläsartesterna för det som bara en webbläsare kan visa: resan,
layouten och skillnaderna mellan motorerna.

## Läs mer

- [Installation](https://playwright.dev/docs/intro) — att installera Playwright Test, köra
  exempeltesterna, HTML-rapporten och UI Mode.
- [Locators](https://playwright.dev/docs/locators) — den rekommenderade ordningen för att hitta
  element, från roll och etikett till test-id.
- [Auto-waiting](https://playwright.dev/docs/actionability) — kontrollerna bakom varje handling och
  vad `force` stänger av.
- [Assertions](https://playwright.dev/docs/test-assertions) — påståenden som försöker igen och
  sådana som inte gör det, standardtidsgränsen, mjuka påståenden och polling.
- [Trace viewer](https://playwright.dev/docs/trace-viewer-intro) — att spela in en trace vid
  omförsök och stega igenom ett misslyckat test handling för handling.
- [Browsers](https://playwright.dev/docs/browsers) — att installera motorerna, köra
  märkesversionerna av Chrome och Edge och de två headless-lägena.

<https://engineer.company/sv/glossary/playwright/>
