Files
app/e2e/honesty.spec.ts
zeekayandClaude Opus 5.5 5be42486fd A bundle carries the sites its entry registers, and no others
The tenant table and the chain register lived in chrome/brand.tsx and
gov/chain.ts, which every screen, read and piece of chrome imports. So a
bundle built by a fork carried every estate's name, mark, issuer, RPC and
governor addresses, and chose among them by hostname at runtime.

Lux, Zoo and Hanzo are now declared in src/tenants.tsx, imported only by
this repository's main.tsx, which hands them to add(). Each tenant declares
its own chain (and, under DEV, its loopback chain) beside its name, so
chrome/brand.tsx is the mechanism alone and gov/chain.ts is the shape of a
chain. roster() reads the tenant rather than filtering a register. A fork
registers its own site from its own entry and ships nothing of the three.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-24 01:24:29 -07:00

91 lines
4.3 KiB
TypeScript

import { expect, test } from '@playwright/test'
import { SCREENS, ready } from './screens'
/**
* The rule this interface exists to keep.
*
* The app being replaced rendered a hard-coded proposal list — four named
* proposals with vote counts, on a Governor that has never had one — beside
* stat tiles reading "4 Total Proposals, 2 Active". Every number was invented.
* These tests are what stop that coming back, and they are deliberately about
* the rendered page rather than the source, because a fabricated figure can
* arrive from a fixture, a default argument or a component library just as
* easily as from a literal somebody typed.
*/
/** Strings from the retired Pars app and its Decent-derived predecessor. */
const INVENTED = [
'PersianDAO', 'vePARS', 'MIGA', 'MIP-00',
'125,000', '156 delegators', '98% participation',
'Emergency Medical Aid',
]
test.describe('no screen carries a figure nobody measured', () => {
for (const path of SCREENS) {
test(`${path} shows none of the retired app's invented content`, async ({ page }) => {
await page.goto(path)
await ready(page)
const body = (await page.locator('body').innerText()).toLowerCase()
const hits = INVENTED.filter((s) => body.includes(s.toLowerCase()))
expect(hits, `${path} renders invented content: ${hits.join(', ')}`).toEqual([])
})
}
})
test('the picker offers this site\'s own chain and no other estate\'s', async ({ page }) => {
// One site is one tenant, and a tenant declares one chain: this site reads
// its own. A picker listing Zoo, Pars and Hanzo on lux.vote
// told a reader they were somewhere shared and put another network's
// addresses under this one's mark — which is what `roster()` ended.
await page.goto('/work')
await ready(page)
await page.getByRole('button', { name: /Chain:/ }).click()
for (const other of [/^Zoo/, /^Pars/, /^Hanzo/]) {
await expect(page.getByRole('button', { name: other })).toHaveCount(0)
}
await expect(page.getByRole('button', { name: /^Lux C-Chain · 96369/ })).toBeVisible()
})
test('the deployment survey distinguishes all four readings', async ({ page }) => {
await page.goto('/deployment')
await expect(page.getByRole('heading', { level: 1, name: 'Smart contracts' })).toBeVisible()
// Every reading is a measurement performed on load; each of the four has to
// be reachable or the distinction is decorative.
await expect(page.getByText('deployed', { exact: true }).first()).toBeVisible({ timeout: 45_000 })
await expect(page.getByText('not deployed', { exact: true }).first()).toBeVisible()
await expect(page.getByText('no record', { exact: true }).first()).toBeVisible()
})
test('a register says what it read, and an empty one says why it is empty', async ({ page }) => {
// Governance is deployed on 96369 and one proposal exists, so the register
// draws it. The sentence this test used to demand — "no proposal has ever
// been created" — was true of a chain nobody had used and became a lie the
// moment somebody did; the scan floor was measured on the chain before its
// re-genesis, so the walk began past the head, issued no call at all, and
// rendered an empty result as a fact about governance. What is asserted now
// is that the screen reports what it read: a row, or an emptiness it can
// account for. Never a refusal wearing either.
await page.goto('/proposals')
await expect(page.getByRole('heading', { level: 1, name: 'Proposals' })).toBeVisible()
// Wait for the register itself, not for the word — the heading matches
// /proposal/ before a single block has been read, and a body scraped then is
// a body scraped mid-scan.
await expect(page.getByText(/\d+\s+proposals?\b|never been created/i).first()).toBeVisible({
timeout: 45_000,
})
const body = (await page.locator('body').innerText()).toLowerCase()
expect(body, 'a refusal must not read as an empty register').not.toMatch(/could not be read/)
expect(
/\d+\s+proposal/.test(body) || /never been created/.test(body),
'the register neither drew a row nor accounted for being empty',
).toBe(true)
})
test('the standing note about custody is on every screen', async ({ page }) => {
for (const path of SCREENS) {
await page.goto(path)
await ready(page)
await expect(page.getByText(/you sign every transaction in your own wallet/i).first()).toBeVisible()
}
})