import { expect, test } from "@playwright/test"; test.beforeEach(async ({ page }) => { await page.route("**/api/v1/public/app-config", (route) => route.fulfill({ json: { auth: { phone_enabled: true, password_enabled: false }, operator: { call_phone: "+74950000000" }, ux: { idle_timeout_minutes: 15 }, attachments: { max_size_mb: 5, allowed_extensions: ["png", "pdf"], allowed_mime_types: ["image/png", "application/pdf"] }, consents: { personal_data: { required: true, version: "2026-07-01", document_url: "https://example.test/personal" }, user_agreement: { required: true, version: "2026-07-01", document_url: "https://example.test/agreement" }, marketing: { required: false, version: "2026-07-01", document_url: "https://example.test/marketing" }, }, }, })); await page.route("**/api/v1/public/content", (route) => route.fulfill({ json: { locale: "ru", texts: { welcome: "Добро пожаловать в HAN Chat" }, popular_questions: [{ id: "visa", mnemonic: "visa", text: "Как оформить визу?" }], version: "1", }, })); }); test("гостевой экран загружает публичный контент", async ({ page }) => { await page.goto("/"); await expect(page.getByRole("heading", { name: "Привет! Я HAN" })).toBeVisible(); await expect(page.getByText("Добро пожаловать в HAN Chat")).toBeVisible(); await expect(page.getByRole("button", { name: "Как оформить визу?" })).toBeVisible(); await expect(page.getByRole("button", { name: "Голосовое сообщение" })).toHaveCount(0); await expect(page.getByRole("button", { name: "Прикрепить файл" })).toBeVisible(); await expect(page.getByText("Продление патента через 14 дней")).toHaveCount(0); await expect(page.getByRole("button", { name: "Связь с оператором" })).toBeEnabled(); await expect(page.getByText("+74950000000")).toHaveCount(0); await expect(page.getByText(/Гость/)).toBeVisible(); }); test("История открывает текущий единый чат", async ({ page }) => { await page.goto("/"); await page.getByRole("link", { name: "История" }).click(); await expect(page).toHaveURL(/\/dialogs$/); await expect(page.getByRole("heading", { name: "Чат" })).toBeVisible(); await expect(page.getByText(/доступен после авторизации/)).toBeVisible(); }); test("первое сообщение требует обязательные согласия", async ({ page }) => { await page.goto("/"); await page.getByLabel("Сообщение").fill("Здравствуйте"); await page.getByRole("button", { name: "Отправить" }).click(); await expect(page.getByRole("heading", { name: "Согласия перед входом" })).toBeVisible(); await expect(page.getByRole("button", { name: "Продолжить" })).toBeDisabled(); }); test("Enter отправляет введённое сообщение", async ({ page }) => { await page.goto("/"); await page.getByLabel("Сообщение").fill("Отправка с клавиатуры"); await page.getByLabel("Сообщение").press("Enter"); await expect(page.getByRole("heading", { name: "Согласия перед входом" })).toBeVisible(); }); test("сообщение ограничено 4000 символами", async ({ page }) => { await page.goto("/"); await page.getByLabel("Сообщение").fill("а".repeat(4001)); await page.getByRole("button", { name: "Отправить" }).click(); await expect(page.getByRole("alert")).toContainText("Максимум — 4000 символов"); await expect(page.getByRole("heading", { name: "Согласия перед входом" })).toHaveCount(0); }); test("профиль гостя не делает защищённый запрос", async ({ page }) => { let protectedCalls = 0; await page.route("**/api/v1/me", (route) => { protectedCalls++; return route.abort(); }); await page.goto("/profile"); await expect(page.getByText("Профиль доступен после авторизации.")).toBeVisible(); expect(protectedCalls).toBe(0); });