import { test, expect } from '@playwright/test'; // Pages that must be indexed with production canonical URLs const indexedPages = [ { path: '/', titlePattern: /Neuron — The AI That Remembers You/ }, { path: '/about', titlePattern: /About.*Neuron|Neuron.*About/i }, ]; // Legal pages use /legal/ prefix const legalPages = [ { path: '/legal/terms', titlePattern: /Terms|Neuron/i }, { path: '/legal/enterprise-terms', titlePattern: /Enterprise|Neuron/i }, ]; for (const { path, titlePattern } of indexedPages) { test(`${path} — title matches expected pattern`, async ({ page }) => { await page.goto(path); await expect(page).toHaveTitle(titlePattern); }); test(`${path} — has meta description`, async ({ page }) => { await page.goto(path); const desc = await page.locator('meta[name="description"]').getAttribute('content'); expect(desc).toBeTruthy(); expect(desc!.length).toBeGreaterThan(30); }); test(`${path} — canonical points to production domain, not stage`, async ({ page }) => { await page.goto(path); const canonical = await page.locator('link[rel="canonical"]').getAttribute('href'); expect(canonical).toContain('neurontechnologies.ai'); expect(canonical).not.toContain('stage'); expect(canonical).not.toContain('run.app'); }); test(`${path} — has og:title`, async ({ page }) => { await page.goto(path); const ogTitle = await page.locator('meta[property="og:title"]').getAttribute('content'); expect(ogTitle).toBeTruthy(); expect(ogTitle!.length).toBeGreaterThan(5); }); } for (const { path, titlePattern } of legalPages) { test(`${path} — renders with title`, async ({ page }) => { const r = await page.goto(path); expect(r?.status()).toBe(200); await expect(page).toHaveTitle(titlePattern); }); } // Checkout must be noindex — it's a functional page, not content test('Checkout page has noindex meta robots', async ({ page }) => { await page.goto('/checkout?plan=professional'); const robots = page.locator('meta[name="robots"]'); await expect(robots).toHaveCount(1); const content = await robots.getAttribute('content'); expect(content).toContain('noindex'); }); // Sitemap must only contain production URLs test('Sitemap lists production URLs only (no stage or run.app)', async ({ page }) => { const r = await page.request.get('/sitemap.xml'); expect(r.status()).toBe(200); const text = await r.text(); expect(text).toContain('neurontechnologies.ai'); expect(text).not.toContain('run.app'); expect(text).not.toContain('stage'); expect(text).toContain(' { await page.goto('/'); const schemaContent = await page.locator('script[type="application/ld+json"]').textContent(); expect(schemaContent).toBeTruthy(); const parsed = JSON.parse(schemaContent!); // Must be an object with @context at minimum expect(parsed['@context']).toBeTruthy(); });