87 lines
3.4 KiB
TypeScript
87 lines
3.4 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import { ADMIN_BASE } from '../playwright.auth.config';
|
|
|
|
/**
|
|
* Real-login E2E tests — runs with AUTH_DEV_AUTOLOGIN=false.
|
|
* Both apps enforce authentication via middleware.
|
|
*
|
|
* Preconditions (`pnpm db:seed` + docker compose running):
|
|
* - op1@demo.local PIN 1111
|
|
* - admin@demo.local password admin1234
|
|
*
|
|
* Run: pnpm test:e2e:auth (no servers running on 3000/3001 — this starts its own)
|
|
*/
|
|
|
|
// ── Operator — PIN login (baseURL = localhost:3000) ──────────────────────────
|
|
|
|
test('operator: wrong PIN shows error, correct PIN enters the app', async ({ page }) => {
|
|
await page.goto('/select-operator');
|
|
|
|
// Picker is accessible without a session (it IS the login page)
|
|
await expect(page.getByText('op1@demo.local')).toBeVisible({ timeout: 15_000 });
|
|
|
|
// Select op1
|
|
await page.getByRole('button', { name: 'op1@demo.local' }).click();
|
|
await expect(page.getByText('Operador selecionado')).toBeVisible();
|
|
|
|
// Wrong PIN: 9 9 9 9
|
|
for (const d of ['9', '9', '9', '9']) {
|
|
await page.getByRole('button', { name: d }).click();
|
|
}
|
|
await page.getByRole('button', { name: 'Entrar' }).click();
|
|
await expect(
|
|
page.getByText('PIN incorreto ou conta bloqueada. Tente novamente.'),
|
|
).toBeVisible({ timeout: 10_000 });
|
|
|
|
// Digits are cleared after error — type correct PIN
|
|
for (const d of ['1', '1', '1', '1']) {
|
|
await page.getByRole('button', { name: d }).click();
|
|
}
|
|
await page.getByRole('button', { name: 'Entrar' }).click();
|
|
|
|
// Successful login → home page with "Pedir manutenção" CTA
|
|
await expect(page.getByTestId('btn-request-maintenance')).toBeVisible({ timeout: 15_000 });
|
|
});
|
|
|
|
test('operator: unauthenticated root redirects to picker', async ({ page }) => {
|
|
await page.goto('/');
|
|
// Without autologin and no session, middleware redirects to /select-operator
|
|
await expect(page).toHaveURL(/\/select-operator/, { timeout: 10_000 });
|
|
});
|
|
|
|
// ── Admin — password login (separate describe gives an isolated browser context
|
|
// with baseURL = localhost:3001, avoiding cross-port URL confusion) ──────────
|
|
|
|
test.describe('Admin password login', () => {
|
|
test.use({ baseURL: ADMIN_BASE });
|
|
|
|
test('protected route redirects to /login without session', async ({ page }) => {
|
|
await page.goto('/maintenance');
|
|
// Middleware redirects to /login (may include ?callbackUrl= query param)
|
|
await expect(page).toHaveURL(/\/login/, { timeout: 10_000 });
|
|
});
|
|
|
|
test('wrong password shows error, correct password enters the queue', async ({ page }) => {
|
|
await page.goto('/login');
|
|
await expect(page.locator('input#email')).toBeVisible({ timeout: 15_000 });
|
|
|
|
// Wrong password
|
|
await page.fill('input#email', 'admin@demo.local');
|
|
await page.fill('input#password', 'wrongpassword');
|
|
await page.getByRole('button', { name: 'Entrar' }).click();
|
|
await expect(
|
|
page.getByText('Email ou password incorretos. Tente novamente.'),
|
|
).toBeVisible({ timeout: 10_000 });
|
|
|
|
// Correct password
|
|
await page.fill('input#password', 'admin1234');
|
|
await page.getByRole('button', { name: 'Entrar' }).click();
|
|
|
|
// Successful login → maintenance queue
|
|
await expect(page).toHaveURL(/\/maintenance$/, { timeout: 15_000 });
|
|
await expect(
|
|
page.getByText('Fila de manutenção').or(page.getByText('pedidos abertos')),
|
|
).toBeVisible({ timeout: 10_000 });
|
|
});
|
|
});
|