- В нижнем меню добавлен пункт «Игры» (иконка джойстика). Путь:
/games. - Страница игр содержит грид доступных мини-игр с кнопкой «Начать игру» для каждой. Вёрстка помечена
data-testidдля стабильных e2e:data-testid="games-page"— контейнер страницы (есть и в состоянии загрузки)data-testid="games-grid"— грид карточек игрdata-testid="game-card-<id>"иdata-testid="button-start-<id>"
Локальный прогон (Windows PowerShell):
npm run -s e2eПолезные режимы:
# Запуск одного теста по имени
npm run -s e2e -- -g games-smoke
# UI-режим
npm run -s e2e:uiЗамечания по окружению:
- Во время e2e
DATABASE_URLпринудительно пустой, сервер использует in-memory storage. - Базовый URL для браузера:
PLAYWRIGHT_BASE_URL(по умолчаниюhttp://127.0.0.1:5000).
Общие e2e-утилиты:
- Файл
e2e/utils.tsпредоставляет хелперы, чтобы писать короткие и стабильные тесты:registerViaApi(request, prefix)— быстрая регистрация пользователя через API.loginUI(page, creds)— логин через UI вкладки «Вход».createInvite(request)— создать инвайт-код пары.registerPartnerWithInvite(browser, code, prefix)— зарегистрировать партнёра в новом контексте и вернуть{ ctx, page }.openGame(page, gameTestId)— открыть страницу игр и карточку нужной игры, дождаться кнопки «Назад».fillByType(locator, value)— корректно заполнить поля сtype=numberили текстовые.
Стабильные селекторы:
- В списке игр карточки помечены
data-testid="game-card-<id>". - Для игры «20 вопросов» добавлены фазы:
data-testid="phase-setup",phase-thinking,phase-guessing,phase-finished.
- Для «Викторины о партнёре» добавлены:
data-testid="phase-setup",phase-answering,phase-guessing.
- Для «Ролевой игры» добавлены:
data-testid="phase-selection",phase-role-assignment,phase-playing.
- Для «Правда или Действие» добавлены:
data-testid="phase-selection",phase-action.
- Общие элементы:
- Кнопка возврата из игры:
data-testid="button-back". - Заголовки и ключевые поля/кнопки имеют
data-testidтам, где это важно для e2e.
- Кнопка возврата из игры:
Покрытие E2E (выдержка):
- Игры — навигация и открытие всех карточек (
e2e/games-all.spec.ts). - Ролевая игра — минимальный флоу выбора сценария, старта, отправки сообщения и новой подсказки (
e2e/role-playing-flow.spec.ts). - Двухпользовательские флоу: викторина партнёров и «20 вопросов» используют инвайт и второй браузерный контекст (
e2e/partner-quiz-flow.spec.ts,e2e/twenty-questions-flow.spec.ts). - Быстрые smokes:
- «Правда или Действие» — открытие и базовый UI без второго контекста (
e2e/truth-or-dare-smoke.spec.ts). - «Ролевая игра» — выбор сценария и переход к назначению ролей (
e2e/role-playing-smoke.spec.ts). - «Профиль: аватар» — загрузка изображения и появление
<img alt="Avatar">(e2e/avatar-upload-smoke.spec.ts). - «Чат: эфемерные» — включение режима, отправка сообщения, проверка таймера/пометки (
e2e/chat-ephemeral-smoke.spec.ts).
- «Правда или Действие» — открытие и базовый UI без второго контекста (
- «Музыка: хоткеи» — проверка Space/стрелок/мьюта/prev/next (
e2e/music-hotkeys-smoke.spec.ts). - «Музыка: мини‑плеер» — появление и базовые элементы (
e2e/music-mini-player.spec.ts). - «Музыка: загрузка» — диалог метаданных, появление в списке, очистка удалением (
e2e/music-upload-smoke.spec.ts). - «Музыка: удаление» — удаление строки через меню (
e2e/music-delete-smoke.spec.ts). - «Музыка: редактирование» — изменение названия/исполнителя (
e2e/music-edit-meta-smoke.spec.ts).
A11y‑smoke:
- Публичные страницы
/auth,/privacy,/termsпроверяются с помощью@axe-core/playwright(e2e/a11y-smoke.spec.ts). - Авторизованные страницы «Музыка / Профиль / Настройки» имеют отдельный строгий a11y‑smoke (
e2e/a11y-auth-smoke.spec.ts) — тесты падают при любой серьёзной/критичной проблеме.- Запуск только a11y‑смоков:
npm run -s e2e -- -g "^a11y:"
- Запуск только a11y‑смоков:
Когда сценарий требует двух пользователей (вы и партнёр), используйте хелперы из e2e/utils.ts:
import {
registerViaApi,
loginUI,
createInvite,
registerPartnerWithInvite,
openGame,
} from './utils';
test('partner flow example', async ({ page, request, browser }) => {
// 1) Регистрируемся через API, логинимся через UI
const creds = await registerViaApi(request, 'demo');
await loginUI(page, creds);
// 2) Создаём инвайт и регистрируем партнёра во втором контексте
const inviteCode = await createInvite(page.request);
const { ctx, page: partnerPage } = await registerPartnerWithInvite(browser, inviteCode, 'demo');
// 3) Открываем нужную игру у обоих (например, викторина)
await openGame(page, 'game-card-partner-quiz');
await openGame(partnerPage, 'game-card-partner-quiz');
// 4) Пишем ассерты и действия…
// ...
await ctx.close();
});Советы:
- Избегайте жёстких ожиданий и заголовков, предпочитайте устойчивые
data-testid. - Для числовых полей используйте
fillByType— он корректно заполнит<input type="number">.
npm run -s check # TypeScript (в Windows использует локальный tsc через node)
npm run -s test # Юнит-тесты (Vitest)
npm run -s e2e # E2E (Playwright)Кратко: минималистичное веб‑приложение для пары. Можно хранить воспоминания (фото/видео/текст/цитаты), переписываться в чате (в т.ч. эфемерные сообщения), играть в мини‑игры, считать важные вещи (счётчики), слушать свою музыку, вести профиль и настраивать совместные параметры.
- Клиент: React + Vite + Tailwind (минималистичный UI, единая палитра, стеклянные панели). Роутинг — Wouter. Состояние данных — TanStack Query.
- Сервер: Node.js + Express + Vite (в dev), WebSocket (ws) для real‑time чата и игр, сессии через express‑session.
- Данные: Drizzle ORM (PostgreSQL). В dev без БД доступно временное in‑memory хранилище. Схемы и валидация запросов — Zod.
- Файлы: локальные загрузки в
public/uploads/*(аватары, воспоминания, аудио). В проде можно переключить на облако.
Основные разделы:
- Лента воспоминаний: просмотр/создание, теги, видимость, превью.
- Чат: обычные и эфемерные сообщения (исчезают через 5 минут, сервер контролирует срок), индикация печати, анимации слов.
- Игры: заготовки под викторины/правда или действие/20 вопросов и т.п. с real‑time синхронизацией.
- Счётчики: небольшие виджеты для совместных целей.
- Профиль/настройки: персональные и парные параметры, тема, фон чата и др.
client/— фронтенд (React + Tailwind). Важное:src/pages/*— страницы.src/components/*— UI и виджеты (карточки, модалки, чат‑сообщения и пр.).src/lib/*— утилиты, клиент API, настройки Query Client.src/hooks/*— аутентификация, плеер, тосты.
server/— бэкенд (Express + ws):index.ts— инициализация сервера, Vite middlewares в dev, статика в prod.routes.ts— REST API и WebSocket/ws.auth.ts— локальная аутентификация, сессии.storage.ts— реализация хранилища:MemStorage(dev) иPgStorage(prod/БД).db.ts— подключение к Postgres (Neon/pg) и Drizzle.vite.ts— интеграция Vite с Express в dev.
shared/schema.ts— единые типы и схема БД (Drizzle + Zod).
Скопируйте .env.example в .env и при необходимости заполните:
DATABASE_URL— строка подключения Postgres (для prod и dev с БД).SESSION_SECRET— секрет для сессий.APP_ORIGIN— базовый URL (например,http://127.0.0.1:5000).PORT— порт сервера (по умолчанию 5000; в dev авто‑подбор следующего свободного).
Секреты .env игнорируются Git.
- Разработка:
npm run dev— dev‑сервер (Express + Vite HMR).npm run dev:debug— то же, но с Node инспектором.
- Проверки/сборка:
npm run check— проверка типов TypeScript.npm run build— сборка клиента и бандл сервера.npm start— запуск собранного сервера.npm run lint/npm run lint:fix— ESLint проверки/исправления.npm run format— форматирование Prettier.
- База (Drizzle):
npm run db:push— применить схему к БД (нужны корректные права на Postgres).
В VS Code доступны задачи (.vscode/tasks.json): Dev, Build, TypeScript check, DB push, Env check и др.
- Минимализм: единая палитра, аккуратные отступы, стеклянные панели без лишней визуальной «шумихи».
- Безопасность: валидации Zod на сервере, контроль сроков эфемерных сообщений на сервере, маскирование чувствительных логов.
- Заголовки безопасности через helmet (CSP отключён в dev для совместимости с Vite, COEP отключён для HMR).
- Rate limiting: общий лимит для
/api/*, отдельные строгие лимиты для/api/login,/api/register*и эндпоинтов загрузки.
- Производительность: real‑time через WebSocket, без агрессивного polling; чёткий split клиента возможен позже.
- Стеклянные панели:
- Класс
glass— базовое стекло с мягкими тенями. - Класс
glass-strong— более контрастное стекло для акцентов.
- Класс
- Ховеры и фокус:
hover-lift— лёгкий подъём/тень при наведении.focus-ring— заметное и доступное фокус‑кольцо.
- Фоновые слои:
.ui-noiseи.ui-glow— фоновые шум и мягкое свечение, добавляются глобально вApp.tsx.
- Reduced motion:
- Уважение системной настройки
prefers-reduced-motion: анимации упрощаются/отключаются.
- Уважение системной настройки
Где смотреть:
- Реализация классов —
client/src/index.css. - Пример подключения фоновых слоёв —
client/src/App.tsx. - Примеры применения —
BottomNav,memory-card,home-page.
- Пробел — Play/Pause
- ← / → — Перемотка −5/+5 секунд
- ↑ / ↓ — Громкость ±5%
- M — Mute/Unmute
- N / P — Следующий / Предыдущий трек
Чтобы избежать ошибок порядка объявлений (used before declaration) и лишних перерендеров:
- Объявляйте вспомогательные функции/колбэки, которые нужны в
useEffect, до самого эффекта. - Либо обрабатывайте сообщения прямо внутри
ws.onmessageи не тяните внутрь эффекта внешние обработчики. - Для чтения актуального состояния внутри колбэков используйте
useRefснапшоты (например,roundRefдля результата раунда).
Примеры: partner-quiz.tsx (инлайн обработка), role-playing.tsx (колбэки объявлены перед эффектом), twenty-questions.tsx.
- TypeScript: зелёный (
npm run check). - ESLint: строгий режим поддерживается (
npm run lint:strict). - Verify: единый прогон
npm run verify(tsc + eslint strict + tests + smoke).
- Фреймворк: Vitest. Конфиг —
vitest.config.ts(alias@,@shared). - Тесты лежат в
tests/. Сейчас покрытMemStorageбазовыми кейсами. - Запуск:
npm run -s test— единоразовый прогонnpm run -s test:watch— режим наблюдения
- Примечание: во время юнит‑тестов
.envне загружается (см.server/config.ts),DATABASE_URLочищается черезtests/setup.ts, сервер использует in-memory хранилище. Для проверки против реальной БД явно задайтеDATABASE_URLи запустите внеNODE_ENV=test.
- Установка браузеров (однократно):
npm exec -- @playwright/test install - Запуск смоук‑тестов:
npm run -s e2e- UI‑режим:
npm run -s e2e:ui
- База URL для e2e: задайте
PLAYWRIGHT_BASE_URL(по умолчаниюhttp://127.0.0.1:5000).- PowerShell:
$env:PLAYWRIGHT_BASE_URL='http://127.0.0.1:5000'; npm run -s e2e
- PowerShell:
Примечание для Windows/Pwsh:
- Если PowerShell сообщает «Could not determine Node.js install directory», запустите Playwright через локальный CLI ноды:
npm run -s e2e:node -- -g "settings: reset to defaults"Включены husky + lint-staged:
- На коммит выполняются: форматирование Prettier и eslint --fix только по затронутым файлам, затем общий tsc, eslint:strict и vitest (только изменённые тесты, при необходимости — полный прогон).
- Настройки: раздел
lint-stagedвpackage.json, хук.husky/pre-commit.
Примечание: если коммит слишком большой, прогон может занять время — рекомендуется коммитить чаще небольшими порциями.
- В репозитории есть workflow
.github/workflows/verify.yml— запускается на push/PR вmainи гоняетnpm run verifyсNODE_ENV=development. - БД: в non‑prod окружении при отсутствии
DATABASE_URLсервер работает в in‑memory режиме, что позволяет выполнять smoke без внешней базы.
- Helmet: добавляет базовые security‑заголовки. В dev отключены
contentSecurityPolicyиcrossOriginEmbedderPolicyдля корректной работы Vite HMR. - Rate limiting: мягкий лимит для всех
/api/*(по умолчанию 300 запросов/мин), плюс более строгие лимиты для авторизации и загрузок. - Эфемерные сообщения: срок действия задаётся только на сервере, клиентская длительность игнорируется.
GET /api/health— простой статус{ status: "ok", env }(без аутентификации)GET /api/version— читаетpackage.jsonи отдаёт{ name, version }
Для базовой валидации памяти MemStorage добавлен скрипт:
- Запуск:
npm run smoke - Проверяет:
- создание пользователя и авто-создание пары для main_admin
- генерацию/отзыв/повторную генерацию инвайт-кода
- присоединение к паре и корректное присвоение роли (guest|co_admin)
- получение партнёра
getPartnerInfo - обновление пользователя
updateUserс сохранениемid/updatedAt
В .vscode/tasks.json доступны задачи:
- TypeScript check — проверка типов
- ESLint (strict) — строгий линт без предупреждений
- Smoke (MemStorage) — быстрый прогон in-memory сценариев
- Verify (tsc+lint+smoke) — полный прогон проверок
- Установить зависимости:
npm i - Заполнить
.env(или удалитьDATABASE_URL, чтобы в dev использовать in‑memory). - Запустить разработку:
npm run dev - Открыть URL из лога (ожидаемо
http://127.0.0.1:5000или:5000).
- Если задать
DATABASE_URL, сервер и сессии используют Postgres. Убедитесь, что учетные данные верные — иначе миграции/CRUD упадут. - Для локальной разработки допустим режим без БД: просто не задавайте
DATABASE_URL.
Поддержка и доработка: добавление хуков pre‑commit (Husky), Docker‑сборка, облачные стореджи (S3/GCS) и CI/CD — по запросу.