Files
functional-programming-snake/e2e/playwright.config.mjs
T
Lucas WintherandClaude Fable 5.2 edd57f0148 feat(course): audit fixes and twelve extensions (Modules 7b, 12, 13)
Audit pass:
- Frame rule counts frames since the last move, so every step lasts
  exactly movesEvery(score) frames, also right after a speed-up
- clampTime + MAX_GAP_MS: a hidden tab no longer replays the whole gap
- Pong Restart keeps held keys
- Fact corrections (mulberry32 output coverage, Haskell IO, uniform)
- New fixture cases from a mutation analysis

Extensions (all three tracks, shared fixtures, course text):
- Turn queue (Exercise 10.6), persisted high score (10.7),
  replay viewer (10.8), play() end-to-end helper (9.5)
- Optional State (4.7) and optional Module 7b, stack-safe IO
- Module 12, property-based testing with generators, shrinking,
  invariants and a model-based oracle
- Module 13, Conway's Life with a Click event
- JS type checking via jsconfig, JSDoc and types.d.ts
- Maintainer tools: scripts/mutate.mjs, scripts/typecheck-js.sh,
  Playwright end-to-end suite (e2e/, scripts/e2e.sh)

Docs: docs/contract.md is the canonical contract; specs and build log
under docs/superpowers.

Verified: JS 728, Scala 689, F# 691 unit tests; stubs and progression
M01-M13 and M07b; 176 end-to-end tests on Chromium and WebKit.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
2026-11-11 12:05:29 +01:00

55 lines
2.5 KiB
JavaScript

// Playwright configuration for the end-to-end tests. Run through scripts/e2e.sh, which builds and serves a copy of the
// repository whose <track>/src holds the solutions and passes its address in E2E_BASE_URL.
//
// Browsers: Chromium and WebKit, and Firefox if a build is installed. Nothing is ever downloaded. If the exact build
// this Playwright version expects is missing but another revision of the same browser is in the Playwright cache
// (~/.cache/ms-playwright, or PLAYWRIGHT_BROWSERS_PATH), that one is used and named; if there is none, the project is
// left out with a message.
import { defineConfig, chromium, webkit, firefox } from '@playwright/test'
import { existsSync, readdirSync } from 'node:fs'
import { homedir } from 'node:os'
import { join } from 'node:path'
const cache = process.env.PLAYWRIGHT_BROWSERS_PATH || join(homedir(), '.cache', 'ms-playwright')
const launchers = {
chromium: ['chrome-linux64/chrome', 'chrome-linux/chrome'],
webkit: ['pw_run.sh'],
firefox: ['firefox/firefox'],
}
// Print the notes once, from the main process, not again from every worker.
const say = (msg) => { if (!process.env.TEST_WORKER_INDEX) console.log(msg) }
const browser = (name, type) => {
if (existsSync(type.executablePath())) return { name, use: { browserName: name } }
const other = existsSync(cache)
? readdirSync(cache)
.filter((d) => new RegExp(`^${name}-\\d+$`).test(d))
.sort((a, b) => Number(b.split('-')[1]) - Number(a.split('-')[1]))
.flatMap((d) => launchers[name].map((l) => join(cache, d, l)))
.find(existsSync)
: undefined
if (other) {
say(`e2e: ${name}: the expected build is not installed; using ${other}`)
return { name, use: { browserName: name, launchOptions: { executablePath: other } } }
}
say(`e2e: ${name}: no build installed, skipping this project (npx playwright install ${name} would download one)`)
return null
}
export default defineConfig({
testDir: 'tests',
fullyParallel: true,
workers: process.env.E2E_WORKERS ? Number(process.env.E2E_WORKERS) : '50%',
forbidOnly: true,
retries: 0,
timeout: 60_000,
reporter: [['list'], ['html', { open: 'never', outputFolder: 'playwright-report' }]],
outputDir: 'test-results',
use: {
baseURL: process.env.E2E_BASE_URL ?? 'http://127.0.0.1:8000',
viewport: { width: 1280, height: 900 },
trace: 'retain-on-failure',
},
projects: [browser('chromium', chromium), browser('webkit', webkit), browser('firefox', firefox)].filter(Boolean),
})