React End-to-End Testing
End-to-End (E2E) testing ensures that your entire application works correctly from the user's perspective. Unlike unit tests, which test individual components, E2E tests simulate real user interactions, like clicking buttons, filling forms, and navigating pages.
Why E2E Testing is Important
- Validates real user flows – Ensures login, signup, and navigation work as expected
- Catches integration issues – Detects bugs missed by unit tests
- Automates regression testing – Saves time when deploying updates
1. Setting Up Cypress for React
Cypress is a popular E2E testing framework for modern web applications.
Installation
npm install cypress --save-dev
Open Cypress
npx cypress open
- Opens Cypress Test Runner
- You can create spec files under
cypress/e2e
Basic Cypress Test
Suppose you have a simple React app with a login form:
// Login.jsx
import React, { useState } from "react";
function Login() {
const [username, setUsername] = useState("");
const [loggedIn, setLoggedIn] = useState(false);
return (
<div>
{loggedIn ? (
<h2>Welcome, {username}</h2>
) : (
<>
<inputtype="text"
placeholder="Username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<button onClick={() => setLoggedIn(true)}>Login</button>
</>
)}
</div>
);
}
export default Login;
Cypress Test Example:
// login.cy.js
describe("Login Form", () => {
it("logs in a user", () => {
cy.visit("<http://localhost:3000>"); // React app URL
cy.get("input[placeholder='Username']").type("Alice");
cy.get("button").contains("Login").click();
cy.contains("Welcome, Alice").should("be.visible");
});
});
cy.visit()opens the app in the browsercy.get()selects DOM elementscy.contains()checks that text is visible- Simulates real user interaction
2. Playwright for React E2E Testing
Playwright is another modern E2E testing tool that supports multi-browser testing.
Installation
npm install -D @playwright/test
npx playwright install
Basic Playwright Test
// login.spec.js
const { test, expect } = require("@playwright/test");
test("user can log in", async ({ page }) => {
await page.goto("<http://localhost:3000>");
await page.fill("input[placeholder='Username']", "Alice");
await page.click("text=Login");
await expect(page.locator("h2")).toHaveText("Welcome, Alice");
});
page.goto()navigates to your apppage.fill()andpage.click()simulate user actionsexpect().toHaveText()asserts that the login worked
Key Differences: Cypress vs Playwright
| Feature | Cypress | Playwright |
|---|---|---|
| Browser support | Chrome, Edge, Firefox (experimental) | Chrome, Firefox, WebKit (Safari) |
| Parallel tests | Limited | Advanced |
| Network interception | Easy | Easy |
| Test speed | Fast | Faster |
| Debugging | Interactive UI | Code-driven |
