Files
zeekay 6c65e3e941 @hanzo/app 0.2.0: the app SDK, renamed from @hanzo/rooms
Every import, the catalog pin and the docs name @hanzo/app and
github.com/hanzoai/app. lib/rooms.ts is lib/app.ts and
components/rooms.tsx is components/app.tsx.
2026-10-22 19:07:20 -07:00

63 lines
3.1 KiB
TypeScript

import { expect, test, type Page } from '@playwright/test'
import { serveExport } from './export'
import { signIn } from '../session'
/**
* API KEYS HAVE ONE HOME, THE PLATFORM.
*
* The site's Settings lists API keys as platform.hanzo.ai/api-keys, and the old
* address only sends the reader on. In the app, the account menu (@hanzo/app Me)
* reaches them through Settings, the site's one tree at /settings, whose API keys
* row is that platform page. Measured on the shipped bytes.
*/
const CONSOLE = 'https://platform.hanzo.ai/api-keys'
let base: string
let stop: () => Promise<void>
test.beforeAll(async () => {
const served = await serveExport()
base = served.url
stop = served.close
})
test.afterAll(async () => stop())
/** A signed-in owner of `hanzo`; the keys read answers none, everything else `{}`. */
async function open(page: Page, path: string) {
await signIn(page)
await page.route(
(u) => u.pathname.startsWith('/v1/') && !u.pathname.startsWith('/v1/iam/oauth/') && !u.pathname.startsWith('/v1/billing/'),
(route) => {
const path = new URL(route.request().url()).pathname
if (path === '/v1/account/keys') return route.fulfill({ json: { keys: [] } })
if (path.endsWith('/stream')) return route.fulfill({ status: 200, contentType: 'text/event-stream', body: '' })
return route.fulfill({ json: {} })
},
)
await page.setViewportSize({ width: 1440, height: 900 })
await page.goto(`${base}${path}`)
}
test('the account menu reaches API keys through Settings, the site\'s /settings', async ({ page }) => {
await open(page, '/')
await expect(page.getByRole('navigation', { name: 'Hanzo' })).toBeVisible({ timeout: 30_000 })
await page.getByRole('dialog', { name: 'Cookie preferences' }).getByRole('button', { name: 'OK' }).click({ timeout: 5000 }).catch(() => {})
await page.getByRole('button', { name: 'Account: gate ยท hanzo' }).click()
const menu = page.getByRole('menu', { name: 'Account' })
const rows = await menu.getByRole('menuitem').evaluateAll((els) => els.map((el) => el.textContent?.trim() ?? ''))
expect(rows.slice(rows.indexOf('Upgrade plan')), 'the plan, then the person\'s own rows').toEqual(['Upgrade plan', 'Personalization', 'Profile', expect.stringMatching(/^Settings/), 'Beta', 'Help', 'Log out'])
await menu.getByRole('menuitem', { name: 'Settings' }).click()
await expect.poll(() => new URL(page.url()).pathname).toBe('/settings')
await expect(page.getByRole('navigation', { name: 'Settings' }).getByRole('link', { name: 'API keys' })).toHaveAttribute('href', CONSOLE, { timeout: 30_000 })
})
test('Settings lists API keys as the platform page, and the old address sends the reader there', async ({ page }) => {
await page.context().route('https://platform.hanzo.ai/**', (route) => route.fulfill({ contentType: 'text/html', body: 'platform' }))
await open(page, '/settings')
const nav = page.getByRole('navigation', { name: 'Settings' })
await expect(nav.getByRole('link', { name: 'API keys' })).toHaveAttribute('href', CONSOLE, { timeout: 30_000 })
await page.goto(`${base}/settings/organization/keys`)
await expect.poll(() => page.url()).toBe(CONSOLE)
})