Unit Tests vs End-to-End Tests
Let’s understand the difference between unit tests and end-to-end (e2e) tests.
Unit Tests (Vitest)
- Test small pieces of code (like single functions)
 - Run very quickly
 - Don’t use a real browser
 - Good for testing business logic
 
End-to-End Tests (Playwright)
- Test your whole website
 - Run in a real browser
 - Test how everything works together
 - Good for testing what real users do
 
Why Do We Need Both Types of Tests?
Think of checking a car:
- Unit tests are like testing one part at a time (brakes, lights)
 - E2E tests are like driving the whole car to make sure it works
 
We need both because:
- Unit tests help us find problems in specific parts quickly
 - E2E tests make sure everything works together properly
 
Setting Up Playwright
Let’s set up Playwright in our project.
First, install Playwright:
npm init playwright@latest
During installation, answer these questions:
- Do you want to use TypeScript? → No
 - Where to put your end-to-end tests? → tests
 - Add a GitHub Actions workflow? → No
 - Install Playwright browsers? → Yes
 
This creates:
- A 
testsfolder for your test files - A 
playwright.config.jsfile with settings 
The First Test
Let’s write our first real test.
We’ll check if we can find a link on the Noroff website:
import { test, expect } from "@playwright/test";
test("homepage should show the News link", async ({ page }) => {
  // Start at the English homepage
  await page.goto("https://www.noroff.no/en");
  // Wait for the new page to load and check its content
  await expect(page.getByRole("link", { name: "News" })).toBeVisible();
});
Let’s understand this test:
test- Creates a new test (like in Vitest)"homepage should show the News link"- Describes what we’re testingasync- Tells JavaScript to wait for things to complete({ page })- Gives us a browser page to work withgoto- Opens a specific URLgetByRole- Finds elements by their HTML roletoBeVisible- Checks if we can see something on the page
This simple test is doing what a real user would do:
- Go to the Noroff website
 - Check if they can see the News link
 
Running Tests
npx playwright test
# Runs tests in all browsers in the background (headless mode)
npx playwright test --ui
# Opens Playwright's test interface where you can see tests, run them, and see results
npx playwright test --headed
# Shows the actual browser windows while tests run - useful to see what's happening
npx playwright test --debug
# Runs tests step by step - helpful when tests fail and you need to see why
Run in specific browsers:
npx playwright test --project=webkit   # Only Safari
npx playwright test --project=firefox  # Only Firefox
npx playwright test --project=webkit --project=firefox   # Safari and Firefox
By default, tests run in:
- Chromium (Chrome)
 - Firefox
 - WebKit (Safari)
 
You can change this in playwright.config.js:
// Only run in Chrome and Firefox
export default {
  projects: [
    {
      name: "chromium",
      use: { ...devices["Desktop Chrome"] },
    },
    {
      name: "firefox",
      use: { ...devices["Desktop Firefox"] },
    },
  ],
};
Common Matchers
Here are some useful ways to check things on a webpage. These work just like the Vitest matchers we learned about before:
// Check if something is visible
await expect(page.getByRole("button")).toBeVisible();
// Check if something is hidden
await expect(page.getByRole("button")).toBeHidden();
// Check page URL
await expect(page).toHaveURL("https://www.noroff.no/en");
// Check page title
await expect(page).toHaveTitle("Noroff");
// Check text content
await expect(page.getByRole("heading")).toHaveText("Welcome");
// Check if something exists
await expect(page.getByRole("button")).toBeEnabled();
Video
Installing Playwright and looking at some of the components of an e2e test.