83 lines
3.7 KiB
TypeScript
83 lines
3.7 KiB
TypeScript
/**
|
||
* 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) })
|