mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-29 07:20:43 +00:00
This export carried a second copy of the builder at /dev — the composer,
a run's transcript and a project pane (app/(app)/dev and
components/workspace/{Build,Session,project}.tsx), plus DevStudio.tsx and
enter.ts, which nothing else used. They are deleted, and dev.hanzo.ai is no
longer published from this export.
Every link to the builder is DEV or dev(ref) from lib/host.ts. dev() carries
a run id or a project slug into the path only when it is exactly one, so no
caller can make it name another address. The shell's Dev tile, Projects and
Runs open it there; /code forwards there. The edge's permanent redirects for
hanzo.ai/dev, /code, dev.hanzo.ai and hanzo.app live in universe.
Gates and specs that drove the old /dev drive /chat where they tested the
shared shell, and are removed where the builder itself was the subject.
Co-authored-by: Hanzo Dev <[email protected]>
55 lines
2.6 KiB
TypeScript
55 lines
2.6 KiB
TypeScript
// Every room ships exactly one <h1>.
|
|
//
|
|
// This is its own spec, and small, because it is the claim that four other
|
|
// tests kept failing FOR. Using the heading as a precondition made one missing
|
|
// element report as a broken board, a broken rail and a broken composer, which
|
|
// buries the actual defect under three false ones.
|
|
//
|
|
// It is also the invariant this repo has already shipped broken once, and the
|
|
// notes say exactly how it happens: "Give the `<h1>` a new home in the same
|
|
// commit… cloud.hanzo.ai shipped a live page with ZERO `<h1>` this way. Nothing
|
|
// catches this — the export is valid, the build is green." A heading is what a
|
|
// crawler reads, what a screen reader lands on, and what tells a visitor which
|
|
// page they are on.
|
|
//
|
|
// THIS IS THE SAME CLAIM `e2e/gates/workspace.spec.ts` MAKES ABOUT THE EXPORT,
|
|
// held here against the running server instead. That gate is a step in the
|
|
// PUBLISHING JOB, so when this is red the site does not deploy at all — the
|
|
// repo's own record is "four gates went red and hanzo.ai published nothing for
|
|
// a day while pushes kept succeeding". A failure here is therefore not a
|
|
// cosmetic finding; it is the publish lane.
|
|
//
|
|
// BASE_URL=http://localhost:3000 pnpm exec playwright test --project=chromium e2e/headings.spec.ts
|
|
|
|
import { test, expect } from '@playwright/test'
|
|
import { BASE, ROUTES, open, settled, shot } from './app'
|
|
|
|
test.describe.configure({ timeout: 120_000 })
|
|
|
|
test.describe('the rooms name themselves', () => {
|
|
for (const route of ['/chat'] as const) {
|
|
test(`${route} renders exactly one heading`, async ({ page }) => {
|
|
await open(page, route)
|
|
const rendered = await page.locator('h1').count()
|
|
await shot(page, `heading${route.replace('/', '-')}`)
|
|
|
|
expect(rendered, `${route} renders ${rendered} <h1> elements after hydration`).toBe(1)
|
|
|
|
const words = (await page.locator('h1').first().innerText()).trim()
|
|
expect(words.length, `${route}'s heading is empty, which is the same as not having one`).toBeGreaterThan(0)
|
|
test.info().annotations.push({ type: 'heading', description: `${route}: "${words}"` })
|
|
})
|
|
}
|
|
|
|
test('every room a rail can reach names itself', async ({ page }) => {
|
|
// The two rooms above are the ones the gate covers. The rest are reachable
|
|
// by a reader and owe the same thing, so a room added to the rail cannot
|
|
// arrive without a heading and go unnoticed.
|
|
for (const route of ROUTES) {
|
|
await open(page, route)
|
|
const rendered = await page.locator('h1').count()
|
|
expect(rendered, `${route} renders ${rendered} <h1> elements after hydration`).toBe(1)
|
|
}
|
|
})
|
|
})
|