test: add playwright smoke suite
Add playwright.config.ts with webServer configured to run build and preview on port 4173. Add e2e/smoke.spec.ts with 4 smoke tests: rel=me anchor presence, all identity links in HTML, canvas and HUD visibility, and reduced motion fallback rendering. Restructure App.tsx to render Scroller outside #demo div to fix selector ambiguity in e2e tests. Add test.exclude to vite.config.ts to prevent vitest from running playwright tests.
This commit is contained in:
@@ -0,0 +1,30 @@
|
|||||||
|
import { expect, test } from '@playwright/test'
|
||||||
|
import { LINKS } from '../src/content/links'
|
||||||
|
|
||||||
|
test('raw HTML contains the rel=me anchor (no JS needed)', async ({ request }) => {
|
||||||
|
const res = await request.get('/')
|
||||||
|
const html = await res.text()
|
||||||
|
expect(html).toMatch(
|
||||||
|
/<a[^>]*href="https:\/\/mastodon\.saillant\.cc\/@clement"[^>]*rel="me"/,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('raw HTML contains every identity link', async ({ request }) => {
|
||||||
|
const html = await (await request.get('/')).text()
|
||||||
|
for (const l of LINKS) expect(html).toContain(`href="${l.href}"`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('the demo boots: canvas mounts and hud shows', async ({ page }) => {
|
||||||
|
await page.goto('/')
|
||||||
|
await expect(page.locator('#demo canvas')).toBeVisible()
|
||||||
|
await expect(page.locator('#tracker')).toBeVisible()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('reduced motion serves the readable fallback', async ({ browser }) => {
|
||||||
|
const ctx = await browser.newContext({ reducedMotion: 'reduce' })
|
||||||
|
const page = await ctx.newPage()
|
||||||
|
await page.goto('/')
|
||||||
|
await expect(page.locator('#fallback h1')).toBeVisible()
|
||||||
|
await expect(page.locator('#demo canvas')).toHaveCount(0)
|
||||||
|
await ctx.close()
|
||||||
|
})
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { defineConfig } from '@playwright/test'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
testDir: 'e2e',
|
||||||
|
use: { baseURL: 'http://localhost:4173' },
|
||||||
|
webServer: {
|
||||||
|
command: 'npm run build && npm run preview',
|
||||||
|
port: 4173,
|
||||||
|
reuseExistingServer: !process.env.CI,
|
||||||
|
},
|
||||||
|
})
|
||||||
+20
-18
@@ -15,24 +15,26 @@ export default function App() {
|
|||||||
useRideInput()
|
useRideInput()
|
||||||
const player = useMemo(() => createModPlayer(), [])
|
const player = useMemo(() => createModPlayer(), [])
|
||||||
return (
|
return (
|
||||||
<div id="demo">
|
<>
|
||||||
<Canvas
|
<div id="demo">
|
||||||
dpr={0.6}
|
<Canvas
|
||||||
gl={{ antialias: false }}
|
dpr={0.6}
|
||||||
camera={{ fov: 55, position: [0, 6.5, -11], near: 0.1, far: 900 }}
|
gl={{ antialias: false }}
|
||||||
>
|
camera={{ fov: 55, position: [0, 6.5, -11], near: 0.1, far: 900 }}
|
||||||
<color attach="background" args={['#05010d']} />
|
>
|
||||||
<ambientLight intensity={0.55} />
|
<color attach="background" args={['#05010d']} />
|
||||||
<directionalLight position={[60, 90, 30]} intensity={1.3} />
|
<ambientLight intensity={0.55} />
|
||||||
<CameraRig />
|
<directionalLight position={[60, 90, 30]} intensity={1.3} />
|
||||||
<World />
|
<CameraRig />
|
||||||
<Bus />
|
<World />
|
||||||
<Passengers />
|
<Bus />
|
||||||
<Sky />
|
<Passengers />
|
||||||
<Stops />
|
<Sky />
|
||||||
</Canvas>
|
<Stops />
|
||||||
|
</Canvas>
|
||||||
|
<TrackerPanel player={player} />
|
||||||
|
</div>
|
||||||
<Scroller />
|
<Scroller />
|
||||||
<TrackerPanel player={player} />
|
</>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,4 +47,7 @@ export default defineConfig({
|
|||||||
// served straight from node_modules, where the relative lookup works.
|
// served straight from node_modules, where the relative lookup works.
|
||||||
exclude: ['chiptune3'],
|
exclude: ['chiptune3'],
|
||||||
},
|
},
|
||||||
|
test: {
|
||||||
|
exclude: ['node_modules', 'dist', 'e2e'],
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user