diff options
Diffstat (limited to 'frontend/scripts/browser-smoke.mjs')
| -rw-r--r-- | frontend/scripts/browser-smoke.mjs | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/frontend/scripts/browser-smoke.mjs b/frontend/scripts/browser-smoke.mjs new file mode 100644 index 0000000..6afc2f4 --- /dev/null +++ b/frontend/scripts/browser-smoke.mjs @@ -0,0 +1,49 @@ +/** + * Browser smoke for 策研 Strategy Lab frontend. + * Usage: PLAYWRIGHT_BROWSERS_PATH=... node scripts/browser-smoke.mjs [baseURL] + * Requires the Vite dev server (frontend/ npm run dev, /api proxying to backend). + */ +import { chromium } from 'playwright'; + +const base = process.argv[2] ?? 'http://127.0.0.1:8788'; + +const browser = await chromium.launch(); +const page = await browser.newPage(); +const pageErrors = []; +page.on('pageerror', (e) => pageErrors.push(String(e))); +page.on('response', (r) => { + if (r.status() >= 500) pageErrors.push(`${r.status} ${r.url()}`); +}); + +await page.goto(`${base}/#/login`, { waitUntil: 'networkidle' }); +const t1 = await page.evaluate(() => document.body.innerText); +if (!t1.includes('邮箱') || !t1.includes('登录')) throw new Error(`login page missing content: ${t1.slice(0, 100)}`); + +await page.goto(`${base}/#/register`, { waitUntil: 'networkidle' }); +if (!(await page.$('form'))) throw new Error('register form missing'); + +await page.goto(`${base}/#/reset`, { waitUntil: 'networkidle' }); +if ((await page.$$eval('input', (els) => els.length)) < 3) throw new Error('reset inputs missing'); + +// wrong password flow must NOT navigate to app, must render error banner +await page.goto(`${base}/#/login`, { waitUntil: 'networkidle' }); +await page.fill('#le', '[email protected]'); +await page.fill('#lp', 'wrong-password'); +await page.click('button[type="submit"]'); +await page.waitForTimeout(1200); +const t2 = await page.evaluate(() => document.body.innerText); +if (!t2.includes('不正确') && !t2.includes('HTTP') && !t2.includes('出错')) { + throw new Error(`expected visible login error, got: ${t2.slice(0, 160)}`); +} + +for (const h of ['projects', 'datasets', 'runs', 'usage', 'account', 'admin']) { + await page.goto(`${base}/#/${h}`, { waitUntil: 'networkidle' }); + const has = await page.evaluate(() => document.body.innerText.length > 50); + if (!has) throw new Error(`route ${h} rendered empty`); +} + +if (pageErrors.length > 0) { + throw new Error(`page errors: ${pageErrors.slice(0, 5).join('; ')}`); +} +console.log('BROWSER SMOKE OK', { pageErrors: pageErrors.length }); +await browser.close(); |
