From b04eecdf6db1d46b75236da7b14c3b43b2d1f950 Mon Sep 17 00:00:00 2001 From: Chris Arter Date: Fri, 8 May 2026 12:53:24 -0400 Subject: [PATCH] test(e2e): smoke tests for core routes Add 6 Playwright smoke tests covering home, blog post with TOC, RSS, sitemap, OG image, and about page. Update playwright.config.ts to use port 3001 (port 3000 is occupied by OrbStack). Fix payload.config.ts null-safe realpath call that crashed tsx/esm import. Co-Authored-By: Claude Opus 4.7 (1M context) --- playwright.config.ts | 4 ++-- src/payload.config.ts | 2 +- tests/e2e/smoke.spec.ts | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 tests/e2e/smoke.spec.ts diff --git a/playwright.config.ts b/playwright.config.ts index c60fa9d..923a5e1 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -22,7 +22,7 @@ export default defineConfig({ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ use: { /* Base URL to use in actions like `await page.goto('/')`. */ - // baseURL: 'http://localhost:3000', + baseURL: process.env.PLAYWRIGHT_BASE_URL ?? 'http://localhost:3001', /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry', @@ -36,6 +36,6 @@ export default defineConfig({ webServer: { command: 'pnpm dev', reuseExistingServer: true, - url: 'http://localhost:3000', + url: process.env.PLAYWRIGHT_BASE_URL ?? 'http://localhost:3001', }, }) diff --git a/src/payload.config.ts b/src/payload.config.ts index 1efdf2e..c977454 100644 --- a/src/payload.config.ts +++ b/src/payload.config.ts @@ -19,7 +19,7 @@ const filename = fileURLToPath(import.meta.url) const dirname = path.dirname(filename) const realpath = (value: string) => (fs.existsSync(value) ? fs.realpathSync(value) : undefined) -const isCLI = process.argv.some((value) => realpath(value).endsWith(path.join('payload', 'bin.js'))) +const isCLI = process.argv.some((value) => realpath(value)?.endsWith(path.join('payload', 'bin.js'))) const isProduction = process.env.NODE_ENV === 'production' const createLog = diff --git a/tests/e2e/smoke.spec.ts b/tests/e2e/smoke.spec.ts new file mode 100644 index 0000000..8b9e1cb --- /dev/null +++ b/tests/e2e/smoke.spec.ts @@ -0,0 +1,38 @@ +// tests/e2e/smoke.spec.ts +import { test, expect } from '@playwright/test' + +test('home renders', async ({ page }) => { + await page.goto('/') + await expect(page.locator('h2:has-text("Latest in Tech")')).toBeVisible() +}) + +test('blog post renders with TOC anchor', async ({ page }) => { + await page.goto('/blog/a-guide-to-laravel-authorization-patterns/') + await expect(page.locator('h1:has-text("Authorization Patterns")')).toBeVisible() + const firstAnchor = page.locator('h2[id]').first() + await expect(firstAnchor).toBeVisible() +}) + +test('rss returns xml', async ({ request }) => { + const r = await request.get('/rss.xml') + expect(r.status()).toBe(200) + expect(r.headers()['content-type']).toContain('application/rss+xml') + expect(await r.text()).toContain(' { + const xml = await (await request.get('/sitemap.xml')).text() + expect(xml).toContain('/blog/') + expect(xml).toContain('/tags/') +}) + +test('og image returns png', async ({ request }) => { + const r = await request.get('/og/blog/a-guide-to-laravel-authorization-patterns/') + expect(r.status()).toBe(200) + expect(r.headers()['content-type']).toBe('image/png') +}) + +test('about page renders via catch-all', async ({ page }) => { + await page.goto('/about/') + await expect(page.locator('h1')).toBeVisible() +}) -- 2.51.2