Files
hanzo.ai/e2e/gates/rail.ts
zeekay 0d17be6a91 Land the fold's setup prompt and the agent strip
HomeLanding draws AgentStrip and Fold draws CopyPrompt, which the gates
on main had asserted for a day before the components were committed —
main was specs ahead of components, and every forge deploy since failed
at that gap. With them: the dot backdrop as an SVG grid instead of a
canvas loop, Find at a fraction of its size, /affiliates, /oss and
/partners with titles of their own, and a Solutions menu in the header.
2026-09-06 19:08:32 -07:00

44 lines
1.9 KiB
TypeScript

import { expect, type Page } from '@playwright/test'
/**
* THE RAIL, OUT — however it arrived, and still out a moment later.
*
* Six gates pressed "Open sidebar" on arrival, which encoded a default rather
* than a behaviour: the rail used to start away, and `5c849331 Open the rail on
* desktop` changed that. The button then reads "Close sidebar", the press never
* finds its target, and three gates hung for thirty seconds each on a room that
* was working — the shape they were written for, not the thing they check.
*
* Asking for the END STATE fixed that and left a subtler one. The prerendered
* tree carries the rail OUT at every width, because a server knows neither the
* window nor what this reader last chose; both arrive after mount, and on a
* phone they put the rail away. So a gate that reads visibility on arrival
* reads the SERVER'S rail, presses nothing, and goes on to measure a column
* already leaving — which is how `/dev at phone` failed perhaps one run in ten.
*
* Hence: press when it is away, then hold still and require it to be there
* afterwards. A rail seen before the reader's answer lands does not survive
* that second look, and the retry opens it properly.
*/
export async function rail(page: Page, selector: string): Promise<void> {
await page
.locator('[data-slot="workspace"][data-hydrated="true"]')
.first()
.waitFor({ timeout: 15_000 })
.catch(() => {})
const out = page.locator(selector).first()
const handle = page
.locator('header')
.getByRole('button', { name: /Open sidebar|Close sidebar/ })
.first()
await expect(async () => {
if (!(await out.isVisible().catch(() => false))) {
if (await handle.count()) await handle.click().catch(() => {})
}
await page.waitForTimeout(250)
expect(await out.isVisible(), 'the rail must come out, and stay out').toBe(true)
}).toPass({ timeout: 20_000 })
}