diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 209e229..e80f9ae 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,3 +27,18 @@ jobs: - run: npm run typecheck - run: npm run test - run: npm run build + + e2e: + name: Playwright e2e + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + persist-credentials: false + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7 + with: + node-version: 24 + - run: npm ci + - run: npx playwright install --with-deps chromium firefox webkit + - run: npm run test:e2e diff --git a/.gitignore b/.gitignore index fa28420..8fe45a5 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,7 @@ npm-debug.log* yarn-debug.log* yarn-error.log* +# playwright e2e +/test-results +/playwright-report +/e2e/test-results diff --git a/README.md b/README.md index d85234e..1e6f31a 100644 --- a/README.md +++ b/README.md @@ -229,6 +229,172 @@ covers the manual full reset (a missed webhook, or a change to the query-ID form | `DRAFT_SECRET_TOKEN` | Authorizes draft enable/disable and web-previews | | `CACHE_INVALIDATION_SECRET_TOKEN` | Authorizes the revalidate and cache-tag webhooks (`Webhook-Token`) | +## `@smartive/utils/testing` + +Building blocks for sitemap-driven smoke tests. Zero dependencies, no browser. + +```typescript +import { checkUrls, fetchSitemapRoutes, formatUrlCheckFailures } from '@smartive/utils/testing'; + +const routes = await fetchSitemapRoutes({ + baseURL: 'http://localhost:3333', + limits: [{ pattern: '/arbeiten/', max: 3 }], // sample large collections + exclude: ['/ueber-uns/livebilder'], +}); + +const results = await checkUrls(routes, { baseURL: 'http://localhost:3333' }); +``` + +- `fetchSitemapRoutes` follows a sitemap index and includes `xhtml:link` alternates. It replaces the + sitemap host with `baseURL`, deduplicates, applies `exclude` then `limits`, and throws when the + sitemap is unreachable, slower than `timeoutMs` (default 30 s) or empty, so a broken sitemap never turns into a green run that checked + nothing. +- `checkUrls` requests every URL without following redirects (a redirecting sitemap URL fails), + retries network errors and 5xx once, and never throws. `formatUrlCheckFailures` turns the + failures into an assertion message. +- `parseSitemap`, `limitRoutes`, `excludeRoutes`, `toPath` and `isIgnored` are exported for custom + setups. Patterns are a `string` (substring) or a `RegExp`. + +### `@smartive/utils/testing/playwright` + +Fixtures that fail a Playwright test on client-side errors: hydration mismatches, React errors, +exceptions in client components, failed first-party requests. Only types are imported from +`@playwright/test`, so install the version that matches your CI image: + +```bash +npm install -D @playwright/test@ +``` + +The automatic `smoke` fixture: + +- blocks every request that is not same-origin with `baseURL` or listed in `allowHosts`, so + trackers, consent banners and embeds neither add noise nor send hits from CI +- collects console errors and warnings (`failOn`), uncaught exceptions and unhandled rejections, + first-party responses with status ≥ 400 and failed first-party requests +- ignores console errors of blocked requests and expected aborts (`