const assert = require('node:assert/strict') const fs = require('node:fs') const path = require('node:path') const { pathToFileURL } = require('node:url') const { chromium } = require('/Users/macclaw/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright') async function main() { const directory = '/Volumes/Extreme SSD/yawan-storage/weknora/acceptance' const root = path.resolve(__dirname, '../frontend') const apiOrigin = process.env.VERIFY_API_ORIGIN || 'http://127.0.0.1:18080' const checks = [], requestedAssets = new Set(), unexpectedMutations = [], pageErrors = [] const reportPath = path.join(directory, 'lazy-platform-modals-20260919.json') const credentials = JSON.parse(fs.readFileSync(path.join(directory, 'super-admin-login.json'), 'utf8')) const login = await fetch(`${apiOrigin}/api/v1/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: credentials.email, password: credentials.password }), }) assert.equal(login.status, 200, 'Read-only verification login') const auth = await login.json() process.env.VITE_DEV_PROXY_TARGET = apiOrigin const { preview } = await import(pathToFileURL(path.join(root, 'node_modules/vite/dist/node/index.js')).href) const server = await preview({ root, configFile: path.join(root, 'vite.config.ts'), preview: { host: '127.0.0.1', port: 15174, strictPort: true } }) const origin = server.resolvedUrls.local[0].replace(/\/$/, '') let browser async function check(name, fn) { const started = Date.now() try { await fn() checks.push({ name, passed: true, duration_ms: Date.now() - started }) console.log(JSON.stringify(checks.at(-1))) } catch (error) { checks.push({ name, passed: false, duration_ms: Date.now() - started, error: error.name, location: error.stack?.split('\n').filter(line => line.trim().startsWith('at ')).slice(0, 3) }) console.log(JSON.stringify(checks.at(-1))) throw error } } try { 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) for (const key of ['weknora:new-user-guide-done:v1', 'weknora:contextual-guide-kb-list:v2', 'weknora:contextual-guide-kb-create:v3', 'weknora:contextual-guide-tenant-models:v1']) localStorage.setItem(key, '1') }, auth) await context.route('**/api/**', async route => { const request = route.request() if (!['GET', 'HEAD', 'OPTIONS'].includes(request.method())) { unexpectedMutations.push({ method: request.method(), path: new URL(request.url()).pathname }) return route.abort('blockedbyclient') } await route.continue() }) const page = await context.newPage() page.setDefaultTimeout(20000) page.on('pageerror', error => pageErrors.push({ name: error.name })) page.on('request', request => { const pathname = new URL(request.url()).pathname if (pathname.startsWith('/assets/')) requestedAssets.add(pathname) }) const editor = page.locator('.settings-overlay').filter({ has: page.locator('[data-guide="kb-editor-sidebar"]') }) const settings = page.locator('.settings-overlay').filter({ has: page.locator('[data-guide="settings-models"]') }) const nameInput = editor.locator('[data-guide="kb-create-name"] input') const create = async () => { await page.locator('[data-guide="kb-list-create"]').first().click() await nameInput.waitFor({ state: 'visible' }) } const closeEditor = async () => { await editor.locator('.close-btn').click() await editor.waitFor({ state: 'hidden' }) } await check('cold_knowledge_list_defers_hidden_modal_chunks', async () => { await page.goto(`${origin}/platform/knowledge-bases`) await page.locator('[data-guide="kb-list-create"]').first().waitFor({ state: 'visible' }) await page.waitForLoadState('networkidle') assert.equal([...requestedAssets].filter(asset => /\/(Settings|KnowledgeBaseEditorModal)-.*\.js$/.test(asset)).length, 0) }) await check('command_palette_keyboard_shortcut_remains_registered', async () => { await page.keyboard.press('Meta+k') await page.locator('.cmdk').waitFor({ state: 'visible' }) await page.keyboard.press('Escape') await page.locator('.cmdk').waitFor({ state: 'hidden' }) }) await check('first_create_initializes_and_only_loads_editor', async () => { await create() assert.equal(await nameInput.inputValue(), '') assert.ok([...requestedAssets].some(asset => /\/KnowledgeBaseEditorModal-.*\.js$/.test(asset))) assert.equal([...requestedAssets].filter(asset => /\/Settings-.*\.js$/.test(asset)).length, 0) }) await check('create_close_reopen_discards_unsaved_form', async () => { await nameInput.fill('UNSAVED_BROWSER_CHECK') await closeEditor() await create() assert.equal(await nameInput.inputValue(), '') }) async function openModelsSettings() { await editor.locator('[data-guide="kb-editor-nav-models"]').click() await editor.locator('[data-guide="kb-create-llm"] .model-selector').click() await page.locator('.add-model-option:visible').click() await settings.waitFor({ state: 'visible' }) } await check('lazy_settings_opens_models_from_editor', async () => { await openModelsSettings() assert.ok([...requestedAssets].some(asset => /\/Settings-.*\.js$/.test(asset))) assert.equal(await page.locator('.settings-overlay').count(), 2) }) await check('settings_escape_closes_and_reopens_without_losing_editor', async () => { await page.keyboard.press('Escape') await settings.waitFor({ state: 'hidden' }) assert.ok(await editor.isVisible()) await openModelsSettings() await settings.locator('.close-btn').click() await settings.waitFor({ state: 'hidden' }) await closeEditor() }) await check('existing_knowledge_editor_loads_and_reopens_correct_resource', async () => { const card = page.locator('.kb-card').filter({ has: page.locator('.more-wrap') }).first() await card.waitFor({ state: 'visible' }) const expectedName = await card.locator('.card-title').getAttribute('title') const edit = async () => { const settingsItem = page.locator('.card-more-popup:visible .popup-menu-item').filter({ has: page.locator('.t-icon-setting') }) if (!await settingsItem.isVisible()) await card.locator('.more-wrap').click() await settingsItem.click() await nameInput.waitFor({ state: 'visible' }) const actualName = await nameInput.inputValue() if (actualName !== expectedName) { console.log(JSON.stringify({ diagnostic: 'editor_name_mismatch', expected_length: expectedName?.length, actual_length: actualName.length, blank: !actualName, normalized_match: actualName.trim() === expectedName?.trim() })) } assert.equal(actualName, expectedName) } await edit() await nameInput.fill('UNSAVED_BROWSER_CHECK') await closeEditor() await edit() await closeEditor() }) await check('direct_settings_models_route_has_one_initialized_overlay', async () => { await page.goto(`${origin}/platform/settings?section=models`) await settings.waitFor({ state: 'visible' }) assert.equal(await page.locator('.settings-overlay').count(), 1) await page.waitForLoadState('networkidle') }) await check('no_browser_errors_or_business_mutations', async () => { assert.equal(pageErrors.length, 0) assert.equal(unexpectedMutations.length, 0) }) } finally { if (browser) await browser.close() await new Promise((resolve, reject) => server.httpServer.close(error => error ? reject(error) : resolve())) const report = { checked_at: new Date().toISOString(), origin, api_origin: apiOrigin, checks, passed: checks.length === 9 && checks.every(check => check.passed), requested_assets: [...requestedAssets], page_errors: pageErrors, unexpected_mutations: unexpectedMutations } fs.writeFileSync(reportPath, JSON.stringify(report, null, 2)) console.log(JSON.stringify({ report: reportPath, passed: report.passed, checks: checks.length })) } } main().catch(error => { console.error(error.name); process.exitCode = 1 })