Build a password strength meter
Build a password input that scores strength live as the user types.
Score is based on four signals: length ≥ 8, contains a lowercase letter, contains an uppercase letter, contains a digit or symbol. Each adds 1 to the score (0–4).
The label updates: 0 → Empty, 1 → Weak, 2 → Fair, 3 → Good, 4 → Strong. The meter bar fills proportionally.
Requirements
- The input is `<input type="password" data-testid="password" />`.
- The score label is `<p data-testid="strength-label">`, with text one of: Empty, Weak, Fair, Good, Strong.
- The score bar is `<div data-testid="strength-bar" aria-valuenow="N" aria-valuemin="0" aria-valuemax="4" role="progressbar" />` with aria-valuenow equal to the current score (0–4).
- An empty password renders label "Empty" and aria-valuenow="0".
- A `<p data-testid="strength-announce" role="status" aria-live="polite">` announces the current label, so a screen reader hears strength changes without the user focusing the meter.
Where it's been asked
- Microsoft
- Stripe
- Razorpay
From public interview reports — a build very like this one has shown up in a round at these companies. Not an exhaustive list.
Stuck? The react course covers the ideas this problem is built on.
import { useState } from "react"; const LABELS = ["Empty", "Weak", "Fair", "Good", "Strong"]; export default function App() { const [password, setPassword] = useState(""); // TODO: compute score (0..4) from password; look up the label. const score = 0; const label = LABELS[score]; return ( <div style={{ fontFamily: "sans-serif", padding: 16, maxWidth: 320 }}> <input type="password" data-testid="password" value={password} onChange={(e) => setPassword(e.target.value)} style={{ width: "100%", padding: 8 }} /> <div data-testid="strength-bar" role="progressbar" aria-valuenow={score} aria-valuemin={0} aria-valuemax={4} style={{ height: 8, background: "#eee", borderRadius: 4, marginTop: 8 }} > <div style={{ height: "100%", width: `${(score / 4) * 100}%`, background: "#4caf50" }} /> </div> <p data-testid="strength-label" style={{ margin: 4 }}>{label}</p> <p data-testid="strength-announce" role="status" aria-live="polite" style={{ position: "absolute", left: -9999 }}> {label} </p> </div> ); }
Ready to check it?
5 tests run against your rendered component, right here in your browser. Sign in to claim the XP when you pass.
Need a nudge?
Reveal a conceptual hint or the reference solution. Both were written and reviewed with the problem — no runtime magic.
Discussion
Sign in to postNo comments yet. Be the first to say something.