From 071ce390e9fe95e584b3ea10b393f19688b7561f Mon Sep 17 00:00:00 2001 From: Arjun Komath Date: Sun, 2 Nov 2025 18:01:31 +1100 Subject: [PATCH 1/7] Migrate checkly tests --- .github/workflows/page-e2e-tests.yml | 45 ++++++++++ apps/page/.gitignore | 3 + apps/page/package.json | 5 +- apps/page/playwright.config.js | 20 +++++ apps/page/tests/page.spec.js | 49 +++++++++++ pnpm-lock.yaml | 118 ++++++++++++++++++--------- 6 files changed, 200 insertions(+), 40 deletions(-) create mode 100644 .github/workflows/page-e2e-tests.yml create mode 100644 apps/page/playwright.config.js create mode 100644 apps/page/tests/page.spec.js diff --git a/.github/workflows/page-e2e-tests.yml b/.github/workflows/page-e2e-tests.yml new file mode 100644 index 0000000..5f88404 --- /dev/null +++ b/.github/workflows/page-e2e-tests.yml @@ -0,0 +1,45 @@ +name: Page E2E Tests + +on: + workflow_dispatch: + +jobs: + test: + name: Run Playwright Tests + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 8 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Install Playwright Browsers + run: pnpm --filter @changes-page/page exec playwright install --with-deps chromium + + - name: Run Playwright tests + run: pnpm --filter @changes-page/page test + + - name: Upload screenshots + uses: actions/upload-artifact@v4 + if: always() + with: + name: screenshots + path: | + apps/page/screenshot.jpg + apps/page/latestPostResponse-screenshot.jpg + retention-days: 7 + if-no-files-found: ignore diff --git a/apps/page/.gitignore b/apps/page/.gitignore index 3978add..9f9e664 100644 --- a/apps/page/.gitignore +++ b/apps/page/.gitignore @@ -7,6 +7,9 @@ # testing /coverage +/test-results/ +/playwright-report/ +/playwright/.cache/ # next.js /.next/ diff --git a/apps/page/package.json b/apps/page/package.json index 9620617..58ae351 100644 --- a/apps/page/package.json +++ b/apps/page/package.json @@ -6,7 +6,9 @@ "dev": "next dev --port 3001", "build": "mkdir -p public/v1 && minify widget/widget.js > public/v1/widget.js && next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "test": "playwright test", + "test:headed": "playwright test --headed" }, "dependencies": { "@arcjet/next": "1.0.0-alpha.20", @@ -50,6 +52,7 @@ }, "devDependencies": { "@next/bundle-analyzer": "^13.1.6", + "@playwright/test": "^1.48.0", "@types/cors": "^2.8.13", "@types/node": "^17.0.41", "@types/nprogress": "^0.2.3", diff --git a/apps/page/playwright.config.js b/apps/page/playwright.config.js new file mode 100644 index 0000000..d671c72 --- /dev/null +++ b/apps/page/playwright.config.js @@ -0,0 +1,20 @@ +const { defineConfig, devices } = require("@playwright/test"); + +module.exports = defineConfig({ + testDir: "./tests", + fullyParallel: true, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : undefined, + reporter: "html", + use: { + trace: "on-first-retry", + screenshot: "only-on-failure", + }, + projects: [ + { + name: "chromium", + use: { ...devices["Desktop Chrome"] }, + }, + ], +}); diff --git a/apps/page/tests/page.spec.js b/apps/page/tests/page.spec.js new file mode 100644 index 0000000..db90528 --- /dev/null +++ b/apps/page/tests/page.spec.js @@ -0,0 +1,49 @@ +const { expect, test, request } = require("@playwright/test"); + +test("visit page and take screenshot", async ({ page }) => { + const targetUrl = process.env.ENVIRONMENT_URL || "https://hey.changes.page"; + + const response = await page.goto(targetUrl); + + expect(response.status()).toBeLessThan(400); + + await page.screenshot({ path: "screenshot.jpg" }); + + const context = await request.newContext({ + baseURL: targetUrl, + }); + + const latest = await context.get(`/latest.json`); + expect(latest.ok()).toBeTruthy(); + + const latestPost = await latest.json(); + const latestPostResponse = await page.goto(latestPost.url); + expect(latestPostResponse.status()).toBeLessThan(400); + await page.screenshot({ path: "latestPostResponse-screenshot.jpg" }); +}); + +test("verify APIs", async () => { + const targetUrl = process.env.ENVIRONMENT_URL || "https://hey.changes.page"; + + const context = await request.newContext({ + baseURL: targetUrl, + }); + + const posts = await context.get(`/changes.json`); + expect(posts.ok()).toBeTruthy(); + + const robots = await context.get(`/robots.txt`); + expect(robots.ok()).toBeTruthy(); + + const sitemap = await context.get(`/sitemap.xml`); + expect(sitemap.ok()).toBeTruthy(); + + const markdown = await context.get(`/changes.md`); + expect(markdown.ok()).toBeTruthy(); + + const rss = await context.get(`/rss.xml`); + expect(rss.ok()).toBeTruthy(); + + const atom = await context.get(`/atom.xml`); + expect(atom.ok()).toBeTruthy(); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 08d41e0..d146f6f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,16 +12,16 @@ importers: dependencies: fumadocs-core: specifier: 15.3.0 - version: 15.3.0(@types/react@18.3.1)(next@15.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 15.3.0(@types/react@18.3.1)(next@15.3.1(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) fumadocs-mdx: specifier: 11.6.3 - version: 11.6.3(acorn@8.14.1)(fumadocs-core@15.3.0(@types/react@18.3.1)(next@15.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@15.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + version: 11.6.3(acorn@8.14.1)(fumadocs-core@15.3.0(@types/react@18.3.1)(next@15.3.1(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@15.3.1(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) fumadocs-ui: specifier: 15.3.0 - version: 15.3.0(@types/react-dom@18.3.1)(@types/react@18.3.1)(next@15.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@4.1.6) + version: 15.3.0(@types/react-dom@18.3.1)(@types/react@18.3.1)(next@15.3.1(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@4.1.6) next: specifier: 15.3.1 - version: 15.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 15.3.1(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: 18.3.1 version: 18.3.1 @@ -58,7 +58,7 @@ importers: dependencies: '@arcjet/next': specifier: 1.0.0-alpha.20 - version: 1.0.0-alpha.20(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + version: 1.0.0-alpha.20(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@changes-page/supabase': specifier: workspace:* version: link:../../packages/supabase @@ -76,7 +76,7 @@ importers: version: 1.0.6(react@18.3.1) '@sentry/nextjs': specifier: ^7.93.0 - version: 7.120.3(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 7.120.3(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@supabase/supabase-js': specifier: ^2.39.2 version: 2.49.4 @@ -106,13 +106,13 @@ importers: version: 6.1.0 next: specifier: ^14.2.25 - version: 14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-seo: specifier: ^5.15.0 - version: 5.15.0(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 5.15.0(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-themes: specifier: ^0.2.1 - version: 0.2.1(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 0.2.1(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) nprogress: specifier: ^0.2.0 version: 0.2.0 @@ -174,6 +174,9 @@ importers: '@next/bundle-analyzer': specifier: ^13.1.6 version: 13.5.11 + '@playwright/test': + specifier: ^1.48.0 + version: 1.56.1 '@types/cors': specifier: ^2.8.13 version: 2.8.18 @@ -221,7 +224,7 @@ importers: dependencies: '@arcjet/next': specifier: 1.0.0-alpha.20 - version: 1.0.0-alpha.20(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + version: 1.0.0-alpha.20(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@changes-page/supabase': specifier: workspace:* version: link:../../packages/supabase @@ -251,7 +254,7 @@ importers: version: 1.1.0 '@sentry/nextjs': specifier: ^7.77.0 - version: 7.120.3(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 7.120.3(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@supabase/auth-ui-react': specifier: ^0.4.7 version: 0.4.7(@supabase/supabase-js@2.49.4) @@ -272,7 +275,7 @@ importers: version: 1.9.0 '@vercel/analytics': specifier: ^1.5.0 - version: 1.5.0(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 1.5.0(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@vercel/og': specifier: ^0.0.20 version: 0.0.20 @@ -314,13 +317,13 @@ importers: version: 2.1.35 next: specifier: ^14.2.25 - version: 14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-seo: specifier: ^6.4.0 - version: 6.6.0(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 6.6.0(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-sitemap: specifier: ^4.2.3 - version: 4.2.3(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + version: 4.2.3(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) nprogress: specifier: ^0.2.0 version: 0.2.0 @@ -1194,6 +1197,11 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@playwright/test@1.56.1': + resolution: {integrity: sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==} + engines: {node: '>=18'} + hasBin: true + '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} @@ -3024,6 +3032,11 @@ packages: fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -4282,6 +4295,16 @@ packages: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} + playwright-core@1.56.1: + resolution: {integrity: sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.56.1: + resolution: {integrity: sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==} + engines: {node: '>=18'} + hasBin: true + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -5332,7 +5355,7 @@ snapshots: dependencies: '@arcjet/sprintf': 1.0.0-alpha.20 - '@arcjet/next@1.0.0-alpha.20(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': + '@arcjet/next@1.0.0-alpha.20(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0))(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': dependencies: '@arcjet/env': 1.0.0-alpha.20 '@arcjet/headers': 1.0.0-alpha.20 @@ -5341,7 +5364,7 @@ snapshots: '@arcjet/protocol': 1.0.0-alpha.20 '@connectrpc/connect-web': 1.4.0(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.4.0(@bufbuild/protobuf@1.10.0)) arcjet: 1.0.0-alpha.20 - next: 14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) transitivePeerDependencies: - '@bufbuild/protobuf' - '@connectrpc/connect' @@ -5869,6 +5892,10 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@playwright/test@1.56.1': + dependencies: + playwright: 1.56.1 + '@polka/url@1.0.0-next.29': {} '@radix-ui/number@1.1.1': {} @@ -6316,7 +6343,7 @@ snapshots: '@sentry/utils': 7.120.3 localforage: 1.10.0 - '@sentry/nextjs@7.120.3(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@sentry/nextjs@7.120.3(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: '@rollup/plugin-commonjs': 24.0.0(rollup@2.79.2) '@sentry/core': 7.120.3 @@ -6328,7 +6355,7 @@ snapshots: '@sentry/vercel-edge': 7.120.3 '@sentry/webpack-plugin': 1.21.0 chalk: 3.0.0 - next: 14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 resolve: 1.22.8 rollup: 2.79.2 @@ -6869,9 +6896,9 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.7.2': optional: true - '@vercel/analytics@1.5.0(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@vercel/analytics@1.5.0(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': optionalDependencies: - next: 14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 '@vercel/og@0.0.20': @@ -7934,10 +7961,13 @@ snapshots: fs.realpath@1.0.0: {} + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true - fumadocs-core@15.3.0(@types/react@18.3.1)(next@15.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + fumadocs-core@15.3.0(@types/react@18.3.1)(next@15.3.1(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@formatjs/intl-localematcher': 0.6.1 '@orama/orama': 3.1.6 @@ -7955,14 +7985,14 @@ snapshots: shiki: 3.4.0 unist-util-visit: 5.0.0 optionalDependencies: - next: 15.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.3.1(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) transitivePeerDependencies: - '@types/react' - supports-color - fumadocs-mdx@11.6.3(acorn@8.14.1)(fumadocs-core@15.3.0(@types/react@18.3.1)(next@15.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@15.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): + fumadocs-mdx@11.6.3(acorn@8.14.1)(fumadocs-core@15.3.0(@types/react@18.3.1)(next@15.3.1(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@15.3.1(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): dependencies: '@mdx-js/mdx': 3.1.0(acorn@8.14.1) '@standard-schema/spec': 1.0.0 @@ -7971,11 +8001,11 @@ snapshots: esbuild: 0.25.4 estree-util-value-to-estree: 3.4.0 fast-glob: 3.3.3 - fumadocs-core: 15.3.0(@types/react@18.3.1)(next@15.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + fumadocs-core: 15.3.0(@types/react@18.3.1)(next@15.3.1(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) gray-matter: 4.0.3 js-yaml: 4.1.0 lru-cache: 11.1.0 - next: 15.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.3.1(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) picocolors: 1.1.1 unist-util-visit: 5.0.0 zod: 3.24.4 @@ -7983,7 +8013,7 @@ snapshots: - acorn - supports-color - fumadocs-ui@15.3.0(@types/react-dom@18.3.1)(@types/react@18.3.1)(next@15.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@4.1.6): + fumadocs-ui@15.3.0(@types/react-dom@18.3.1)(@types/react@18.3.1)(next@15.3.1(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@4.1.6): dependencies: '@radix-ui/react-accordion': 1.2.10(@types/react-dom@18.3.1)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@radix-ui/react-collapsible': 1.1.10(@types/react-dom@18.3.1)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -7996,9 +8026,9 @@ snapshots: '@radix-ui/react-slot': 1.2.2(@types/react@18.3.1)(react@18.3.1) '@radix-ui/react-tabs': 1.1.11(@types/react-dom@18.3.1)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) class-variance-authority: 0.7.1 - fumadocs-core: 15.3.0(@types/react@18.3.1)(next@15.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + fumadocs-core: 15.3.0(@types/react@18.3.1)(next@15.3.1(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) lodash.merge: 4.6.2 - next: 15.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.3.1(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-themes: 0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) postcss-selector-parser: 7.1.0 react: 18.3.1 @@ -9499,29 +9529,29 @@ snapshots: negotiator@1.0.0: {} - next-seo@5.15.0(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next-seo@5.15.0(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - next: 14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - next-seo@6.6.0(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next-seo@6.6.0(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - next: 14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - next-sitemap@4.2.3(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): + next-sitemap@4.2.3(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): dependencies: '@corex/deepmerge': 4.0.43 '@next/env': 13.5.11 fast-glob: 3.3.3 minimist: 1.2.8 - next: 14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - next-themes@0.2.1(next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next-themes@0.2.1(next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - next: 14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -9530,7 +9560,7 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - next@14.2.28(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@14.2.28(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@next/env': 14.2.28 '@swc/helpers': 0.5.5 @@ -9551,11 +9581,12 @@ snapshots: '@next/swc-win32-arm64-msvc': 14.2.28 '@next/swc-win32-ia32-msvc': 14.2.28 '@next/swc-win32-x64-msvc': 14.2.28 + '@playwright/test': 1.56.1 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros - next@15.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@15.3.1(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@next/env': 15.3.1 '@swc/counter': 0.1.3 @@ -9575,6 +9606,7 @@ snapshots: '@next/swc-linux-x64-musl': 15.3.1 '@next/swc-win32-arm64-msvc': 15.3.1 '@next/swc-win32-x64-msvc': 15.3.1 + '@playwright/test': 1.56.1 sharp: 0.34.1 transitivePeerDependencies: - '@babel/core' @@ -9742,6 +9774,14 @@ snapshots: pirates@4.0.7: {} + playwright-core@1.56.1: {} + + playwright@1.56.1: + dependencies: + playwright-core: 1.56.1 + optionalDependencies: + fsevents: 2.3.2 + possible-typed-array-names@1.1.0: {} postcss-import@15.1.0(postcss@8.5.3): From 24589bc9412ab20c47687311f1ba28b506302295 Mon Sep 17 00:00:00 2001 From: Arjun Komath Date: Sun, 2 Nov 2025 18:04:52 +1100 Subject: [PATCH 2/7] Update pnpm version --- .github/workflows/page-e2e-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/page-e2e-tests.yml b/.github/workflows/page-e2e-tests.yml index 5f88404..3caa7cf 100644 --- a/.github/workflows/page-e2e-tests.yml +++ b/.github/workflows/page-e2e-tests.yml @@ -16,7 +16,7 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v4 with: - version: 8 + version: 10 - name: Setup Node.js uses: actions/setup-node@v4 From 9871c3c9c0a147fa70a56c2688dc358c33e6d3a5 Mon Sep 17 00:00:00 2001 From: Arjun Komath Date: Sat, 15 Nov 2025 09:45:15 +1100 Subject: [PATCH 3/7] Update landing page --- apps/web/components/marketing/features.tsx | 10 +- apps/web/components/marketing/hero.tsx | 10 +- apps/web/pages/index.tsx | 311 +----------------- .../web/public/images/hero/app-screenshot.png | Bin 235920 -> 341280 bytes 4 files changed, 14 insertions(+), 317 deletions(-) diff --git a/apps/web/components/marketing/features.tsx b/apps/web/components/marketing/features.tsx index 09a8ce9..370c338 100644 --- a/apps/web/components/marketing/features.tsx +++ b/apps/web/components/marketing/features.tsx @@ -93,15 +93,15 @@ export default function Features() { open-source {" "} - solution revolutionizing{" "} + platform for{" "} - changelog + changelogs {" "} and{" "} - roadmap - {" "} - management. + roadmaps + + , built for modern teams.

diff --git a/apps/web/components/marketing/hero.tsx b/apps/web/components/marketing/hero.tsx index 4f0c861..b08d7a4 100644 --- a/apps/web/components/marketing/hero.tsx +++ b/apps/web/components/marketing/hero.tsx @@ -112,11 +112,11 @@ export default function Hero({ stars = null }: { stars?: string | null }) {

- Our open-source platform empowers you to publish changelog pages and - interactive roadmaps. Share what you've built and what's - coming next. Notify users via email, gather feedback with voting, - track analytics, and enjoy a host of additional features. Kickstart - your page in just a few minutes! + Our open-source platform empowers you to share what you've + built with changelogs and what's coming next with roadmaps. + Notify users via email, gather feedback with voting, track + analytics, and enjoy a host of additional features. Kickstart your + page in just a few minutes!

diff --git a/apps/web/pages/index.tsx b/apps/web/pages/index.tsx index f1fb03e..1121495 100644 --- a/apps/web/pages/index.tsx +++ b/apps/web/pages/index.tsx @@ -1,7 +1,5 @@ -import { ServerIcon, ShieldCheckIcon, UserIcon } from "@heroicons/react/solid"; import dynamic from "next/dynamic"; import Head from "next/head"; -import Link from "next/link"; import FooterComponent from "../components/layout/footer.component"; import HeaderComponent from "../components/layout/header.component"; import Features from "../components/marketing/features"; @@ -22,7 +20,7 @@ export default function Index({ addons, unit_amount, stars }) { {/* FAQ Schema for SEO */}