Formsadvanced hidden bug 18 min
Multi-Step Auth & OTP Flow — Practice in Playwright, Selenium & Cypress
End-to-end auth automation practice — username/password step, six-digit OTP, simulated network verification, and POM-friendly fixture setup.
Live element
Hidden bug planted — try to catch it🐞 Sort High→Low and watch your test catch a defect.
Locators cheat-sheet
| data-testid | Role | Accessible label | What it is |
|---|---|---|---|
| email-input | textbox | Email field. 🐞 Validation is case-sensitive when it shouldn't be. | |
| password-input | textbox | Password | Password field (type=password). |
| login-btn | button | Log in | Submits the form. |
| welcome | status | Welcome message | Appears on a successful login. |
| login-error | alert | Login error | Appears on a failed login attempt. |
Reference solutions
import { test, expect } from '@playwright/test';
const EMAIL = 'qa@pilot.test';
const PASS = 'Password1!';
test('logs in with seed credentials', async ({ page }) => {
await page.goto('/practice/auth-flow');
const frame = page.frameLocator('iframe[title="Auth flow live widget"]');
await frame.getByTestId('email-input').fill(EMAIL);
await frame.getByTestId('password-input').fill(PASS);
await frame.getByTestId('login-btn').click();
await expect(frame.getByTestId('welcome')).toBeVisible();
});
test('🐞 email comparison should be case-insensitive (planted bug)', async ({ page }) => {
await page.goto('/practice/auth-flow');
const frame = page.frameLocator('iframe[title="Auth flow live widget"]');
// Same email, different casing — a real product should accept it.
await frame.getByTestId('email-input').fill('QA@Pilot.Test');
await frame.getByTestId('password-input').fill(PASS);
await frame.getByTestId('login-btn').click();
// ❌ With the planted bug, login-error appears and this assertion FAILS.
await expect(frame.getByTestId('welcome')).toBeVisible();
});