metallkart-erp/tests/e2e/admin-users.spec.ts
louis b5c39f38a4 fix(admin): email edit in user form + reset password modal (USER-EDIT-FIX-S109)
DEFECT-1: email field was missing from edit modal form — added to schema,
service (with unicity check + audit), and frontend form.
DEFECT-2: reset password modal showed undefined — fixed API return type
(temporaryPassword) and added Typography.Text copyable display.
4 Vitest + 2 Playwright E2E tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-19 14:08:38 +04:00

72 lines
3.3 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { loginAs } from './fixtures/auth';
test.describe('Admin — User Edit + Reset Password', () => {
test.beforeEach(async ({ page }) => {
await loginAs(page, 'admin');
await page.goto('/admin/users');
await page.waitForSelector('.ant-table-row', { timeout: 10000 });
});
// T-ADMIN-EDIT-EMAIL
test('edit user email via modal', async ({ page }) => {
const row = page.locator('.ant-table-row').filter({ hasText: 'test-commercial@test.local' });
await row.getByRole('button', { name: 'Редактировать' }).click();
const modal = page.getByRole('dialog', { name: 'Редактировать пользователя' });
await expect(modal).toBeVisible({ timeout: 5000 });
const emailInput = modal.getByRole('textbox', { name: /Email/i });
await expect(emailInput).toHaveValue('test-commercial@test.local');
await emailInput.clear();
await emailInput.fill('edited-commercial@test.local');
// Ensure nameRu is filled (required field, may be empty in seed)
const nameRuInput = modal.getByRole('textbox', { name: /Имя \(RU\)/i });
const nameRuVal = await nameRuInput.inputValue();
if (!nameRuVal) {
await nameRuInput.fill('Тест Продажников RU');
}
await modal.getByRole('button', { name: 'Сохранить' }).click();
await expect(modal).toBeHidden({ timeout: 5000 });
await expect(page.locator('.ant-table-row').filter({ hasText: 'edited-commercial@test.local' })).toBeVisible({ timeout: 5000 });
// Restore original email
const editedRow = page.locator('.ant-table-row').filter({ hasText: 'edited-commercial@test.local' });
await editedRow.getByRole('button', { name: 'Редактировать' }).click();
const modal2 = page.getByRole('dialog', { name: 'Редактировать пользователя' });
await expect(modal2).toBeVisible({ timeout: 5000 });
const emailInput2 = modal2.getByRole('textbox', { name: /Email/i });
await emailInput2.clear();
await emailInput2.fill('test-commercial@test.local');
await modal2.getByRole('button', { name: 'Сохранить' }).click();
await expect(modal2).toBeHidden({ timeout: 5000 });
});
// T-ADMIN-RESET-PWD
test('reset password shows copyable temporary password', async ({ page }) => {
const row = page.locator('.ant-table-row').filter({ hasText: 'test-acheteur@test.local' });
await row.getByRole('button', { name: 'Сбросить пароль' }).click();
const popconfirm = page.locator('.ant-popover:visible');
await popconfirm.getByRole('button', { name: 'Да' }).click();
// AntD v6 Modal.success — use .ant-modal-confirm
const successModal = page.locator('.ant-modal-confirm');
await expect(successModal).toBeVisible({ timeout: 10000 });
await expect(successModal.getByText('Временный пароль:')).toBeVisible();
// The password is rendered inside Typography.Text copyable
const pwdElement = successModal.locator('strong');
await expect(pwdElement).toBeVisible();
const pwd = await pwdElement.textContent();
expect(pwd).toBeTruthy();
expect(pwd!.trim()).toMatch(/^[0-9a-f]{12}$/);
await successModal.getByRole('button', { name: 'OK' }).click();
await expect(successModal).toBeHidden({ timeout: 5000 });
});
});