mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-29 07:20:43 +00:00
_web.tsx draws rooms' App inside rooms' `Orgs`, as every room is: a reader with no organization makes one, one with several picks one, and a team on Free is asked for the Team plan before the app is drawn; a personal organization on Free opens it. The app reads its place from the path: /chat and /chat/<id> are Chat, a path under /dev is Dev. /?chat=<id> and /chat?thread=<id> move to /chat/<id>, /?at= to /dev?at=, whose place the door replaces with its path, as it does the builder's grammar rooms 0.1.35-0.1.38 wrote under /dev. The gates read the app at its paths and the rooms' shell at /home, with new Linux baselines for it; the limit banner, the model chip and the side panel are held to what rooms 0.1.55 draws; the landing's budget is 445 KB, since rooms' lib/host carries @hanzo/build's route grammar. app/gui.css is what the build writes. Co-authored-by: Hanzo Dev <[email protected]>
71 lines
2.5 KiB
TypeScript
71 lines
2.5 KiB
TypeScript
import { expect, test } from '@playwright/test'
|
|
import { rail } from './rail'
|
|
import { serveExport } from './export'
|
|
import { signIn } from '../session'
|
|
|
|
/**
|
|
* WITH BOTH COLUMNS OPEN, THE ROOM IS STILL A ROOM.
|
|
*
|
|
* Every other gate opens a room with its columns away, and a sidebar that
|
|
* floats over the room passes all of them: nothing is clipped, nothing leaves
|
|
* the window, every page still ships. It is simply covered — measured on
|
|
* production at 1440, `main` began at x=0 under a 240px sheet and the composer
|
|
* read "Hanzo to build…".
|
|
*
|
|
* So this opens what a working reader opens — the list on the left, the panel on
|
|
* the right — and asks the room for its own box at every width.
|
|
*/
|
|
const SIZES = [
|
|
{ w: 1920, h: 1080, name: 'desktop' },
|
|
{ w: 1440, h: 900, name: 'laptop' },
|
|
{ w: 834, h: 1112, name: 'tablet' },
|
|
{ w: 390, h: 844, name: 'phone' },
|
|
]
|
|
|
|
test.describe('a room keeps its own space beside its columns', () => {
|
|
let base: string
|
|
let stop: () => Promise<void>
|
|
|
|
test.beforeAll(async () => {
|
|
const served = await serveExport()
|
|
base = served.url
|
|
stop = served.close
|
|
})
|
|
test.afterAll(async () => stop())
|
|
|
|
for (const s of SIZES) {
|
|
test(`/home at ${s.name}`, async ({ page }) => {
|
|
await signIn(page)
|
|
await page.setViewportSize({ width: s.w, height: s.h })
|
|
await page.goto(`${base}/home`)
|
|
|
|
await rail(page, '[data-slot="sidebar"]')
|
|
const panel = page.getByRole('button', { name: 'Open side panel' })
|
|
if (await panel.isVisible()) await panel.click()
|
|
|
|
const seen = async () =>
|
|
page.evaluate(() => {
|
|
const m = document.querySelector('main')!.getBoundingClientRect()
|
|
const sheet = document.querySelector('[data-slot="sidebar"]')?.getBoundingClientRect()
|
|
return {
|
|
left: Math.round(m.x),
|
|
width: Math.round(m.width),
|
|
sheetRight: sheet && sheet.width > 0 ? Math.round(sheet.right) : 0,
|
|
}
|
|
})
|
|
|
|
await expect.poll(async () => (await seen()).sheetRight, { timeout: 15_000 }).toBeGreaterThan(0)
|
|
const { left, width, sheetRight } = await seen()
|
|
|
|
// A phone gives the sheet the screen on purpose; anything wider owes the
|
|
// room the space it is standing in.
|
|
if (s.w >= 768) {
|
|
expect(left, `the room is covered by its own list at ${s.name}`).toBeGreaterThanOrEqual(
|
|
sheetRight - 1,
|
|
)
|
|
}
|
|
expect(width, `the room has no room at ${s.name}`).toBeGreaterThan(s.w * 0.2)
|
|
})
|
|
}
|
|
})
|