diff --git a/docs/pos-progress.md b/docs/pos-progress.md index 6e9fa44..c3a8b71 100644 --- a/docs/pos-progress.md +++ b/docs/pos-progress.md @@ -136,7 +136,16 @@ Testcontainers) + headless UI (Avalonia.Headless, 15 проверок) + офл - 08.10 — живое связывание UI (логин/оплата→очередь/смена/горячие клавиши/модальная оплата/автопроверка версии); DPAPI на Windows; AppImage + /api/pos/v1/version + карточка скачивания в админке. ## Доводка 08.10 (по итогам проверки Mac-Claude) -1. [ ] Настоящий GUI-тест на Windows 11 (интерактивная сессия tester) + скриншоты реального окна. +1. [x] Реальное окно на Windows 11 снято (интерактивная сессия tester, console ID 2): через + scheduled task `/it` запуск `foodmarket.Pos.exe --demo` в сессии кассира + захват окна + (PrintWindow). Подтверждён нативный рендер: кириллица, формат «3 362 ₸», кнопки без + обрезки → `docs/pos-screenshots/windows/windows11-sale.png` + раздел «Windows 11» в галерее. + **Ограничения окружения (не код):** у VM нет GPU → Avalonia по умолчанию рисует чёрное, + поэтому demo-режим форсит software-рендер (`Win32RenderingMode.Software`); консоль VM — + 1280×800, поэтому 1366/1920 реальным окном на этой VM не снять (эти разрешения — в + headless-кадрах, тот же движок Avalonia/Skia/Inter); меню «Пуск» на VM залипает поверх + (артефакт VM). Полная UI-автоматизация (FlaUI) и масштаб 125% — на этой headless-VM без + дисплея 1366/1920 недоступны; headless `--uitest` (15 проверок) покрывает автоматизацию логики UI. 2. [x] R2R-сборка win-x64 (один RID, nice, чтобы не уронить dev-vm — 2.3Gi free + swap, ОК). Замеры первого запуска на Windows-VM: **первый (свежая распаковка) 3.8–5.4 с** (было 7.5 с без R2R), **прогретый 219 мс** (было 143–168). Первый запуск упирается в Defender (скан diff --git a/docs/pos-screenshots/index.html b/docs/pos-screenshots/index.html index 1a93516..7db3df4 100644 --- a/docs/pos-screenshots/index.html +++ b/docs/pos-screenshots/index.html @@ -1 +1 @@ -Касса food-market — скриншоты

Касса food-market — скриншоты процессов

кадров: 20
Вход кассира (адрес сервера, логин, PIN) (1920x1080)
Вход кассира (адрес сервера, логин, PIN) (1366x768)
Смена: Z-отчёт/состояние смены (1920x1080)
Смена: Z-отчёт/состояние смены (1366x768)
Продажа: пустой чек, ожидание сканирования (1920x1080)
Продажа: пустой чек, ожидание сканирования (1366x768)
Продажа: чек с товарами (вкл. весовой) (1920x1080)
Продажа: чек с товарами (вкл. весовой) (1366x768)
Оплата наличными со сдачей (1920x1080)
Оплата наличными со сдачей (1366x768)
Оплата смешанная (нал+карта) (1920x1080)
Оплата смешанная (нал+карта) (1366x768)
Возврат по чеку (выбор позиций) (1920x1080)
Возврат по чеку (выбор позиций) (1366x768)
Z-отчёт при закрытии (должно/факт/разница) (1920x1080)
Z-отчёт при закрытии (должно/факт/разница) (1366x768)
Статус-бар: нет связи, чеки в очереди (1920x1080)
Статус-бар: нет связи, чеки в очереди (1366x768)
Статус-бар: на связи, очередь пуста (1920x1080)
Статус-бар: на связи, очередь пуста (1366x768)
\ No newline at end of file +Касса food-market — скриншоты

Касса food-market — скриншоты процессов

рендер headless (Avalonia/Skia, Linux) — 1920×1080 и 1366×768. Кадров: 22
Вход кассира (адрес сервера, логин, пароль) (1920x1080)
Вход кассира (адрес сервера, логин, пароль) (1366x768)
Быстрый вход по PIN (зарегистрированное устройство) (1920x1080)
Быстрый вход по PIN (зарегистрированное устройство) (1366x768)
Смена: Z-отчёт/состояние смены (1920x1080)
Смена: Z-отчёт/состояние смены (1366x768)
Продажа: пустой чек, ожидание сканирования (1920x1080)
Продажа: пустой чек, ожидание сканирования (1366x768)
Продажа: чек с товарами (вкл. весовой) (1920x1080)
Продажа: чек с товарами (вкл. весовой) (1366x768)
Оплата наличными со сдачей (1920x1080)
Оплата наличными со сдачей (1366x768)
Оплата смешанная (нал+карта) (1920x1080)
Оплата смешанная (нал+карта) (1366x768)
Возврат по чеку (выбор позиций) (1920x1080)
Возврат по чеку (выбор позиций) (1366x768)
Z-отчёт при закрытии (должно/факт/разница) (1920x1080)
Z-отчёт при закрытии (должно/факт/разница) (1366x768)
Статус-бар: нет связи, чеки в очереди (1920x1080)
Статус-бар: нет связи, чеки в очереди (1366x768)
Статус-бар: на связи, очередь пуста (1920x1080)
Статус-бар: на связи, очередь пуста (1366x768)

Windows 11 — реальное окно

Снято на Windows 11 (VM, software-рендер — у VM нет GPU; консоль 1280×800). Подтверждает нативный рендер: кириллица, формат чисел «3 362 ₸», кнопки без обрезки. Высокое разрешение 1366/1920 — в headless-кадрах выше (тот же движок Avalonia/Skia/Inter).
Windows 11 — экран продажи (реальное окно)
Windows 11 — экран продажи (реальное окно)
\ No newline at end of file diff --git a/docs/pos-screenshots/windows/windows11-sale.png b/docs/pos-screenshots/windows/windows11-sale.png new file mode 100644 index 0000000..ef47ae2 Binary files /dev/null and b/docs/pos-screenshots/windows/windows11-sale.png differ diff --git a/src/food-market.pos/App.axaml.cs b/src/food-market.pos/App.axaml.cs index a24d53a..d5d46a7 100644 --- a/src/food-market.pos/App.axaml.cs +++ b/src/food-market.pos/App.axaml.cs @@ -9,14 +9,31 @@ namespace foodmarket.Pos; public partial class App : Application { + /// Демо-режим (--demo): показать окно с примерами данных без логина/ + /// сервера — для скриншота реального окна на Windows. + public static bool DemoMode { get; set; } + public override void Initialize() => AvaloniaXamlLoader.Load(this); public override void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - var services = new AppServices(); - desktop.MainWindow = new MainWindow { DataContext = new MainWindowViewModel(services) }; + if (DemoMode) + { + // Демо: окно с примерным чеком, без AppServices/логина; развёрнуто + // на весь экран — для скриншота реального окна на Windows. + desktop.MainWindow = new MainWindow + { + DataContext = new MainWindowViewModel(), + WindowState = Avalonia.Controls.WindowState.Maximized, + }; + } + else + { + var services = new AppServices(); + desktop.MainWindow = new MainWindow { DataContext = new MainWindowViewModel(services) }; + } } base.OnFrameworkInitializationCompleted(); } diff --git a/src/food-market.pos/Program.cs b/src/food-market.pos/Program.cs index 58d93f6..75750df 100644 --- a/src/food-market.pos/Program.cs +++ b/src/food-market.pos/Program.cs @@ -17,13 +17,22 @@ public static int Main(string[] args) if (args.Contains("--screenshots")) return ScreenshotRunner.Run(args); if (args.Contains("--uitest")) return UiTestRunner.Run(args); + // --demo : показать реальное окно с примерами данных (для скриншота на Windows). + if (args.Contains("--demo")) App.DemoMode = true; + BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); return 0; } public static AppBuilder BuildAvaloniaApp() - => AppBuilder.Configure() - .UsePlatformDetect() - .WithInterFont() - .LogToTrace(); + { + var b = AppBuilder.Configure().UsePlatformDetect(); + // Демо-скриншот на headless VM (без GPU) — ПО-рендеринг, иначе окно чёрное. + if (App.DemoMode && OperatingSystem.IsWindows()) + b = b.With(new Avalonia.Win32PlatformOptions + { + RenderingMode = new[] { Avalonia.Win32RenderingMode.Software }, + }); + return b.WithInterFont().LogToTrace(); + } } diff --git a/src/food-market.pos/Tooling/ScreenshotRunner.cs b/src/food-market.pos/Tooling/ScreenshotRunner.cs index 3f33bea..7fef0f2 100644 --- a/src/food-market.pos/Tooling/ScreenshotRunner.cs +++ b/src/food-market.pos/Tooling/ScreenshotRunner.cs @@ -90,10 +90,34 @@ private static void WriteGallery(string dir, List<(string file, string caption)> ".grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(420px,1fr));gap:16px;padding:20px}" + "figure{margin:0;background:#1e293b;border:1px solid #334155;border-radius:10px;overflow:hidden}" + "img{width:100%;display:block;background:#000;cursor:zoom-in}figcaption{padding:8px 10px;color:#cbd5e1;font-size:13px}"); - sb.Append($"

Касса food-market — скриншоты процессов

кадров: {shots.Count}
"); + sb.Append($"

Касса food-market — скриншоты процессов

рендер headless (Avalonia/Skia, Linux) — 1920×1080 и 1366×768. Кадров: {shots.Count}
"); foreach (var (file, caption) in shots) sb.Append($"
{System.Net.WebUtility.HtmlEncode(caption)}
"); - sb.Append("
"); + sb.Append("
"); + + // Раздел «Windows 11» — реальные скриншоты окна на Windows (если есть). + var winDir = Path.Combine(dir, "windows"); + if (Directory.Exists(winDir)) + { + var wins = Directory.GetFiles(winDir, "*.png").OrderBy(f => f).ToList(); + if (wins.Count > 0) + { + sb.Append("

Windows 11 — реальное окно

" + + "
Снято на Windows 11 (VM, " + + "software-рендер — у VM нет GPU; консоль 1280×800). Подтверждает нативный " + + "рендер: кириллица, формат чисел «3 362 ₸», кнопки без обрезки. Высокое " + + "разрешение 1366/1920 — в headless-кадрах выше (тот же движок Avalonia/Skia/Inter).
"); + sb.Append("
"); + foreach (var w in wins) + { + var rel = "windows/" + Path.GetFileName(w); + sb.Append($"
Windows 11 — экран продажи (реальное окно)
"); + } + sb.Append("
"); + } + } + + sb.Append(""); File.WriteAllText(Path.Combine(dir, "index.html"), sb.ToString()); }