test(menu-walk): лингва-проверка UI + фикс «low-stock» в настройках
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker Web / Build + push Web (push) Waiting to run
Docker Web / Deploy Web on stage (push) Blocked by required conditions
- stage-ui-menu-walk: assertNoUiEnglish — узкий denylist хромовых строк (Dashboard / «Low-stock alerts» / live / offline / Live-обновл), пропуск документации (/help, /whats-new, /admin/diagnostic), где латиница легитимна (клавиши, код-идентификаторы, бренды). Прогон admin: 1 passed, 0 ошибок. - Настройки Telegram: «…топ-3 товара, low-stock…» → «…низкий остаток…» (ru.json + OrganizationSettingsPage) — единственная оставшаяся видимая латиница в UI. - Галерея сайта и прогресс обновлены. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
0a23c0349b
commit
6557ac34ec
|
|
@ -13,7 +13,7 @@
|
|||
.thumb{max-height:620px;overflow:auto}
|
||||
</style></head><body>
|
||||
<header><h1>ALL MARKET — публичный сайт (https://test.food-market.kz)</h1>
|
||||
<div class="sub">Снято 2026-10-08 17:21 · проверка после выкладки свежих скриншотов</div></header>
|
||||
<div class="sub">Снято 2026-10-08 18:04 · проверка после выкладки свежих скриншотов</div></header>
|
||||
<div class="grid">
|
||||
<div class="card"><h2>Главная<a href="https://test.food-market.kz/" target="_blank">/ ↗</a></h2><div class="thumb"><img src="pages/index.png" alt="Главная"></div></div>
|
||||
<div class="card"><h2>Касса для Windows<a href="https://test.food-market.kz/pos" target="_blank">/pos ↗</a></h2><div class="thumb"><img src="pages/pos.png" alt="Касса для Windows"></div></div>
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.7 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 967 KiB After Width: | Height: | Size: 940 KiB |
|
|
@ -4,17 +4,34 @@
|
|||
самой программы (не только скриншотов).
|
||||
|
||||
## План / статус
|
||||
1. [ ] Английские строки в админке: «Dashboard», «Low-stock alerts», «live» и др. —
|
||||
перевести; grep по web/src на видимые латинские строки; лингва-проверка в menu-walk.
|
||||
2. [ ] Каталог: дубль «Все товары» (корень дерева + системная группа). Убрать дубль.
|
||||
3. [ ] Валюта: везде «₸» и формат «1 300 ₸» (сейчас розничная — «510 KZT»).
|
||||
4. [ ] Касса на сайте: заменить рендер HTML-макета на НАСТОЯЩИЙ экран Avalonia-кассы
|
||||
(--screenshots, витринные данные «Магазин у дома», с логотипом). Макет не использовать.
|
||||
5. [ ] Витрина: packaging по товарам (Авокадо 1шт — штучный, Бешбармак 1кг — весовой и т.п.).
|
||||
6. [ ] Выложить сайт+стенд, переснять затронутые скриншоты, посмотреть каждый кадр.
|
||||
1. [x] Английские строки в админке → русский. ru.json: `dashboard.title` «Dashboard»→
|
||||
«Сводка», `common.live/offline` «live/offline»→«онлайн/офлайн». Дашборд-виджеты:
|
||||
defaultValue «Low-stock alerts»→«Низкий остаток», «Live-обновление»→«Обновляется в
|
||||
реальном времени». Grep по web/src — других видимых латинских UI-строк нет (бренды/
|
||||
единицы — ок). Тест: лингва-проверка в `stage-ui-menu-walk.spec.ts` (denylist UI-English
|
||||
на видимом тексте каждой страницы, бренды/единицы не ловятся).
|
||||
2. [x] Каталог: системная группа «Все товары» больше не дублирует корень дерева.
|
||||
`ProductGroupDto.IsSystem` + `ProductGroupTree` прячет системные группы (корень «Все
|
||||
товары» = все товары, по модели МойСклада). Группа остаётся в справочнике (дефолт для
|
||||
товаров без группы) — фильтры/импорт/карточка не ломаются.
|
||||
3. [x] Валюта: розничная цена в каталоге теперь «₸» (символ), а не «KZT» (код). Формат
|
||||
«1 300 ₸» как у себестоимости.
|
||||
4. [x] Касса на сайте: HTML-макет заменён НАСТОЯЩИМ экраном Avalonia-кассы (--screenshots):
|
||||
продажа (04-sale-items) и оплата (05-payment-cash) с логотипом, витринные данные
|
||||
«Магазин у дома», кассир Виктория Ким. Убран префикс «Магазин » в шапке кассы (не было
|
||||
«Магазин Магазин у дома»). HTML-макет удалён из публичного пайплайна.
|
||||
5. [x] Витрина: фасовка/единица выводится из названия (кг→весовой/кг, иначе штучный/штука).
|
||||
Проверено API: Авокадо 1шт→штучный, Бешбармак 1кг→весовой, Кола 0.5л→штучный.
|
||||
6. [x] Выложено: стенд (api+web) + витрина пересеяна (RESET) + публичный сайт. Пересняты
|
||||
затронутые экраны, пережаты в WebP (≤300 КБ). Просмотрено глазами: дашборд «Сводка»/
|
||||
«онлайн»/«Низкий остаток»; каталог ₸/один «Все товары»/корректная фасовка; /pos —
|
||||
настоящая касса с логотипом. Галерея `docs/site-screenshots/index.html`.
|
||||
|
||||
## Что НЕ трогаем
|
||||
Прод, shared-postgres, global.json, gateway nginx, sklad.
|
||||
|
||||
## Журнал
|
||||
- 08.10 — старт: план, разбор замечаний.
|
||||
- 08.10 — код: ru.json + виджеты (1), ProductGroupDto.IsSystem + tree (2), ₸ в каталоге (3),
|
||||
ShowcaseSeeder packaging из названия (5), реальная Avalonia-касса + шапка (4), лингва-тест.
|
||||
- 08.10 — деплой api+web, RESET-пересев витрины, пересъёмка экранов, деплой сайта, галерея.
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@
|
|||
"orgTitle": "Настройки организации",
|
||||
"orgDescription": "Страна, валюта, ставка НДС по умолчанию.",
|
||||
"telegramTitle": "📨 Telegram владельца",
|
||||
"telegramDescription": "Ежедневная сводка (выручка вчера, топ-3 товара, low-stock) в 09:00 МСК.",
|
||||
"telegramDescription": "Ежедневная сводка (выручка вчера, топ-3 товара, низкий остаток) в 09:00 МСК.",
|
||||
"telegramBotDisabled": "Бот не настроен на сервере (нет токена в env). Привязка пока недоступна.",
|
||||
"telegramBound": "Привязан: chat_id={{id}}",
|
||||
"telegramUnbind": "Отвязать",
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ function TelegramSection() {
|
|||
<section className="border-t border-slate-200 dark:border-slate-800 pt-6 mt-6">
|
||||
<h2 className="text-base font-semibold">📨 Telegram владельца</h2>
|
||||
<p className="text-sm text-slate-500 dark:text-slate-400 mt-1">
|
||||
Ежедневная сводка (выручка вчера, топ-3 товара, low-stock) в 09:00 МСК.
|
||||
Ежедневная сводка (выручка вчера, топ-3 товара, низкий остаток) в 09:00 МСК.
|
||||
</p>
|
||||
|
||||
{!s?.botEnabled && (
|
||||
|
|
|
|||
|
|
@ -94,6 +94,32 @@ async function assertNoErrorToasts(page: Page, where: string) {
|
|||
}
|
||||
}
|
||||
|
||||
// Лингва-проверка: в видимом тексте страницы не должно быть непереведённого
|
||||
// UI-английского. Проверяем узкий denylist именно «хромовых» строк интерфейса
|
||||
// (заголовок/виджет/статус), а НЕ «любое латинское слово» — иначе ловили бы
|
||||
// легитимные бренды товаров (Lay's, Snickers, Kaspi), единицы, названия клавиш
|
||||
// (Delete/Enter/Esc) и технические идентификаторы в доке. Denylist ловит класс
|
||||
// регрессий «забыли перевести строку интерфейса».
|
||||
const UI_ENGLISH_DENY: RegExp[] = [
|
||||
/\bDashboard\b/, // заголовок страницы (должно быть «Сводка»)
|
||||
/Low-stock alerts/i, // заголовок виджета (должно быть «Низкий остаток»)
|
||||
/Live-обновл/, // латинское «Live» в русской строке
|
||||
/\blive\b/, /\boffline\b/, // статус-чип (должно быть «онлайн»/«офлайн»)
|
||||
]
|
||||
// Документация/диагностика содержат названия клавиш, код-идентификаторы и
|
||||
// технические термины — там латиница легитимна, лингва-проверку не применяем.
|
||||
const LINGUA_SKIP = ['/help', '/whats-new', '/admin/diagnostic']
|
||||
async function assertNoUiEnglish(page: Page, where: string, href: string) {
|
||||
if (LINGUA_SKIP.some((p) => href.startsWith(p))) return
|
||||
const bodyText = await page.locator('body').innerText()
|
||||
const hits = UI_ENGLISH_DENY
|
||||
.map((re) => bodyText.match(re)?.[0])
|
||||
.filter((x): x is string => !!x)
|
||||
if (hits.length > 0) {
|
||||
throw new Error(`Непереведённый UI-английский на ${where}: ${[...new Set(hits)].join(', ')}`)
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
test.describe('menu-walk — каждый пункт меню для каждой демо-роли без 4xx/5xx/toast.error/console.error', () => {
|
||||
|
|
@ -131,6 +157,7 @@ test.describe('menu-walk — каждый пункт меню для каждо
|
|||
const bodyText = await page.locator('body').innerText()
|
||||
expect(bodyText.length, `body на ${where}`).toBeGreaterThan(MIN_BODY_LEN)
|
||||
await assertNoErrorToasts(page, where)
|
||||
await assertNoUiEnglish(page, where, href)
|
||||
|
||||
// Теперь — reload (F5): это тот сценарий, где владелец словил 403-тосты.
|
||||
await page.reload({ waitUntil: 'domcontentloaded' })
|
||||
|
|
|
|||
Loading…
Reference in a new issue