const assert = require('node:assert/strict') const fs = require('node:fs') 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 origin = process.env.VERIFY_FRONTEND_ORIGIN || 'https://agent.pducv.cn' const checks = [], failures = [] let browser const check = (name, result) => { checks.push({name, passed: !!result}); assert.ok(result, name) } async function main() { const credentials = JSON.parse(fs.readFileSync(`${directory}/super-admin-login.json`, 'utf8')) const response = await fetch(`${origin}/api/v1/auth/login`, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({email: credentials.email, password: credentials.password}), signal: AbortSignal.timeout(30000), }) assert.equal(response.status, 200) const auth = 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: String(a.user.tenant_id)}), 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') }, auth) const page = await context.newPage(), errors = [], writes = [] page.on('pageerror', e => errors.push(e.name)) page.on('request', request => { if (request.method() === 'POST') writes.push(new URL(request.url()).pathname) }) await page.goto(`${origin}/platform/agents`) await page.getByRole('button', {name: 'AI 创建', exact: true}).waitFor() await page.getByRole('button', {name: '手动创建', exact: true}).click() await page.locator('.settings-modal').waitFor() check('manual_creation_opens_editor_without_ai', !writes.includes('/api/v1/agents/draft')) await page.screenshot({path: `${directory}/public-agent-manual-desktop.png`, animations: 'disabled'}) await page.locator('.settings-modal .close-btn').click() await page.locator('.settings-modal').waitFor({state: 'hidden'}) await page.getByRole('button', {name: 'AI 创建', exact: true}).click() const dialog = page.locator('.t-dialog').filter({hasText: 'AI 创建 Agent'}) await dialog.locator('textarea').fill('创建一个课程规划 Agent,面向新学员整理连续课程框架,每天衔接前一天的核心概念,并检查主题重复。只生成配置草稿。') const generate = dialog.getByRole('button', {name: '生成配置', exact: true}) await page.setViewportSize({width: 390, height: 844}) const draftResponse = page.waitForResponse(r => new URL(r.url()).pathname === '/api/v1/agents/draft', {timeout: 120000}) await generate.click() await dialog.locator('progress').waitFor() check('ai_draft_has_visible_progress', await dialog.locator('progress').isVisible()) await page.screenshot({path: `${directory}/public-agent-ai-progress-mobile.png`, animations: 'disabled'}) check('ai_dialog_mobile_has_no_horizontal_overflow', await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth + 2)) const result = await draftResponse check(`configured_model_generates_real_draft_http_${result.status()}`, result.status() === 200) const draft = (await result.json()).data check('draft_has_no_persisted_resource_id', !!draft?.name && !draft.id) await page.locator('.settings-modal').waitFor() const name = page.locator('[data-guide="agent-create-name"] input') await name.waitFor() await page.waitForFunction(expected => document.querySelector('[data-guide="agent-create-name"] input')?.value === expected, draft.name) check('generated_draft_is_editable_before_saving', await name.inputValue() === draft.name && await name.isEditable()) await page.screenshot({path: `${directory}/public-agent-ai-draft-mobile.png`, animations: 'disabled'}) await page.setViewportSize({width: 1440, height: 1000}) await page.screenshot({path: `${directory}/public-agent-ai-draft-desktop.png`, animations: 'disabled'}) check('ai_draft_does_not_auto_create_agent', !writes.includes('/api/v1/agents')) check('agent_creation_has_no_javascript_errors', errors.length === 0) } main().catch(error => {failures.push(error.message); process.exitCode = 1}).finally(async () => { if (browser) await browser.close() const report = {checked_at: new Date().toISOString(), origin, checks, failures, passed: failures.length === 0} fs.writeFileSync(`${directory}/public-agent-creation.json`, JSON.stringify(report, null, 2)) console.log(JSON.stringify(report)) })