const fs = require('node:fs') const assert = require('node:assert/strict') const { chromium } = require('/Users/macclaw/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright') const directory = '/Volumes/Extreme SSD/yawan-storage/weknora/acceptance' const checks = [] let browser async function main() { const fixture = JSON.parse(fs.readFileSync(`${directory}/upload-ui-fixture.json`, 'utf8')) const response = await fetch('http://127.0.0.1:18080/api/v1/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: fixture.email, password: 'UploadAcceptance!20260917' }) }) assert.equal(response.status, 200) const identity = await response.json() browser = await chromium.launch({ headless: true, channel: 'chrome' }) const context = await browser.newContext({ viewport: { width: 1440, height: 1000 } }) await context.addInitScript(a => { const values = { weknora_user: JSON.stringify({ ...a.user, tenant_id: '10059' }), weknora_tenant: JSON.stringify({ ...a.active_tenant, id: '10059' }), weknora_token: a.token, weknora_refresh_token: a.refresh_token, weknora_memberships: JSON.stringify(a.memberships) } for (const [key, value] of Object.entries(values)) localStorage.setItem(key, value) localStorage.setItem('weknora:new-user-guide-done:v1', '1') }, identity) const page = await context.newPage(), errors = [] page.on('pageerror', error => errors.push(error.message)) await page.goto('http://127.0.0.1:15173/platform/knowledge-bases') const launcher = page.getByRole('button', { name: '文件上传与解析', exact: true }) await launcher.waitFor() await launcher.click() await page.locator('.upload-row').first().waitFor() assert.ok(await page.getByText('处理完成', { exact: true }).count()) checks.push({ name: 'completed_upload_persists_after_fresh_browser', passed: true }) await page.screenshot({ path: `${directory}/resumable-ui-desktop.png`, animations: 'disabled' }) await page.reload() await launcher.waitFor(); await launcher.click(); await page.locator('.upload-row').first().waitFor() checks.push({ name: 'upload_drawer_restores_after_reload', passed: true }) await page.setViewportSize({ width: 390, height: 844 }) await page.screenshot({ path: `${directory}/resumable-ui-mobile.png`, animations: 'disabled' }) assert.ok(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth + 2)) const bounds = await page.locator('.upload-heading').first().boundingBox() assert.ok(bounds && bounds.x >= 0 && bounds.x + bounds.width <= 392) checks.push({ name: 'mobile_upload_content_fits', passed: true }) await page.screenshot({ path: `${directory}/resumable-ui-mobile.png`, animations: 'disabled' }) await page.keyboard.press('Escape') await page.locator('.upload-list').waitFor({ state: 'hidden' }) checks.push({ name: 'drawer_dismisses_with_escape', passed: true }) assert.equal(errors.length, 0, errors.join('; ')) checks.push({ name: 'upload_browser_has_no_page_errors', passed: true }) } main().catch(error => { checks.push({ name: 'failure', message: error.message }); console.error(error.message); process.exitCode = 1 }).finally(async () => { await browser?.close() fs.writeFileSync(`${directory}/resumable-ui-verification.json`, JSON.stringify({ checks, finished_at: new Date().toISOString() }, null, 2)) console.log(JSON.stringify(checks)) })