screen-sync «retries the resource with GET…». Тест полагал, что первый 503 сразу переводит query в error. На самом деле fetchAppRead сам повторяет transient GET (1 s + 2 s). waitFor(gets === 1) срабатывал, пока запрос ещё шёл, и retry() ничего не делал (isError=false). Дальше всё зависело от того, успеет ли внутренний retry транспорта вернуть 200 до таймаута waitFor (1 s по умолчанию). Под нагрузкой не успевал, отсюда expected undefined to deeply equal [].
Исправление: fake timers прогоняют back-off транспорта, тест ждёт transportError === true, затем вызывает ручной retry и проверяет ровно один дополнительный GET. Проверки стали строже: точное число запросов, все без sync.
Новый случай, найден при воспроизведении: AppRoutes «offers a retry…».RouteTransition анимирует opacity 0→1 за 0.2 s. findByRole находил заголовок посреди анимации (зафиксировано opacity: 0.18), и toBeVisible падал (2 из 3 полных прогонов под нагрузкой).
Исправление: MotionGlobalConfig.skipAnimations = true в unit setup. Продуктовое поведение и проверки не меняются.
OperationForm / StockPage. Не воспроизвелись: при нагрузке до 40 процессов yes на 10 ядрах около 10 полных прогонов зелёные. Гипотеза про локаль не подтвердилась: при LANG=C, en_NZ, TZ=Pacific/Auckland тесты зелёные, потому что форматирование идёт через явную ru-локаль i18n. Причина не установлена, под эти два теста код не менялся. Если они упадут снова, нужен полный лог.
Проверка
До фикса: полный vitest run --project unit под CPU-нагрузкой → 1 failed (screen-sync); затем 1 failed (AppRoutes) в 2 из 3 прогонов.
После фикса: 6 полных прогонов подряд под нагрузкой из 40 процессов → 576 passed каждый; screen-sync отдельно 3/3.
npm run verify → exit 0. Node 24.22.1.
Ограничения: AC про 10 прогонов закрыт частично (6 прогонов под нагрузкой и verify); причина для OperationForm/StockPage не установлена.
Closes #138.
## Причины
**screen-sync «retries the resource with GET…».** Тест полагал, что первый 503 сразу переводит query в error. На самом деле `fetchAppRead` сам повторяет transient GET (1 s + 2 s). `waitFor(gets === 1)` срабатывал, пока запрос ещё шёл, и `retry()` ничего не делал (`isError=false`). Дальше всё зависело от того, успеет ли внутренний retry транспорта вернуть 200 до таймаута `waitFor` (1 s по умолчанию). Под нагрузкой не успевал, отсюда `expected undefined to deeply equal []`.
Исправление: fake timers прогоняют back-off транспорта, тест ждёт `transportError === true`, затем вызывает ручной retry и проверяет ровно один дополнительный GET. Проверки стали строже: точное число запросов, все без `sync`.
**Новый случай, найден при воспроизведении: AppRoutes «offers a retry…».** `RouteTransition` анимирует opacity 0→1 за 0.2 s. `findByRole` находил заголовок посреди анимации (зафиксировано `opacity: 0.18`), и `toBeVisible` падал (2 из 3 полных прогонов под нагрузкой).
Исправление: `MotionGlobalConfig.skipAnimations = true` в unit setup. Продуктовое поведение и проверки не меняются.
**OperationForm / StockPage.** Не воспроизвелись: при нагрузке до 40 процессов `yes` на 10 ядрах около 10 полных прогонов зелёные. Гипотеза про локаль не подтвердилась: при `LANG=C`, `en_NZ`, `TZ=Pacific/Auckland` тесты зелёные, потому что форматирование идёт через явную `ru`-локаль i18n. Причина не установлена, под эти два теста код не менялся. Если они упадут снова, нужен полный лог.
## Проверка
- До фикса: полный `vitest run --project unit` под CPU-нагрузкой → `1 failed` (screen-sync); затем `1 failed` (AppRoutes) в 2 из 3 прогонов.
- После фикса: 6 полных прогонов подряд под нагрузкой из 40 процессов → `576 passed` каждый; screen-sync отдельно 3/3.
- `npm run verify` → exit 0. Node 24.22.1.
Ограничения: AC про 10 прогонов закрыт частично (6 прогонов под нагрузкой и verify); причина для OperationForm/StockPage не установлена.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #138.
Причины
screen-sync «retries the resource with GET…». Тест полагал, что первый 503 сразу переводит query в error. На самом деле
fetchAppReadсам повторяет transient GET (1 s + 2 s).waitFor(gets === 1)срабатывал, пока запрос ещё шёл, иretry()ничего не делал (isError=false). Дальше всё зависело от того, успеет ли внутренний retry транспорта вернуть 200 до таймаутаwaitFor(1 s по умолчанию). Под нагрузкой не успевал, отсюдаexpected undefined to deeply equal [].Исправление: fake timers прогоняют back-off транспорта, тест ждёт
transportError === true, затем вызывает ручной retry и проверяет ровно один дополнительный GET. Проверки стали строже: точное число запросов, все безsync.Новый случай, найден при воспроизведении: AppRoutes «offers a retry…».
RouteTransitionанимирует opacity 0→1 за 0.2 s.findByRoleнаходил заголовок посреди анимации (зафиксированоopacity: 0.18), иtoBeVisibleпадал (2 из 3 полных прогонов под нагрузкой).Исправление:
MotionGlobalConfig.skipAnimations = trueв unit setup. Продуктовое поведение и проверки не меняются.OperationForm / StockPage. Не воспроизвелись: при нагрузке до 40 процессов
yesна 10 ядрах около 10 полных прогонов зелёные. Гипотеза про локаль не подтвердилась: приLANG=C,en_NZ,TZ=Pacific/Aucklandтесты зелёные, потому что форматирование идёт через явнуюru-локаль i18n. Причина не установлена, под эти два теста код не менялся. Если они упадут снова, нужен полный лог.Проверка
vitest run --project unitпод CPU-нагрузкой →1 failed(screen-sync); затем1 failed(AppRoutes) в 2 из 3 прогонов.576 passedкаждый; screen-sync отдельно 3/3.npm run verify→ exit 0. Node 24.22.1.Ограничения: AC про 10 прогонов закрыт частично (6 прогонов под нагрузкой и verify); причина для OperationForm/StockPage не установлена.