Files
hanzo.ai/e2e/gates/houses.spec.ts

53 lines
2.3 KiB
TypeScript

import { test, expect } from '@playwright/test'
import { serveExport } from './export'
import { signIn } from '../session'
/** Every house agent resolves to a face WITHOUT the API answering. */
const HOUSE = ['Hanzo Researcher', 'Hanzo Designer', 'Hanzo DevOps', 'Hanzo Quant',
'Hanzo Copywriter', 'Hanzo Executive Assistant']
test('each house agent wears its likeness with no roster', async ({ page }) => {
// Six full page loads plus a settle each: the default 30s budget cannot hold
// the loop, and the timeout it raises reads as a broken room rather than a
// slow test.
test.setTimeout(180_000)
await signIn(page)
const site = await serveExport()
try {
// The roster is REFUSED, which is the case this measures: the cast has to
// answer on its own.
await page.route('**/v1/agents', (r) => r.fulfill({ status: 403, contentType: 'application/json',
headers: { 'access-control-allow-origin': '*' }, body: '{"error":"forbidden"}' }))
await page.setViewportSize({ width: 1280, height: 900 })
const missing: string[] = []
for (const name of HOUSE) {
// 'load', not 'networkidle': the room holds a live /v1 connection, so the
// network never goes idle and the wait times out before the page is read.
await page.goto(`${site.url}/chat?agent=${encodeURIComponent(name)}`, { waitUntil: 'load' })
// The app loads after the page does (app/_web.tsx), so the face is waited
// for rather than read once after a fixed pause a slow runner outlasts.
const drawn = await expect
.poll(
() =>
page.evaluate(() => {
const h = document.querySelector('h1')
if (!h) return false
const hy = h.getBoundingClientRect().y
return [...document.querySelectorAll('img')].some((i) => {
const r = i.getBoundingClientRect()
return r.width > 40 && r.bottom <= hy + 1 && (i.getAttribute('src') || '').includes('/agents/')
})
}),
{ timeout: 20_000 },
)
.toBe(true)
.then(
() => true,
() => false,
)
if (!drawn) missing.push(name)
}
expect(missing, 'a house agent with no likeness above its name').toEqual([])
} finally { await site.close() }
})