diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b5ed2b9f..613c1e2d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -181,6 +181,8 @@ jobs: Start-Sleep -Seconds 10 - name: Install Playwright browsers run: npx playwright install chromium + - name: Reading Mode Test + run: npm run test:reading - name: VRT Test run: npm run test:vrt - name: Upload test results on failure diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml index 2dfd4ef7..bed76aa1 100644 --- a/.github/workflows/update.yml +++ b/.github/workflows/update.yml @@ -69,6 +69,17 @@ jobs: # Content update pushed to gh-pages. No Deploy dispatch here โ€” # Promote merges main and dispatches Deploy (may run before or after us). fi + - name: Setup Node + uses: actions/setup-node@v7 + with: + node-version-file: '.nvmrc' + cache: 'npm' + - name: Install dependencies + run: npm ci --omit dev --ignore-scripts --prefer-offline + - name: Build site + run: npm run build + - name: Run readability test on built site + run: npm run test:reading - if: failure() uses: ./.github/actions/notify-failure with: diff --git a/package.json b/package.json index c32782d3..df5b39fe 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "test": "vitest run", "test:e2e": "vitest run --config vitest.config.e2e.ts", "test:vrt": "playwright test", + "test:reading": "playwright test", "test:vrt:update": "playwright test --update-snapshots", "verify:client-script": "node scripts/verify-client-script.mjs" }, diff --git a/scripts/run-readability-test.mjs b/scripts/run-readability-test.mjs new file mode 100644 index 00000000..90c7d7d1 --- /dev/null +++ b/scripts/run-readability-test.mjs @@ -0,0 +1,39 @@ +// run-readability-test.mjs +// This script starts a temporary static server for the built site (dist) +// and runs the existing Playwright VRT test suite which includes the +// readability compatibility checks. + +import { spawn } from 'child_process'; +import { setTimeout } from 'timers/promises'; + +async function main() { + console.log('๐Ÿš€ Starting static server for dist...'); + // "serve" is invoked via npx; it will be fetched onโ€‘theโ€‘fly if not installed. + const server = spawn('npx', ['serve', 'dist', '-l', '5173'], { + stdio: 'inherit', + shell: true, + }); + + // Give the server a moment to start listening. + await setTimeout(5000); + + try { + console.log('๐Ÿงช Running readability VRT tests...'); + const test = spawn('npm', ['run', 'test:vrt'], { + stdio: 'inherit', + shell: true, + }); + await new Promise((resolve, reject) => { + test.on('close', code => (code === 0 ? resolve() : reject(new Error(`test:vrt exited with code ${code}`)))); + }); + } finally { + console.log('๐Ÿ›‘ Stopping static server'); + // Ensure the server process is terminated even if the tests fail. + server.kill(); + } +} + +main().catch(err => { + console.error('โŒ Readability CI script failed:', err); + process.exit(1); +}); diff --git a/tests/e2e/readability.vrt.test.ts b/tests/e2e/readability.vrt.test.ts new file mode 100644 index 00000000..89bc18a9 --- /dev/null +++ b/tests/e2e/readability.vrt.test.ts @@ -0,0 +1,22 @@ +import { expect, test } from '@playwright/test' + +const FIXTURE_ROUTES = [ + '/essays/is-sqrt-of-squared-x-pm-x', + '/essays/scroll-depth-test', +] as const + +test.describe('Readability compatibility tests', () => { + for (const route of FIXTURE_ROUTES) { + test(`should be readerable for ${route}`, async ({ page }) => { + await page.goto(route, { waitUntil: 'domcontentloaded' }) + + // Evaluate readability check within the browser context using CDN module import. + const isReadable = await page.evaluate(async () => { + const { isProbablyReaderable } = await import('https://cdn.jsdelivr.net/npm/@mozilla/readability@0.5.0/+esm') + return isProbablyReaderable(document) + }) + + expect(isReadable).toBe(true) + }) + } +})