food-market/tests/e2e/scripts/screenshot-confirm-dialog.ts
nns c201625b2b
Some checks are pending
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
docs(sprint7): пункт 2 ✓ + screenshot script
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 10:46:52 +05:00

83 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Sprint 7 item 2 — визуальная проверка ConfirmDialog на стейдже.
* Логинимся под demo-orgом, открываем карточку любого товара, жмём
* «Удалить», скриншот, отмена → проверяем что товар не удалился.
*
* Запуск: cd tests/e2e && pnpm exec tsx scripts/screenshot-confirm-dialog.ts
* Env: E2E_ADMIN_URL (default https://test.admin.food-market.kz),
* E2E_EMAIL / E2E_PASSWORD (если нет — создаст временный signup +
* запустит seed демо-данных).
*/
import { chromium } from 'playwright'
import { makeClient, login } from '../lib/api.js'
const BASE = process.env.E2E_ADMIN_URL ?? 'https://test.admin.food-market.kz'
const TS = Date.now()
const EMAIL = process.env.E2E_EMAIL ?? `confirm-shot-${TS}@food-market.local`
const PASS = process.env.E2E_PASSWORD ?? 'ConfirmShot12345!'
async function ensureSession() {
const api = makeClient()
// если signup провалится 409 — значит юзер уже есть, просто залогинимся
const r = await api.post('/api/auth/signup', {
email: EMAIL, password: PASS,
organizationName: `ConfirmShot ${TS}`, phone: '+77011190001', plan: 'start',
})
if (r.status !== 200 && r.status !== 409) {
throw new Error(`signup ${r.status}: ${JSON.stringify(r.data)}`)
}
const sess = await login(EMAIL, PASS)
// Seed демо-данных — нам нужен хотя бы один товар, чтобы зайти в edit.
const seed = makeClient(sess.accessToken)
await seed.post('/api/admin/seed-demo', {})
return sess
}
async function main() {
const sess = await ensureSession()
console.log(`[shot] session ok email=${sess.email}`)
const browser = await chromium.launch({ headless: true })
const ctx = await browser.newContext({
ignoreHTTPSErrors: true,
viewport: { width: 1280, height: 800 },
})
const page = await ctx.newPage()
// Авто-логин через токен: положим в localStorage то, что ожидает web
// (web использует ключ fm.access_token, см. src/lib/auth.ts).
await page.goto(`${BASE}/`)
await page.evaluate(({ token }) => {
localStorage.setItem('fm.access_token', token)
}, { token: sess.accessToken })
await page.goto(`${BASE}/catalog/products`, { waitUntil: 'domcontentloaded' })
await page.waitForLoadState('networkidle')
await page.screenshot({ path: `reports/confirm-list-${TS}.png`, fullPage: false })
// Ждём первую строку таблицы товаров
await page.locator('tbody tr').first().waitFor({ timeout: 15000 })
await page.locator('tbody tr').first().click()
await page.waitForLoadState('networkidle')
// Кнопка «Удалить» — danger variant в правом верхнем углу
const deleteBtn = page.getByRole('button', { name: /удалить/i }).first()
await deleteBtn.click()
// Ждём появления нашего диалога
await page.waitForSelector('[aria-labelledby="confirm-dialog-title"]', { timeout: 5000 })
const outDir = 'reports'
await page.screenshot({ path: `${outDir}/confirm-dialog-${TS}.png`, fullPage: false })
console.log(`[shot] saved → ${outDir}/confirm-dialog-${TS}.png`)
// Проверка: Esc закрывает (NOT удаляет)
await page.keyboard.press('Escape')
await page.waitForTimeout(300)
const stillOpen = await page.locator('[aria-labelledby="confirm-dialog-title"]').count()
console.log(`[shot] dialog closed after Esc: ${stillOpen === 0 ? '✓' : '✗ STILL OPEN'}`)
await browser.close()
}
main().catch(err => { console.error(err); process.exit(1) })