Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ jobs:
name: playwright-report-${{ matrix.shard }}
path: |
playwright-report/
privacy-report/
test-results/
retention-days: 7

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ pnpm-debug.log*
# Local development documents (instructions and roadmap), kept on this machine only
/CLAUDE.md
/PLAN.md
privacy-report/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Nothing reaches `main` without a green `CI passed` check (enforced by a reposito
| Lint, format, types | ESLint (typescript-eslint strict), Prettier, `astro check` |
| Unit tests | Vitest |
| Build-output checks | Metadata, legal pages, links and anchors, security headers, CSP, contact data protection |
| End-to-end tests | Playwright (desktop and mobile), privacy guard (same-origin only, nothing stored), axe |
| End-to-end tests | Playwright (desktop and mobile), layout guard and privacy guard (own packages), axe |
| Lighthouse | Every category at least 95 on mobile, size budgets, no third-party requests |
| Security | CodeQL, dependency review, `pnpm audit`, OpenSSF Scorecard, Dependabot, secret scanning |
| Workflow lint | `actionlint` for the workflow files, actions pinned to commit SHAs |
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"lighthouse": "^13.5.0",
"lint-staged": "^17.6.0",
"playwright-layout-guard": "0.3.0",
"playwright-privacy-guard": "0.2.0",
"prettier": "^3.9.10",
"prettier-plugin-astro": "^1.1.2",
"prettier-plugin-tailwindcss": "^0.8.1",
Expand Down
18 changes: 16 additions & 2 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { defineConfig, devices } from '@playwright/test';
import type { LayoutGuardOptions } from 'playwright-layout-guard';
import type { PrivacyGuardOptions } from 'playwright-privacy-guard';

import { privacyGuardOptions } from './tests/e2e/privacy-options';

// The ports: `astro dev` is 4321 (WebStorm or Claude, only one of them at a time), the browser tests
// start their own `astro preview` on 4322, Lighthouse uses 4323. A server that already stands on
Expand All @@ -8,7 +11,10 @@ import type { LayoutGuardOptions } from 'playwright-layout-guard';
const port = 4322;
const isCI = Boolean(process.env.CI);

export default defineConfig<{ layoutGuard: boolean | LayoutGuardOptions }>({
export default defineConfig<{
layoutGuard: boolean | LayoutGuardOptions;
privacyGuard: boolean | PrivacyGuardOptions;
}>({
testDir: './tests/e2e',
fullyParallel: true,
forbidOnly: isCI,
Expand All @@ -23,12 +29,20 @@ export default defineConfig<{ layoutGuard: boolean | LayoutGuardOptions }>({
...(isCI ? { workers: 4 } : {}),
retries: isCI ? 1 : 0,
// `list` prints every test as it finishes, so a stuck run is visible in the CI log
reporter: isCI ? [['list'], ['github'], ['html', { open: 'never' }]] : [['list']],
reporter: [
['list'],
...(isCI ? ([['github'], ['html', { open: 'never' }]] as const) : []),
// One page for the whole run with everything the privacy guard found (also in the summary of a CI run)
// The tests that make a page misbehave on purpose are not part of the report
['playwright-privacy-guard/reporter', { ignore: [/canary/] }],
],
use: {
baseURL: `http://localhost:${String(port)}`,
// On this site not even the height of a page may change, also not when it gets lower (the default
// of the layout guard is to count only a page that gets higher)
layoutGuard: { pageHeight: 'any' },
// The promise of the privacy policy, for every test (what is watched: privacy-options.ts)
privacyGuard: privacyGuardOptions,
trace: 'on-first-retry',
// Fail fast instead of waiting minutes when the browser cannot start
launchOptions: { timeout: 60_000 },
Expand Down
13 changes: 13 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
allowBuilds:
esbuild: true
workerd: true
# pnpm does not install a version that is younger than its minimum release age. playwright-privacy-guard
# is my own package and 0.2.0 was published on 2026-10-28: delete this entry once pnpm installs it
# without it (a few days after the release).
minimumReleaseAgeExclude:
- playwright-privacy-guard@0.2.0
# miniflare (inside wrangler) pins undici 7.29.1 exactly, and 7.29.1 has known denial of service
# findings (patched in 7.30.1; found by pnpm audit on 2026-10-24). Written as a range of the bad
# versions, so it does nothing once miniflare asks for a patched version itself: then delete it.
Expand Down
5 changes: 4 additions & 1 deletion scripts/lighthouse.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,13 @@ const CATEGORIES = ['performance', 'accessibility', 'best-practices', 'seo'];
* conservative. Measured on 2026-10-01 (with the contact form): scripts 4.5 KB, stylesheets 7.1 KB, total 134 KB.
* The stylesheet limit was raised from 20 to 21 KB on 2026-10-18: the home page carries the pictures of
* the tiles of all five games (the Backbone tile came last), it measured 20.2 KB with a smaller tile.
* It was raised from 21 to 22 KB on 2026-10-28: the project card of playwright-privacy-guard brings its
* own picture (the same kind as the one of the layout guard, a loop of ten seconds), the page measured
* 21.2 KB with it, and a card of this kind is part of the design of the page.
*/
const BUDGETS = {
script: 10 * 1024,
stylesheet: 21 * 1024,
stylesheet: 22 * 1024,
total: 200 * 1024,
};

Expand Down
Loading
Loading