chore: скрипт скриншотов 390/1440 для критика (Playwright), журнал ошибок ИИ
This commit is contained in:
@@ -23,3 +23,4 @@
|
|||||||
| 17 | Шаг 5, прод | `TRUSTED_PROXIES=172.31.120.1` не срабатывал: Node отдаёт адрес сокета как `::ffff:172.31.120.1`, и все посетители снова делили один лимит. Тесты этого не ловили — в них адреса без префикса | Проверка на проде: 6 запросов с X-Real-IP «A», затем «B» получил 429 | Нормализация IPv4-mapped адресов + тест; на сервере проверено пробным контейнером |
|
| 17 | Шаг 5, прод | `TRUSTED_PROXIES=172.31.120.1` не срабатывал: Node отдаёт адрес сокета как `::ffff:172.31.120.1`, и все посетители снова делили один лимит. Тесты этого не ловили — в них адреса без префикса | Проверка на проде: 6 запросов с X-Real-IP «A», затем «B» получил 429 | Нормализация IPv4-mapped адресов + тест; на сервере проверено пробным контейнером |
|
||||||
| 18 | План, Telegram | План исходил из того, что VPS ходит в api.telegram.org напрямую; не проверил — с сервера в РФ Telegram недоступен (таймаут), бот не получил `/setup` | Тишина после `/setup` автора, затем проверка `fetch` из контейнера | Ретранслятор Bot API на домашнем сервере (`deploy/tg-relay`) по Tailscale + `TELEGRAM_API_BASE` |
|
| 18 | План, Telegram | План исходил из того, что VPS ходит в api.telegram.org напрямую; не проверил — с сервера в РФ Telegram недоступен (таймаут), бот не получил `/setup` | Тишина после `/setup` автора, затем проверка `fetch` из контейнера | Ретранслятор Bot API на домашнем сервере (`deploy/tg-relay`) по Tailscale + `TELEGRAM_API_BASE` |
|
||||||
| 19 | Шаг 9, бот | Сетевые ошибки `getUpdates` молча повторялись без единой строки в логе — недоступность Telegram была невидима | Пустой `docker logs` при неработающем боте | Предупреждение в лог раз в 10 минут |
|
| 19 | Шаг 9, бот | Сетевые ошибки `getUpdates` молча повторялись без единой строки в логе — недоступность Telegram была невидима | Пустой `docker logs` при неработающем боте | Предупреждение в лог раз в 10 минут |
|
||||||
|
| 20 | Оркестрация | Оркестратор закоммитил ретранслятор через `git add -A` в том же чекауте, где дизайнер вёл незакоммиченную вёрстку шага 12 — почти весь шаг 12 уехал в коммит `20db25b` «ретранслятор Bot API», а на прод выкатилась половина вёрстки | Отчёт дизайнера | Впредь — `git add` по путям и отдельный worktree для параллельных агентов |
|
||||||
|
|||||||
+4
-1
@@ -3,7 +3,9 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"packageManager": "pnpm@11.22.0",
|
"packageManager": "pnpm@11.22.0",
|
||||||
"engines": { "node": ">=22" },
|
"engines": {
|
||||||
|
"node": ">=22"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "pnpm -r --parallel dev",
|
"dev": "pnpm -r --parallel dev",
|
||||||
"build": "pnpm -r build",
|
"build": "pnpm -r build",
|
||||||
@@ -13,6 +15,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^26.6.5",
|
"@types/node": "^26.6.5",
|
||||||
|
"playwright": "^1.64.1",
|
||||||
"typescript": "~6.0.3",
|
"typescript": "~6.0.3",
|
||||||
"vitest": "^5.0.5"
|
"vitest": "^5.0.5"
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+19
@@ -11,6 +11,9 @@ importers:
|
|||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^26.6.5
|
specifier: ^26.6.5
|
||||||
version: 26.6.5
|
version: 26.6.5
|
||||||
|
playwright:
|
||||||
|
specifier: ^1.64.1
|
||||||
|
version: 1.64.1
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ~6.0.3
|
specifier: ~6.0.3
|
||||||
version: 6.0.3
|
version: 6.0.3
|
||||||
@@ -2343,6 +2346,16 @@ packages:
|
|||||||
pkg-types@1.3.1:
|
pkg-types@1.3.1:
|
||||||
resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
|
resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
|
||||||
|
|
||||||
|
playwright-core@1.64.1:
|
||||||
|
resolution: {integrity: sha512-BC4s8y6SEVA6Q1rSxZTto8hI1KUI3xXlHGZgvGqP4IqPdI/a6FX9H29IDNz7vKo9l21b6LfYosScPL6M3xxyDQ==}
|
||||||
|
engines: {node: '>=20'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
|
playwright@1.64.1:
|
||||||
|
resolution: {integrity: sha512-HCrVhHr5QQuwYoswEUGTb7gGp522yflbv/ST8nF4sFWGuLjQCt17Q/EubpGGSNKYn1tsTCPZxqHhHCfVURu7UA==}
|
||||||
|
engines: {node: '>=20'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
possible-typed-array-names@1.1.0:
|
possible-typed-array-names@1.1.0:
|
||||||
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
|
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -4969,6 +4982,12 @@ snapshots:
|
|||||||
mlly: 1.8.2
|
mlly: 1.8.2
|
||||||
pathe: 2.0.3
|
pathe: 2.0.3
|
||||||
|
|
||||||
|
playwright-core@1.64.1: {}
|
||||||
|
|
||||||
|
playwright@1.64.1:
|
||||||
|
dependencies:
|
||||||
|
playwright-core: 1.64.1
|
||||||
|
|
||||||
possible-typed-array-names@1.1.0: {}
|
possible-typed-array-names@1.1.0: {}
|
||||||
|
|
||||||
postcss-load-config@6.0.1(jiti@2.7.0)(postcss@8.5.30)(tsx@4.23.15):
|
postcss-load-config@6.0.1(jiti@2.7.0)(postcss@8.5.30)(tsx@4.23.15):
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// Скриншоты для критика: полная страница и первый экран на 390 и 1440.
|
||||||
|
// node scripts/screenshots.mjs <url> <каталог>
|
||||||
|
// Анимации доигрываются: страница прокручивается до низа, чтобы сработали IntersectionObserver.
|
||||||
|
import { mkdir } from 'node:fs/promises';
|
||||||
|
import { chromium } from 'playwright';
|
||||||
|
|
||||||
|
const [url = 'http://127.0.0.1:3000/', outDir = '.screenshots/critic'] = process.argv.slice(2);
|
||||||
|
await mkdir(outDir, { recursive: true });
|
||||||
|
|
||||||
|
const browser = await chromium.launch();
|
||||||
|
for (const width of [390, 1440]) {
|
||||||
|
const page = await browser.newPage({
|
||||||
|
viewport: { width, height: width === 390 ? 844 : 900 },
|
||||||
|
deviceScaleFactor: width === 390 ? 2 : 1,
|
||||||
|
});
|
||||||
|
await page.goto(url, { waitUntil: 'networkidle' });
|
||||||
|
await page.screenshot({ path: `${outDir}/${width}-fold.png` });
|
||||||
|
for (let y = 0; y < (await page.evaluate(() => document.body.scrollHeight)); y += 400) {
|
||||||
|
await page.evaluate((top) => window.scrollTo(0, top), y);
|
||||||
|
await page.waitForTimeout(120);
|
||||||
|
}
|
||||||
|
await page.waitForTimeout(800);
|
||||||
|
await page.evaluate(() => window.scrollTo(0, 0));
|
||||||
|
await page.screenshot({ path: `${outDir}/${width}-full.png`, fullPage: true });
|
||||||
|
const overflow = await page.evaluate(() => document.documentElement.scrollWidth - window.innerWidth);
|
||||||
|
console.log(`${width}: ${outDir}/${width}-full.png, горизонтальный выход за экран ${overflow}px`);
|
||||||
|
await page.close();
|
||||||
|
}
|
||||||
|
await browser.close();
|
||||||
Reference in New Issue
Block a user