Files
Cursor Agentandz c3af929c56 site: one API, one account, better cheaper faster
The bar is Models, Dev, Platform, Pricing, Docs, Enterprise, Log in, and Get API key. The homepage is seven sections. Launch pages stay in the tree and drop out of the index through lib/launch.ts. /platform forwards to /cloud. Model and repository floors come from the snapshots the build already keeps.

Co-authored-by: z <[email protected]>
2026-10-26 21:53:40 +00:00

96 lines
5.1 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 { expect, test, type Page } from '@playwright/test'
import { serveExport, read } from './export'
import { AGENTS } from '../../components/gen/roster'
import { sideways } from './wide'
/**
* /gen, on the bytes that ship: the harness's page.
*
* It leads with the install (`curl -fsSL https://hanzo.sh | sh -s gen`), then
* `gen` and `gen --<agent>`, keeps `hanzo dev --<agent>` as the same session
* inside the Hanzo CLI, draws every agent the harness's list names
* (components/gen/roster) with its flag, and names gen's latest release only as
* GitHub answers it when the page opens.
*/
const RELEASE = 'https://api.github.com/repos/hanzoai/gen/releases/latest'
/** GitHub's API answers any origin. */
const CORS = { 'access-control-allow-origin': '*' }
/** Waits for gui to mount the page, which is when its effects (the release read) have run. */
const hydrated = (page: Page) =>
page.waitForFunction(() => !document.documentElement.className.includes('t_unmounted'), null, { timeout: 60_000 })
let base: string
let stop: () => Promise<void>
test.beforeAll(async () => {
const served = await serveExport()
base = served.url
stop = served.close
})
test.afterAll(async () => stop())
test('the export holds /gen: its own canonical, offered to crawlers', () => {
const html = read('gen.html')
expect(html).toContain('<title>Hanzo Gen')
expect(html).toContain('<link rel="canonical" href="https://hanzo.ai/gen"/>')
expect(html).not.toContain('noindex')
expect(read('sitemap.xml'), '/gen is offered').toContain('<loc>https://hanzo.ai/gen</loc>')
})
for (const width of [1440, 390]) {
test(`/gen is the harness’s page at ${width}px: the install first, every agent and its flag, and the release GitHub names`, async ({ page }, info) => {
await page.route(RELEASE, (route) =>
route.fulfill({ headers: CORS, json: { tag_name: 'v9.8.7', html_url: 'https://github.com/hanzoai/gen/releases/tag/v9.8.7' } }),
)
await page.setViewportSize({ width, height: 900 })
await page.goto(`${base}/gen`)
await expect(page.getByRole('heading', { level: 1 })).toHaveText(/Any agent\.\s*Our rails\./, { timeout: 20_000 })
await expect(page.locator('header[data-slot="masthead"]')).toBeVisible()
await expect(page.locator('[data-agent]')).toHaveCount(AGENTS.length)
for (const a of AGENTS) await expect(page.locator(`[data-agent="${a.flag}"]`)).toContainText(a.name)
// The install leads, gen runs the agents, and hanzo dev is the same session in the CLI.
const text = await page.locator('main').innerText()
expect(text).toContain('curl -fsSL https://hanzo.sh | sh -s gen')
for (const command of ['gen --claude', 'gen --codex', 'hanzo dev --claude']) {
expect(text).toContain(command)
expect(text.indexOf('curl -fsSL https://hanzo.sh | sh -s gen'), `the install comes before ${command}`).toBeLessThan(text.indexOf(command))
}
expect(text, 'gen is released').not.toMatch(/\bcoming\b|not (yet )?released/i)
// The hero's calls are every family page's (9920b118); the install is one press away under Read.
await expect(page.getByRole('link', { name: 'Get API key', exact: true }).first()).toHaveAttribute('href', 'https://platform.hanzo.ai/keys')
await expect(page.getByRole('link', { name: 'Install curl -fsSL https://hanzo.sh | sh -s gen', exact: true })).toHaveAttribute('href', '#install')
await hydrated(page)
await expect(page.getByRole('link', { name: 'Latest release v9.8.7 →' })).toHaveAttribute('href', 'https://github.com/hanzoai/gen/releases/tag/v9.8.7', {
timeout: 30_000,
})
expect(await sideways(page), 'nothing wider than the window').toBeLessThanOrEqual(0)
await page.evaluate(() => window.scrollTo(0, 0))
await page.screenshot({ path: info.outputPath(`gen-${width}.png`) })
await page.screenshot({ path: info.outputPath(`gen-${width}-full.png`), fullPage: true })
})
}
test('/gen says nothing about a release GitHub does not answer for', async ({ page }) => {
await page.route(RELEASE, (route) => route.fulfill({ status: 403, headers: CORS, json: { message: 'rate limited' } }))
const refused = page.waitForResponse(RELEASE, { timeout: 60_000 })
await page.goto(`${base}/gen`)
await expect(page.getByRole('heading', { level: 1 })).toBeVisible({ timeout: 20_000 })
await refused
await page.waitForTimeout(1000)
await expect(page.getByText(/Latest release/)).toHaveCount(0)
})
test('Dev is a door in the bar, and Gen stays on its page', async ({ page }) => {
await page.setViewportSize({ width: 1440, height: 900 })
await page.goto(`${base}/dev`, { waitUntil: 'load' })
const bar = page.getByRole('banner')
await expect(bar.getByRole('link', { name: 'Dev', exact: true })).toHaveAttribute('href', '/dev')
await expect(bar.getByRole('link', { name: 'Hanzo Gen', exact: true })).toHaveCount(0)
const gen = page.locator('footer').getByRole('link', { name: 'Gen', exact: true })
await expect(gen).toHaveAttribute('href', '/gen')
await gen.click()
await page.waitForURL((u) => u.pathname === '/gen', { timeout: 20_000 })
await expect(page.getByRole('heading', { level: 1 })).toHaveText(/Any agent\.\s*Our rails\./, { timeout: 20_000 })
})