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

76 lines
3.0 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test, expect } from '@playwright/test'
import { serveExport } from './export'
import { signIn } from '../session'
/**
* THE FACE STANDS ABOVE THE NAME.
*
* A room is opened from a face in the column, so the face is what the reader is
* holding in mind when they arrive; the name alone makes them check they landed
* on the right one.
*
* It measures the AGENT'S OWN picture rather than a cast likeness. `Face` casts
* from the name and falls back to initials when the cast has no part for it, so
* a row named for its job — "Hanzo Researcher" — drew two letters here while the
* column beside it drew the memoji. Passing the record's own avatar is what
* makes the two agree, and this asserts the picture, not merely an element.
*/
const AGENT = {
id: 'a1',
name: 'Einstein',
description: 'Exact about what a rule says and whom it binds.',
avatar: '/agents/einstein.png',
model: 'enso',
}
test('the agent’s own face is drawn above its name', async ({ page }) => {
await signIn(page)
const site = await serveExport()
try {
await page.route('**/v1/agents**', (route) =>
route.fulfill({
status: 200,
contentType: 'application/json',
headers: { 'access-control-allow-origin': '*' },
body: JSON.stringify(
/\/agents\/[^?]/.test(route.request().url())
? { ...AGENT, instructions: '' }
: { data: [AGENT] },
),
}),
)
await page.setViewportSize({ width: 1440, height: 950 })
// `agent` is how the room is addressed — components/workspace/open.ts reads
// it off the query, which is what the column's own press writes.
await page.goto(`${site.url}/chat?agent=Einstein`, { waitUntil: 'load' })
const name = page.getByRole('heading', { name: 'Einstein', level: 1 })
await expect(name).toBeVisible()
// The portrait the record names, at a size the hero uses rather than a row.
const drawn = page.locator('img[src="/agents/einstein.png"]')
await expect(drawn.first()).toBeVisible()
// The hero's, told from the column's by size — the column draws the same
// portrait small, so an element check alone would pass on the wrong one.
// The crew under the composer draws every agent at disc size, this one
// included; it is a door to the room, not the hero, so it is left out here.
const boxes = await drawn.evaluateAll((els) =>
els
.filter((e) => !e.closest('[data-slot="crew"]'))
.map((e) => {
const r = e.getBoundingClientRect()
return { y: r.y, bottom: r.bottom, width: r.width }
}),
)
const box = boxes.find((b) => b.width > 40)
expect(boxes.filter((b) => b.width > 40), 'exactly one face at hero size').toHaveLength(1)
const title = await name.boundingBox()
expect(box, 'a portrait drawn at hero size, not a row’s').toBeTruthy()
expect(title, 'the name has a box').toBeTruthy()
expect(box!.bottom, 'the face sits above the name').toBeLessThanOrEqual(title!.y + 1)
} finally {
await site.close()
}
})