Files
zeekay 89691f3697 market: every listing a page and a Markdown twin, with sitemap, llms.txt, robots, auth.md, api-catalog and WebMCP
The build writes the catalog into dist after vite: a page per listing (the
shell with its own head, JSON-LD and a static body the app replaces), its
twin at <path>.md, the shelves, the front, sitemap.xml, llms.txt,
llms-full.txt, 404.html, and a moved page for any path the last release
listed and this one does not. Sources are read whole; one that fails or
answers empty stops the build. Every external link is fetched and dropped
unless it answers.

A price and an Offer come only from the shop. Directory and template
entries say they are not shop listings. Fabricated ratings, reviews and
installs, the directory's certified tax form, and the persona and template
CLI lines the CLI lacks are gone.

WebMCP registers search_market and get_listing, read-only. An unknown path
renders Not found instead of the front page. Persona definitions move to
/personas/<slug>/PERSONA.md, where the twin's path was.
2026-10-27 02:06:43 -07:00

38 lines
1.7 KiB
TypeScript

import { expect, test } from '@playwright/test'
// Read-only checks that run against a deployed storefront (BASE_URL=…) as well
// as the dev server. No sign-in, no writes, no payments.
test('@live the storefront loads with the Hanzo chrome and the catalog', async ({ page }) => {
const errors: string[] = []
page.on('pageerror', (e) => errors.push(e.message))
await page.goto('/')
await expect(page.getByRole('heading', { name: 'Agents, personas, apps, skills, MCP servers and tools' })).toBeVisible()
await expect(page.getByRole('searchbox', { name: 'Search the marketplace' })).toBeVisible()
await expect(page.getByRole('link', { name: 'Try Hanzo' }).first()).toHaveAttribute('href', '/login')
await expect(page.getByRole('contentinfo')).toBeVisible()
expect(errors).toEqual([])
})
test('@live deep links land on the app', async ({ page }) => {
for (const path of ['/agents', '/skills', '/sell', '/l/unknown']) {
const res = await page.goto(path)
expect(res?.status(), path).toBeLessThan(500)
await expect(page.locator('#root')).not.toBeEmpty()
}
await page.goto('/sell')
await expect(page.getByRole('heading', { name: 'Sign in to continue' })).toBeVisible()
})
test('@live signing in stays on this site: /login draws the sign-in and nothing goes to hanzo.id', async ({ page }) => {
const issuer: string[] = []
page.on('request', (r) => {
if (r.isNavigationRequest() && new URL(r.url()).hostname === 'hanzo.id') issuer.push(r.url())
})
await page.goto('/sell')
await page.getByRole('button', { name: 'Try Hanzo' }).click()
await page.waitForURL((u) => u.pathname === '/login')
await expect(page.getByRole('textbox', { name: 'Email' })).toBeVisible()
expect(issuer).toEqual([])
})