import { expect, test } from '@playwright/test'; test('home page shows the product shell and discovery feed with reusable thing cards', async ({ page }) => { await page.goto('/'); // Persistent product shell. await expect(page.getByRole('link', { name: 'Polymodel home' })).toBeVisible(); await expect(page.getByRole('searchbox', { name: 'Search Polymodel' })).toBeVisible(); await expect(page.getByRole('link', { name: 'Publish' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Sign in' })).toBeVisible(); // Discovery home heading + feed selector (Hot default, Following disabled). await expect(page.getByRole('heading', { name: 'Browse the catalog' })).toBeVisible(); await expect(page.getByRole('tab', { name: 'Hot' })).toHaveAttribute('aria-selected', 'true'); await expect(page.getByRole('tab', { name: 'Recent' })).toHaveAttribute('aria-selected', 'false'); await expect(page.getByRole('tab', { name: 'Following' })).toBeDisabled(); // No inline catalog search box on the home surface anymore. await expect(page.getByRole('searchbox', { name: 'Search model projects' })).toHaveCount(0); const results = page.getByLabel('Browse results'); await expect(results).toBeVisible(); await expect(results.getByRole('article')).toHaveCount(3); await expect(page.getByRole('heading', { name: 'Parametric enclosure kit' })).toBeVisible(); await expect(page.getByText('by Ari Chen')).toBeVisible(); await expect(page.getByText('#parametric')).toBeVisible(); await expect(page.getByText('3 models')).toBeVisible(); await expect(page.getByText('18 parts')).toBeVisible(); await expect(page.getByRole('img', { name: 'Rendered preview of a parametric electronics enclosure' })).toBeVisible(); await expect(page.getByRole('heading', { name: 'Untitled thing' })).toBeVisible(); await expect(page.getByText('by mira.tools')).toBeVisible(); await expect(page.getByRole('heading', { name: 'Modular calibration tower' })).toBeVisible(); await expect(page.getByRole('img', { name: 'Blueprint placeholder for missing preview media' })).toHaveCount(2); await expect(page.getByText('No preview')).toHaveCount(2); await expect(page.getByText('preview pending')).toHaveCount(2); await expect(page.getByLabel('Browse results placeholder')).toHaveCount(0); await expect(page.getByText('Empty')).toHaveCount(0); }); test('global shell search navigates client-side to /search', async ({ page }) => { await page.goto('/'); // Gate on a rendered feed card so the wasm client has hydrated and wired the // search field's keydown handler before we type — otherwise Enter races // hydration and is dropped (the SSR input accepts fill but no handler runs). await expect(page.getByLabel('Browse results').getByRole('article').first()).toBeVisible(); const search = page.getByRole('searchbox', { name: 'Search Polymodel' }); await search.fill('enclosure'); await search.press('Enter'); await expect(page).toHaveURL(/\/search\?q=enclosure$/); await expect(page.getByRole('heading', { name: 'Search', exact: true })).toBeVisible(); await expect(page.getByText('Not wired up yet')).toBeVisible(); await expect(page.getByText(/Searched for/)).toBeVisible(); }); test('shell header is present on a deep route', async ({ page }) => { await page.goto('/profile'); await expect(page.getByRole('link', { name: 'Polymodel home' })).toBeVisible(); await expect(page.getByRole('searchbox', { name: 'Search Polymodel' })).toBeVisible(); await expect(page.getByRole('link', { name: 'Publish' })).toBeVisible(); }); test('placeholder routes resolve with honest, non-faked content', async ({ page }) => { await page.goto('/search'); await expect(page.getByRole('heading', { name: 'Search', exact: true })).toBeVisible(); await expect(page.getByText('Not wired up yet')).toBeVisible(); }); test('home thing cards remain readable at narrow widths', async ({ page }) => { await page.setViewportSize({ width: 390, height: 900 }); await page.goto('/'); await expect(page.getByLabel('Browse results')).toBeVisible(); await expect(page.getByRole('heading', { name: 'Parametric enclosure kit' })).toBeVisible(); await expect(page.getByRole('heading', { name: 'Untitled thing' })).toBeVisible(); await expect(page.getByRole('heading', { name: 'Modular calibration tower' })).toBeVisible(); await expect(page.getByRole('img', { name: 'Blueprint placeholder for missing preview media' })).toHaveCount(2); }); test('foundation route shows foundation primitives and reusable states', async ({ page }) => { await page.goto('/foundation'); await expect(page.getByRole('heading', { name: 'Foundation', exact: true })).toBeVisible(); await expect(page.getByText('Token and asset check')).toBeVisible(); await expect(page.getByLabel('Foundation primitives')).toBeVisible(); await expect(page.getByLabel('Reusable states')).toBeVisible(); await expect(page.getByText('No projects yet')).toBeVisible(); await expect(page.getByText('Feed unavailable')).toBeVisible(); }); test('home page no longer uses workflow roadmap demo copy as the product surface', async ({ page }) => { await page.goto('/'); await expect(page.getByText('Thingiverse on atproto')).toHaveCount(0); await expect(page.getByText('Project lexicon')).toHaveCount(0); await expect(page.getByText('Jira and Confluence')).toHaveCount(0); await expect(page.getByText('Polytoken workflow')).toHaveCount(0); await expect(page.getByText('Front-end foundation')).toHaveCount(0); });