Lär dig Playwright 2026 — installation, locators, testning av SPA:er, API-testning, visuell regression och CI/CD-integrering.
Playwright från Microsoft har 2026 etablerat sig som standardverktyget för end-to-end-testning av webbapplikationer. Med stöd för Chromium, Firefox och WebKit i samma test, automatisk väntan på element, nätverksinterception och en kraftfull Inspector är det ett måste i varje utvecklares verktygslåda. Playwright är snabbare, mer tillförlitligt och har bättre API-design än sina konkurrenter.
Den här guiden tar dig från installation till avancerade testmönster. Du lär dig skriva stabila tester med korrekta locators, använda Page Object Model för underhållbarhet, köra tester parallellt, testa API:er, integrera i CI/CD och jämför Playwright med Cypress. Alla exempel är i TypeScript, vilket är standard för Playwright 2026.
Installation och första test
Playwright installeras enkelt med npm. Skapa ett nytt projekt eller lägg till i ett befintligt:
| 1 | npm init playwright@latest |
| 2 | npx playwright install |
Det första kommandot skapar en grundstruktur med testkatalog, konfigurationsfil och exempeltest. Det andra laddar ner webbläsarna (Chromium, Firefox, WebKit). Playwright-hanterade webbläsare är isolerade och påverkas inte av dina installerade webbläsare.
Skapa ditt första test i tests/example.spec.ts:
| 1 | import { test, expect } from "@playwright/test" |
| 2 | |
| 3 | test("visar startsidan", async ({ page }) => { |
| 4 | await page.goto("https://example.com") |
| 5 | await expect(page).toHaveTitle("Example Domain") |
| 6 | await expect(page.locator("h1")).toHaveText("Example Domain") |
| 7 | }) |
Kör testet med npx playwright test. Playwright öppnar en webbläsare (headless som standard), navigerar till sidan och verifierar titeln och rubriken. Resultatet visas i terminalen med grön/röd status.
Locators — hitta element på rätt sätt
Locators är Playwrights sätt att hitta element på sidan. Playwright rekommenderar användarcentrerade locators framför CSS-selektorer eller XPath — de är mer stabila och mindre känsliga för layoutändringar:
page.getByRole("button", { name: "Skicka" })— hitta via ARIA-roll och namn (bästa praxis)page.getByLabel("Anvandarnamn")— hitta formulärfält via labelpage.getByText("Valkommen")— hitta via textinnehållpage.getByTestId("submit-btn")— hitta via data-testid (bra som fallback)
Undvik CSS-selektorer som .btn-primary > span — de är spröda och går sönder vid minsta layoutändring. Använd getByRole som första val eftersom det testar tillgängligheten samtidigt som det hittar elementet. Playwrights locators är auto-waiting — de väntar automatiskt på att elementet ska bli synligt och interagerbart.
Assertions — verifiera att allt fungerar
Playwright har inbyggda assertions som är async och auto-retrying — de väntar en stund på att villkoret ska uppfyllas innan de failar. Detta eliminerar flaky-tester som misslyckas på grund av timing:
| 1 | await expect(page).toHaveURL("/dashboard") |
| 2 | await expect(page.locator("h1")).toBeVisible() |
| 3 | await expect(page.locator(".error")).not.toBeVisible() |
| 4 | await expect(page.locator("table")).toContainText("Simon") |
| 5 | await expect(page.locator("input")).toHaveValue("test@example.com") |
| 6 | await expect(page).toHaveScreenshot() |
Använd soft assertions (expect.soft()) om du vill fortsätta testet efter ett misslyckat assertion — det är användbart för att få en fullständig bild av alla fel i en testkörning.
Page Object Model — strukturera dina tester
Page Object Model (POM) är ett mönster som strukturerar dina tester genom att kapsla in sid-logik i klasser. Det gör testerna mer läsbara, underhållbara och återanvändbara:
| 1 | export class LoginPage { |
| 2 | readonly usernameInput = this.page.getByLabel("Anvandarnamn") |
| 3 | readonly passwordInput = this.page.getByLabel("Losenord") |
| 4 | readonly submitButton = this.page.getByRole("button", { name: "Logga in" }) |
| 5 | |
| 6 | constructor(private page: Page) {} |
| 7 | |
| 8 | async goto() { |
| 9 | await this.page.goto("/login") |
| 10 | } |
| 11 | |
| 12 | async login(username: string, password: string) { |
| 13 | await this.usernameInput.fill(username) |
| 14 | await this.passwordInput.fill(password) |
| 15 | await this.submitButton.click() |
| 16 | } |
| 17 | } |
| 18 | |
| 19 | test("inloggning fungerar", async ({ page }) => { |
| 20 | const loginPage = new LoginPage(page) |
| 21 | await loginPage.goto() |
| 22 | await loginPage.login("user@example.com", "password123") |
| 23 | await expect(page).toHaveURL("/dashboard") |
| 24 | }) |
Skapa en Page Object för varje sida eller komponent i din applikation. För större applikationer kan du använda fixtures för att injicera Page Objects i dina tester — Playwrights fixture-system är kraftfullt och type-safe.
Test fixtures — återanvändbar setup
Fixtures är Playwrights sätt att skapa återanvändbar testsetup. Du kan utöka standardtest-objektet med egna fixtures som Page Objects, inloggade användare eller databaskopplingar:
| 1 | import { test as base } from "@playwright/test" |
| 2 | import { LoginPage } from "./pages/login-page" |
| 3 | import { DashboardPage } from "./pages/dashboard-page" |
| 4 | |
| 5 | export const test = base.extend({ |
| 6 | loginPage: async ({ page }, use) => { |
| 7 | await use(new LoginPage(page)) |
| 8 | }, |
| 9 | authenticatedPage: async ({ page }, use) => { |
| 10 | const loginPage = new LoginPage(page) |
| 11 | await loginPage.login("admin@test.com", "password") |
| 12 | await use(new DashboardPage(page)) |
| 13 | }, |
| 14 | }) |
Använd fixtures för all setup som återkommer i flera tester — det minskar duplicering och gör testerna mer läsbara. Playwrights fixtures är lazy (skapas bara när de används) och kan vara scope:ade till test, describe-block eller hela filen.
Parallell exekvering och sharding
Playwright kör tester parallellt som standard — varje testworker kör en separat webbläsarinstans. Konfigurera antalet workers i playwright.config.ts:
| 1 | export default defineConfig({ |
| 2 | workers: process.env.CI ? 4 : undefined, |
| 3 | fullyParallel: true, |
| 4 | retries: process.env.CI ? 2 : 0, |
| 5 | }) |
För stora testsviter kan du använda sharding — dela upp testerna över flera CI-maskiner för snabbare körning. Playwrights rapportering visar tydligt status för varje test och genererar HTML-rapporter med video, screenshots och traces vid misslyckanden.
Visuell testning med screenshots
Playwright har inbyggd visuell testning med toHaveScreenshot(). Ta en screenshot och jämför pixel för pixel mot en referensbild. Detta fångar layout-förskjutningar, felaktiga färger och andra visuella regressioner som vanliga assertions missar:
| 1 | test("hemsidan ser korrekt ut", async ({ page }) => { |
| 2 | await page.goto("/") |
| 3 | await expect(page).toHaveScreenshot("homepage.png", { |
| 4 | maxDiffPixels: 100, |
| 5 | threshold: 0.2, |
| 6 | }) |
| 7 | }) |
Referensbilderna sparas och versionshanteras i Git. När du gör medvetna visuella ändringar uppdaterar du referenserna med npx playwright test --update-snapshots. Visuell testning är särskilt värdefull för komponentbibliotek, designssystem och sidor med komplex layout.
API-testning — testa backend utan webbläsare
Playwright kan testa API:er direkt utan att öppna en webbläsare, vilket är snabbare och mer fokuserat än E2E-tester för backend-logik:
| 1 | test("API returnerar anvandare", async ({ request }) => { |
| 2 | const response = await request.get("/api/users") |
| 3 | expect(response.ok()).toBeTruthy() |
| 4 | const users = await response.json() |
| 5 | expect(Array.isArray(users)).toBeTruthy() |
| 6 | expect(users.length).toBeGreaterThan(0) |
| 7 | }) |
| 8 | |
| 9 | test("skapa ny anvandare", async ({ request }) => { |
| 10 | const response = await request.post("/api/users", { |
| 11 | data: { name: "Test", email: "test@test.com" } |
| 12 | }) |
| 13 | expect(response.status()).toBe(201) |
| 14 | }) |
Kombinera API-tester med UI-tester för att skapa testdata via API innan du testar UI:t — det är snabbare och stabilare än att skapa data via UI-interaktioner.
Mobiltestning och responsiv design
Playwright emulerar mobila enheter med fördefinierade profiler för iPhone, iPad, Galaxy och Pixel. Du kan testa responsiv design, touch-interaktioner och viewport-anpassningar genom att konfigurera projekt i playwright.config.ts:
| 1 | projects: [ |
| 2 | { |
| 3 | name: "mobile", |
| 4 | use: { ...devices["iPhone 15"] }, |
| 5 | }, |
| 6 | { |
| 7 | name: "tablet", |
| 8 | use: { ...devices["iPad Pro 12.9"] }, |
| 9 | }, |
| 10 | ] |
Du kan också emulera geolocation, språk, tidszon och färgschema (dark mode). Detta gör att du kan testa hela användarupplevelsen för olika enheter och preferenser i samma testsvit.
CI/CD-integration med GitHub Actions
Playwright har utmärkt CI/CD-stöd. För GitHub Actions finns en färdig action som installerar Playwright och kör testerna:
| 1 | - uses: microsoft/playwright-github-action@v1 |
| 2 | - run: npx playwright test |
För att få visuella testrapporter i CI, använd annoteringskommandot --reporter=html och ladda upp artefakten med actions/upload-artifact. Playwrights HTML-rapport innehåller fullständig information om varje test — inklusive video, screenshots, traces och nätverksloggar vid misslyckanden.
Playwright vs Cypress — vad ska du välja?
2026 är Playwright det rekommenderade valet för de flesta nya projekt. Playwright stöder fler webbläsare (Chromium, Firefox, WebKit), har bättre prestanda (parallell exekvering på flera workers), bättre API-testning och mer kraftfull debugging med Trace Viewer. Cypress har fortfarande enklare setup för enkla tester och en mer mogen plugin-ekosystem, men Playwrights utvecklingstakt har gjort det till standardvalet.
Cypress är bättre om du har ett befintligt Cypress-projekt eller om du föredrar dess API-stil med chainable commands. Playwright är bättre för allt annat — särskilt för applikationer som använder iframes, flera tabbar, eller behöver testas i Safari (WebKit).
Felsökning och debugging
Playwrights Trace Viewer är ett kraftfullt debuggingverktyg. Aktivera tracing i konfigurationen: trace: "on-first-retry". När ett test misslyckas genereras en trace-fil som du kan öppna med npx playwright show-trace trace.zip. Trace Viewern visar exakt vad som hände i webbläsaren före, under och efter varje steg — inklusive DOM-state, nätverksloggar och console-meddelanden.
Använd page.pause() för att pausa testet och öppna Playwright Inspector — ett GUI-verktyg där du kan inspektera DOM, testa locators och stega genom testet. För snabb debugging, använd console.log och page.evaluate() för att inspektera tillstånd i webbläsaren.
Sammanfattning
Playwright är 2026 års mest kapabla E2E-testverktyg. Med stöd för alla webbläsare, automatisk väntan, Page Object Model, visuell testning, API-testning och kraftfull debugging har du allt du behöver för att skriva stabila, snabba och underhållbara tester. Börja med enkla tester för dina viktigaste användarflöden och bygg gradvis ut testsviten — dina framtida jag kommer att tacka dig.
“Playwright har 2026 blivit standardvalet för E2E-testning — snabbare, stabilare och mer kapabelt än Cypress.”
- Simon Axelsson
Vanliga frågor
- Är Playwright gratis?
- Ja, Playwright är helt gratis och open source (Apache 2.0). Det finns inga begränsningar eller betalda planer. Playwright är utvecklat av Microsoft och används av tusentals organisationer världen över.
- Kan Playwright testa single-page-applikationer (SPA)?
- Ja, Playwright har utmärkt stöd för SPA:er byggda med React, Vue, Angular och andra ramverk. Det hanterar asynkron rendering, client-side routing och dynamiska DOM-ändringar korrekt med sin auto-waiting-mekanism.
- Vad är skillnaden mellan Playwright och Selenium?
- Playwright är modernare, snabbare och enklare att använda än Selenium. Playwright har automatisk väntan, bättre API, inbyggd nätverksinterception och stöd för moderna webbläsarfunktioner. Selenium har ett större ekosystem och stöder fler språk, men Playwright är standardvalet för nya projekt 2026.
- Hur hanterar Playwright iframes och flera tabbar?
- Playwright har utmärkt stöd för iframes via <code>page.frame()</code> och <code>page.frameLocator()</code>. För flera tabbar använder du <code>context.newPage()</code> — en browser context isolerar cookies och sessions mellan tabbar. Detta är mycket enklare än i Cypress där iframe- och multi-tab-hantering är begränsad.
- Kan Playwright testa mobila appar (native)?
- Playwright testar webbapplikationer, inte native mobila appar. För att testa native iOS- eller Android-appar använder du Appium, XCUITest (iOS) eller Espresso (Android). Playwright kan dock emulera mobila webbläsare för att testa responsiva webbapplikationer på iPhone, iPad och Android.
