Skip to content

Conversation

@chmurson
Copy link
Collaborator

@chmurson chmurson commented Oct 6, 2025

Summary by CodeRabbit

  • New Features
    • No user-facing changes.
  • Tests
    • Added Playwright visual snapshot tests (light/dark), with local and Docker runs, stable test state helpers, and npm scripts to run/update tests.
    • Added Vitest config to exclude tooling paths.
  • CI
    • New GitHub Actions workflow to run visual regression tests and attach reports/comments on PRs.
  • Documentation
    • Added guides for running/updating snapshot tests locally and via Docker.
  • Chores
    • Added Docker/Docker Compose artifacts and ignored test build files.
    • Added testing hooks (data-testid) to tabs and note editor.

@netlify
Copy link

netlify bot commented Oct 6, 2025

Deploy Preview for graypaper-reader ready!

Name Link
🔨 Latest commit 4e85ac0
🔍 Latest deploy log https://app.netlify.com/projects/graypaper-reader/deploys/68e4e7242ff490000724a015
😎 Deploy Preview https://deploy-preview-321--graypaper-reader.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link

coderabbitai bot commented Oct 6, 2025

Walkthrough

Adds Playwright snapshot testing infrastructure (configs, tests, Docker, CI workflow), local and Docker test scripts, test artifacts ignores, small UI test hooks (data-testid), a Vitest config to exclude tools, and documentation for running and troubleshooting snapshot tests.

Changes

Cohort / File(s) Summary
Documentation
README.md, tools/snapshot-tests/README.md
New docs describing running snapshot tests locally and via Docker, environment variables, updating snapshots, CI usage, and troubleshooting.
UI test hooks
src/components/NoteManager/components/Note.tsx, src/components/Tabs/Tabs.tsx
Added data-testid attributes to enable stable selectors for tests; no control-flow or logic changes.
Playwright config & tests
tools/snapshot-tests/playwright.config.ts, tools/snapshot-tests/tests/basic-snapshots.spec.ts, tools/snapshot-tests/tests/utils/add-notes-to-local-storage.ts
New Playwright config (optional webServer via env, light/dark projects, tracing), test suite with visual snapshots, and localStorage seeding utility.
Snapshot-tests package
tools/snapshot-tests/package.json, tools/snapshot-tests/.gitignore
New package scripts (test:with-server, test:local, etc.) and gitignore entries for Playwright artifacts.
Docker support for tests
Dockerfile.snapshot-tests, docker-compose.yml, .dockerignore
Multi-stage Dockerfile and compose services to run/update snapshot tests in containers; repository-level .dockerignore updated.
CI workflow for visual regression
.github/workflows/visual-regression.yml
New GitHub Actions workflow: builds test image, runs tests in container, uploads artifacts, and posts PR comments with report link/status.
Node workflow formatting
.github/workflows/node.js.yml
Minor YAML formatting/indentation adjustments only.
Repo scripts & config
package.json, vitest.config.ts, shared/links-metadata/package.json
Added Docker-related npm scripts, Vitest config to exclude tools/**/*, and added @tsconfig/node20 devDependency.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Developer
  participant Shell as Shell
  participant Docker as Docker Engine
  participant Container as Test Container
  participant Playwright as Playwright Runner
  participant Server as Dev Server (Vite)
  participant App as Web App

  Dev->>Shell: npm run docker:test / docker:test:update
  Shell->>Docker: build image (Dockerfile.snapshot-tests)
  Docker->>Container: run container (env: CI, PLAYWRIGHT_*)
  Container->>Playwright: npm run test (Playwright)
  alt PLAYWRIGHT_START_SERVER=true
    Playwright->>Server: start dev server (PORT)
    Server->>App: serve built app
  end
  Playwright->>App: launch browser, capture snapshots (light/dark)
  Playwright-->>Container: emit test-results & playwright-report
  Container-->>Dev: exit code + mounted artifacts
Loading
sequenceDiagram
  autonumber
  actor GitHub as GH
  participant WF as Actions Workflow
  participant Docker as Docker
  participant Container as Test Container
  participant Playwright as Playwright
  participant Artifacts as Artifacts Service
  participant Bot as PR Commenter

  GH->>WF: Push/PR to main
  WF->>Docker: build playwright-test image
  WF->>Container: run container, execute tests
  Container->>Playwright: run snapshot tests
  Playwright-->>Artifacts: upload reports (test-results, html)
  WF->>Bot: post/update PR comment with report URL & status
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I tap my paw, the pixels gleam,
Snapshots hum inside a stream.
Tabs tagged tidy, notes hold fast,
Docker runs the tests at last.
Light and dark — the screens align; hop, pass, and pass! 🐰✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “Adding snapshot tests” directly and concisely captures the primary focus of the changeset, which centers on introducing Playwright-based snapshot test suites, related configuration, and tooling support for visual regression testing. It is specific enough for a reader to understand the main feature being added without unnecessary detail. The phrasing is clear, succinct, and aligned with the bulk of the modifications.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch adding-snapshot-tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (2)
tools/snapshot-tests/package.json (1)

7-7: Module type mismatch with TypeScript config.

The package is set to "type": "commonjs", but playwright.config.ts uses ES module syntax (import/export default). This works because TypeScript transpiles ES modules, but it creates inconsistency.

For clarity and modern conventions, consider setting the type to "module":

-  "type": "commonjs",
+  "type": "module",

Alternatively, if you prefer CommonJS, convert the config to use require() and module.exports.

tools/snapshot-tests/tests/snaphosts.spec.ts (1)

89-91: Simplify overly complex locator fallbacks.

The locators use multiple fallback selectors (e.g., combining data-testid, :has-text(), aria-label, and class names). This creates fragile tests that are hard to maintain.

Prefer a single, stable selector strategy:

  1. Best: Add data-testid attributes to the components (similar to how you added them to Tabs and Note components)
  2. Good: Use ARIA roles and labels
  3. Avoid: CSS classes and :has-text() which can break with minor UI changes

Example refactor for the GitHub button:

-      const githubButton = page.locator(
-        '[data-testid="github-dropdown"], button:has-text("GitHub"), [aria-label*="github"], .github',
-      );
+      const githubButton = page.locator('[data-testid="github-dropdown"]');

If data-testid isn't present, add it to the component. This makes tests more maintainable and aligns with the pattern you're already using for tabs and notes.

Also applies to: 117-119, 134-136, 165-167

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7845dde and 8fcf469.

⛔ Files ignored due to path filters (36)
  • package-lock.json is excluded by !**/package-lock.json
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/homepage-outline-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/homepage-outline-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/homepage-screenshot-1-chromium-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/homepage-screenshot-1-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/homepage-screenshot-1-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/notes-tab-edit-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/notes-tab-edit-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/notes-tab-initial-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/notes-tab-initial-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/search-initial-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/search-initial-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/search-with-query-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/search-with-query-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/search-with-results-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/search-with-results-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-github-after-hover-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-github-before-hover-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-github-expanded-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-github-expanded-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-github-hover-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-github-hover-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-github-option-hover-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-github-option-hover-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-more-clicked-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-more-clicked-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-more-settings-clicked-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-more-settings-clicked-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-notes-dropdown-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-notes-dropdown-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-notes-selected-off-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-notes-selected-off-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-notes-selected-on-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/topbar-notes-selected-on-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/workflow-start-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/snaphosts.spec.ts-snapshots/workflow-start-light-mode-darwin.png is excluded by !**/*.png
📒 Files selected for processing (8)
  • README.md (1 hunks)
  • src/components/NoteManager/components/Note.tsx (1 hunks)
  • src/components/Tabs/Tabs.tsx (1 hunks)
  • tools/snapshot-tests/.gitignore (1 hunks)
  • tools/snapshot-tests/package.json (1 hunks)
  • tools/snapshot-tests/playwright.config.ts (1 hunks)
  • tools/snapshot-tests/tests/snaphosts.spec.ts (1 hunks)
  • tools/snapshot-tests/tests/utils/add-notes-to-local-storage.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

⚙️ CodeRabbit configuration file

When reviewing Tailwind CSS classes, ensure they follow Tailwind 4.x conventions and suggest modern 4.x alternatives for deprecated patterns.

Files:

  • src/components/NoteManager/components/Note.tsx
  • tools/snapshot-tests/tests/utils/add-notes-to-local-storage.ts
  • tools/snapshot-tests/playwright.config.ts
  • src/components/Tabs/Tabs.tsx
  • tools/snapshot-tests/tests/snaphosts.spec.ts
🧬 Code graph analysis (1)
tools/snapshot-tests/tests/snaphosts.spec.ts (1)
tools/snapshot-tests/tests/utils/add-notes-to-local-storage.ts (1)
  • initialLocalStorage (34-43)
🪛 GitHub Actions: Node.js CI
tools/snapshot-tests/tests/snaphosts.spec.ts

[error] 21-21: Playwright Test did not expect test.describe() to be called here. This caused the test suite to fail during 'npm test'.

🪛 GitHub Check: build
tools/snapshot-tests/tests/snaphosts.spec.ts

[failure] 21-21: tools/snapshot-tests/tests/snaphosts.spec.ts
Error: Playwright Test did not expect test.describe() to be called here.
Most common reasons include:

  • You are calling test.describe() in a configuration file.
  • You are calling test.describe() in a file that is imported by the configuration file.
  • You have two different versions of @playwright/test. This usually happens
    when one of the dependencies in your package.json depends on @playwright/test.
    ❯ TestTypeImpl._currentSuite node_modules/playwright/lib/common/testType.js:74:13
    ❯ TestTypeImpl._describe node_modules/playwright/lib/common/testType.js:114:24
    ❯ Function.describe node_modules/playwright/lib/transform/transform.js:275:12
    ❯ tools/snapshot-tests/tests/snaphosts.spec.ts:21:6
🔇 Additional comments (3)
src/components/Tabs/Tabs.tsx (1)

118-118: LGTM! Clean test ID addition.

The data-testid attribute with the pattern tab-${t.name} provides clear, predictable selectors for snapshot tests without affecting functionality.

src/components/NoteManager/components/Note.tsx (1)

107-107: LGTM! Conditional test ID follows the button's behavior.

The conditional data-testid correctly reflects whether the button is in "save" or "edit" mode, making tests more readable and maintainable.

tools/snapshot-tests/tests/utils/add-notes-to-local-storage.ts (1)

7-7: Verify the future timestamps in test data.

The date fields contain timestamps from October 2025 (e.g., 1759742271192). If the application performs date-based filtering, sorting, or validation, these future dates could cause unexpected test behavior or false negatives.

Consider using timestamps relative to the current date or a fixed reference date from the past to ensure deterministic test behavior:

-      date: 1759742271192,
+      date: Date.now() - 86400000, // 1 day ago

Or use a fixed historical timestamp:

-      date: 1759742271192,
+      date: 1704067200000, // 2024-01-01

Also applies to: 17-17

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
tools/snapshot-tests/tests/basic-snapshots.spec.ts (2)

7-19: Consider consistent test setup across all tests.

The getCommonContext() function is only used in some tests (lines 35, 112, 129) but not others. This creates inconsistent test environments where some tests have pre-loaded localStorage (notes and labels) while others start with a clean state.

Consider whether all tests should use the same context setup for consistency, or document why certain tests require different setups.


89-91: Simplify locator strategy to reduce brittleness.

The locator uses multiple fallback selectors chained together, which makes it brittle and hard to maintain. When UI changes, it's unclear which selector should be updated.

Consider:

  1. Adding consistent data-testid attributes to UI elements (preferred)
  2. Using a single, specific selector
  3. If multiple selectors are needed for different environments, use separate test configurations

Similar patterns appear throughout the file (lines 99-100, 117-119, 134-136, 165-167).

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0619d32 and e640b4e.

📒 Files selected for processing (3)
  • README.md (1 hunks)
  • tools/snapshot-tests/playwright.config.ts (1 hunks)
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • README.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • tools/snapshot-tests/playwright.config.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

⚙️ CodeRabbit configuration file

When reviewing Tailwind CSS classes, ensure they follow Tailwind 4.x conventions and suggest modern 4.x alternatives for deprecated patterns.

Files:

  • tools/snapshot-tests/tests/basic-snapshots.spec.ts
🧬 Code graph analysis (1)
tools/snapshot-tests/tests/basic-snapshots.spec.ts (1)
tools/snapshot-tests/tests/utils/add-notes-to-local-storage.ts (1)
  • initialLocalStorage (34-43)
🔇 Additional comments (1)
tools/snapshot-tests/tests/basic-snapshots.spec.ts (1)

21-31: LGTM!

The homepage tests are well-structured. Good use of waitUntil: "networkidle" and document.fonts.ready to ensure page stability before taking screenshots.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
tools/snapshot-tests/tests/basic-snapshots.spec.ts (2)

4-5: Stop hardcoding the app origin.

Baking http://localhost:5173 into the test makes the suite environment-specific. Read the target host from Playwright’s baseURL (or an env var) so these tests run unchanged in CI/staging.

Apply this diff:

-const origin = "http://localhost:5173";
-const hostname = "http://localhost:5173/#/ab2cdbd?v=0.7.2";
+const origin = test.info().project.use.baseURL ?? process.env.SNAPSHOT_BASE_URL ?? "http://localhost:5173";
+const hostname = `${origin}/#/ab2cdbd?v=0.7.2`;

144-149: Use a stable locator for the “More” button.

button:has-text("...") is ambiguous; any overflow button with ellipsis will match and make the test flaky. Add a dedicated data-testid (or equivalent) and target that instead.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e640b4e and fd5a631.

⛔ Files ignored due to path filters (26)
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/homepage-outline-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/homepage-outline-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/notes-tab-edit-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/notes-tab-edit-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/notes-tab-initial-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/notes-tab-initial-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-initial-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-initial-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-with-query-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-with-query-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-with-results-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-with-results-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-github-expanded-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-github-expanded-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-github-option-hover-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-github-option-hover-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-more-clicked-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-more-clicked-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-more-settings-clicked-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-more-settings-clicked-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-dropdown-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-dropdown-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-selected-off-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-selected-off-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-selected-on-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-selected-on-light-mode-darwin.png is excluded by !**/*.png
📒 Files selected for processing (2)
  • src/components/Tabs/Tabs.tsx (2 hunks)
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/Tabs/Tabs.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

⚙️ CodeRabbit configuration file

When reviewing Tailwind CSS classes, ensure they follow Tailwind 4.x conventions and suggest modern 4.x alternatives for deprecated patterns.

Files:

  • tools/snapshot-tests/tests/basic-snapshots.spec.ts
🧬 Code graph analysis (1)
tools/snapshot-tests/tests/basic-snapshots.spec.ts (1)
tools/snapshot-tests/tests/utils/add-notes-to-local-storage.ts (1)
  • initialLocalStorage (34-43)

@chmurson chmurson force-pushed the adding-snapshot-tests branch from fc671a4 to b0a65e8 Compare October 6, 2025 20:35
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (5)
README.md (1)

38-38: Fix grammar in documentation.

"Visual snapshot tests checks" should be "Visual snapshot tests check" (verb agreement).

Apply this diff:

-Visual snapshot tests checks for visual regression.
+Visual snapshot tests check for visual regression.
tools/snapshot-tests/tests/basic-snapshots.spec.ts (4)

36-47: Close the browser context to prevent resource leaks.

The test creates a browser context but never closes it, which can lead to resource leaks and test instability.

Apply this diff:

   test("notes tab - initial state", async ({ browser }) => {
     const context = await browser.newContext(getCommonContext());
-
-    const page = await context.newPage();
-    await page.goto(hostname, { waitUntil: "networkidle" });
-    await page.evaluate(() => document.fonts.ready);
-    await page.click('[data-testid="tab-notes"]');
-    await page.locator('[data-testid="tab-content-notes"]').waitFor({ state: "visible" });
-    await expect(page).toHaveScreenshot("notes-tab-initial.png", { fullPage: true });
-    await page.click('[data-testid="edit-button"]', { timeout: 2500 });
-    await expect(page).toHaveScreenshot("notes-tab-edit.png", { fullPage: true });
+    try {
+      const page = await context.newPage();
+      await page.goto(hostname, { waitUntil: "networkidle" });
+      await page.evaluate(() => document.fonts.ready);
+      await page.click('[data-testid="tab-notes"]');
+      await page.locator('[data-testid="tab-content-notes"]').waitFor({ state: "visible" });
+      await expect(page).toHaveScreenshot("notes-tab-initial.png", { fullPage: true });
+      await page.click('[data-testid="edit-button"]', { timeout: 2500 });
+      await expect(page).toHaveScreenshot("notes-tab-edit.png", { fullPage: true });
+    } finally {
+      await context.close();
+    }
   });

101-114: Close the browser context to prevent resource leaks.

The test creates a browser context but never closes it, which can lead to resource leaks and test instability.

Apply this diff:

   test("notes dropdown - initial state", async ({ browser }) => {
     const context = await browser.newContext(getCommonContext());
-    const page = await context.newPage();
-    await page.goto(hostname, { waitUntil: "networkidle" });
-    await page.evaluate(() => document.fonts.ready);
-
-    const notesDropdown = page.locator(
-      '[data-testid="notes-dropdown"], button:has-text("Notes"), [aria-label*="notes"], .notes-dropdown',
-    );
-    if ((await notesDropdown.count()) > 0) {
-      await notesDropdown.first().click();
-
-      await expect(page).toHaveScreenshot("topbar-notes-dropdown.png", { fullPage: true });
+    try {
+      const page = await context.newPage();
+      await page.goto(hostname, { waitUntil: "networkidle" });
+      await page.evaluate(() => document.fonts.ready);
+
+      const notesDropdown = page.locator(
+        '[data-testid="notes-dropdown"], button:has-text("Notes"), [aria-label*="notes"], .notes-dropdown',
+      );
+      if ((await notesDropdown.count()) > 0) {
+        await notesDropdown.first().click();
+
+        await expect(page).toHaveScreenshot("topbar-notes-dropdown.png", { fullPage: true });
+      }
+    } finally {
+      await context.close();
     }
   });

117-140: Close the browser context to prevent resource leaks.

The test creates a browser context but never closes it, which can lead to resource leaks and test instability.

Apply this diff:

   test("selecting note on and off", async ({ browser }) => {
     const context = await browser.newContext(getCommonContext());
-    const page = await context.newPage();
-    await page.goto(hostname, { waitUntil: "networkidle" });
-    await page.evaluate(() => document.fonts.ready);
-
-    const notesDropdown = page.locator(
-      '[data-testid="notes-dropdown"], button:has-text("Notes"), [aria-label*="notes"], .notes-dropdown',
-    );
-    if ((await notesDropdown.count()) > 0) {
-      await notesDropdown.first().click();
-
-      const noteOptions = page.locator('[type="checkbox"], .note-option, [role="menuitemcheckbox"]');
-      if ((await noteOptions.count()) > 0) {
-        await noteOptions.first().click();
-
-        await expect(page).toHaveScreenshot("topbar-notes-selected-on.png", { fullPage: true });
-
-        await noteOptions.first().click();
-
-        await expect(page).toHaveScreenshot("topbar-notes-selected-off.png", { fullPage: true });
+    try {
+      const page = await context.newPage();
+      await page.goto(hostname, { waitUntil: "networkidle" });
+      await page.evaluate(() => document.fonts.ready);
+
+      const notesDropdown = page.locator(
+        '[data-testid="notes-dropdown"], button:has-text("Notes"), [aria-label*="notes"], .notes-dropdown',
+      );
+      if ((await notesDropdown.count()) > 0) {
+        await notesDropdown.first().click();
+
+        const noteOptions = page.locator('[type="checkbox"], .note-option, [role="menuitemcheckbox"]');
+        if ((await noteOptions.count()) > 0) {
+          await noteOptions.first().click();
+
+          await expect(page).toHaveScreenshot("topbar-notes-selected-on.png", { fullPage: true });
+
+          await noteOptions.first().click();
+
+          await expect(page).toHaveScreenshot("topbar-notes-selected-off.png", { fullPage: true });
+        }
       }
+    } finally {
+      await context.close();
     }
   });

148-149: Use a more specific selector for the menu button.

The generic selector button:has-text("...") may match multiple elements. Use a data-testid or more specific selector to ensure the correct button is clicked.

Apply this diff:

-      const moreButton = page.locator('button:has-text("...")');
+      const moreButton = page.locator('[data-testid="more-menu-button"]');

Or if a data-testid isn't available:

-      const moreButton = page.locator('button:has-text("...")');
+      const moreButton = page.locator('[aria-label="More options"]');
🧹 Nitpick comments (1)
tools/snapshot-tests/package.json (1)

13-14: Ensure cross-platform compatibility for npm scripts.

The inline environment variable syntax (e.g., PLAYWRIGHT_START_SERVER=true) won't work on Windows. Consider using the cross-env package for cross-platform compatibility or document that these scripts require Unix-like environments.

Option 1: Use cross-env (recommended for cross-platform support):

First, install cross-env:

npm install --save-dev cross-env

Then apply this diff:

-    "test:with-server": "PLAYWRIGHT_START_SERVER=true playwright test",
-    "test:local": "PLAYWRIGHT_START_SERVER=true PLAYWRIGHT_PORT=5173 PLAYWRIGHT_HOST=localhost playwright test"
+    "test:with-server": "cross-env PLAYWRIGHT_START_SERVER=true playwright test",
+    "test:local": "cross-env PLAYWRIGHT_START_SERVER=true PLAYWRIGHT_PORT=5173 PLAYWRIGHT_HOST=localhost playwright test"

Option 2: Document Unix-only requirement in README if Windows support is not needed.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd5a631 and b0a65e8.

⛔ Files ignored due to path filters (30)
  • package-lock.json is excluded by !**/package-lock.json
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/homepage-outline-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/homepage-outline-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/notes-tab-edit-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/notes-tab-edit-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/notes-tab-initial-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/notes-tab-initial-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-initial-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-initial-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-with-query-dark-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-with-query-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-with-query-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-with-query-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-with-results-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-with-results-light-mode-darwin.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-with-results-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-github-expanded-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-github-expanded-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-github-option-hover-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-github-option-hover-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-more-clicked-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-more-clicked-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-more-settings-clicked-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-more-settings-clicked-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-dropdown-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-dropdown-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-selected-off-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-selected-off-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-selected-on-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-selected-on-light-mode-linux.png is excluded by !**/*.png
📒 Files selected for processing (12)
  • .dockerignore (1 hunks)
  • .github/workflows/node.js.yml (1 hunks)
  • Dockerfile.playwright (1 hunks)
  • README.md (1 hunks)
  • docker-compose.yml (1 hunks)
  • package.json (1 hunks)
  • shared/links-metadata/package.json (1 hunks)
  • src/components/NoteManager/NoteManager.tsx (1 hunks)
  • tools/snapshot-tests/README.md (1 hunks)
  • tools/snapshot-tests/package.json (1 hunks)
  • tools/snapshot-tests/playwright.config.ts (1 hunks)
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • tools/snapshot-tests/README.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • Dockerfile.playwright
  • shared/links-metadata/package.json
  • package.json
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

⚙️ CodeRabbit configuration file

When reviewing Tailwind CSS classes, ensure they follow Tailwind 4.x conventions and suggest modern 4.x alternatives for deprecated patterns.

Files:

  • src/components/NoteManager/NoteManager.tsx
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts
  • tools/snapshot-tests/playwright.config.ts
🧬 Code graph analysis (1)
tools/snapshot-tests/tests/basic-snapshots.spec.ts (1)
tools/snapshot-tests/tests/utils/add-notes-to-local-storage.ts (1)
  • initialLocalStorage (34-43)
🪛 actionlint (1.7.7)
.github/workflows/node.js.yml

15-15: string should not be empty

(syntax-check)


51-51: the runner of "peaceiris/actions-gh-pages@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (2)
.dockerignore (1)

1-82: LGTM!

The .dockerignore file contains appropriate patterns for excluding unnecessary files from the Docker build context, following Node.js best practices.

tools/snapshot-tests/playwright.config.ts (1)

1-41: LGTM!

The Playwright configuration is well-structured with conditional server startup, appropriate retry/worker settings for CI, and separate projects for light/dark mode testing.

@chmurson chmurson force-pushed the adding-snapshot-tests branch from b0a65e8 to 91b4d28 Compare October 6, 2025 20:49
@github-actions
Copy link
Contributor

github-actions bot commented Oct 6, 2025

Visual Regression Test Report ✅ Passed

Github run id: 18309305378

🔗 Artifacts: Download

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/components/NoteManager/NoteManager.tsx (1)

85-86: Remove inappropriate placeholder text.

This inappropriate placeholder was already flagged in a previous review but remains unaddressed. The text "TWOJA STARA!!" is unprofessional and should be replaced with the original descriptive placeholder or another appropriate alternative.

Apply this diff to restore the original placeholder:

-          // placeholder="Add a note to the selected fragment. Math typesetting is supported! Use standard delimiters such as $...$, \[...\] or \begin{equation}...\end{equation}."
-          placeholder="TWOJA STARA!!"
+          placeholder="Add a note to the selected fragment. Math typesetting is supported! Use standard delimiters such as $...$, \[...\] or \begin{equation}...\end{equation}."
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b0a65e8 and 91b4d28.

⛔ Files ignored due to path filters (27)
  • package-lock.json is excluded by !**/package-lock.json
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/homepage-outline-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/homepage-outline-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/notes-tab-edit-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/notes-tab-edit-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/notes-tab-initial-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/notes-tab-initial-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-initial-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-initial-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-with-query-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-with-query-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-with-results-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/search-with-results-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-github-expanded-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-github-expanded-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-github-option-hover-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-github-option-hover-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-more-clicked-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-more-clicked-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-more-settings-clicked-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-more-settings-clicked-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-dropdown-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-dropdown-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-selected-off-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-selected-off-light-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-selected-on-dark-mode-linux.png is excluded by !**/*.png
  • tools/snapshot-tests/tests/basic-snapshots.spec.ts-snapshots/topbar-notes-selected-on-light-mode-linux.png is excluded by !**/*.png
📒 Files selected for processing (9)
  • .dockerignore (1 hunks)
  • .github/workflows/node.js.yml (1 hunks)
  • .github/workflows/visual-regression.yml (1 hunks)
  • Dockerfile.playwright (1 hunks)
  • README.md (1 hunks)
  • docker-compose.yml (1 hunks)
  • package.json (1 hunks)
  • shared/links-metadata/package.json (1 hunks)
  • src/components/NoteManager/NoteManager.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • package.json
  • .github/workflows/node.js.yml
  • docker-compose.yml
  • README.md
  • Dockerfile.playwright
  • .dockerignore
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

⚙️ CodeRabbit configuration file

When reviewing Tailwind CSS classes, ensure they follow Tailwind 4.x conventions and suggest modern 4.x alternatives for deprecated patterns.

Files:

  • src/components/NoteManager/NoteManager.tsx
🪛 actionlint (1.7.7)
.github/workflows/visual-regression.yml

48-48: the runner of "peaceiris/actions-gh-pages@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: visual-tests

@FluffyLabs FluffyLabs deleted a comment from github-actions bot Oct 6, 2025
@FluffyLabs FluffyLabs deleted a comment from github-actions bot Oct 6, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 91b4d28 and b8bf073.

📒 Files selected for processing (2)
  • .github/workflows/visual-regression.yml (1 hunks)
  • docker-compose.yml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docker-compose.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: visual-tests

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (7)
.github/workflows/visual-regression.yml (3)

22-29: Improve container stability for Chromium and simplify command.

Add shared memory to avoid browser crashes and use -w instead of cd.

-      - name: Run visual regression tests
-        run: |
-          docker run --rm \
+      - name: Run visual regression tests
+        run: |
+          docker run --rm --shm-size=1g \
             -v ${{ github.workspace }}/tools/snapshot-tests/test-results:/app/tools/snapshot-tests/test-results \
             -v ${{ github.workspace }}/tools/snapshot-tests/playwright-report:/app/tools/snapshot-tests/playwright-report \
             -e CI=true \
-            playwright-test \
-            sh -c "cd tools/snapshot-tests && npm run test"
+            -w /app/tools/snapshot-tests \
+            playwright-test \
+            npm run test

31-37: Also publish raw test-results (not only the HTML report).

If you want junit/json diagnostics, add a guarded upload for tools/snapshot-tests/test-results.

       - name: Upload Playwright Report
         uses: actions/upload-artifact@v4
         if: ${{ always() && hashFiles('tools/snapshot-tests/playwright-report/**') != '' }}
         with:
           name: playwright-report-${{ github.run_number }}
           path: tools/snapshot-tests/playwright-report/
           retention-days: 30
+
+      - name: Upload Test Results
+        uses: actions/upload-artifact@v4
+        if: ${{ always() && hashFiles('tools/snapshot-tests/test-results/**') != '' }}
+        with:
+          name: test-results-${{ github.run_number }}
+          path: tools/snapshot-tests/test-results/
+          retention-days: 30

43-51: Optional: include a direct link to the Playwright report artifact.

You already link the run; adding a deep link improves UX.

-            const body = `## Visual Regression Test Report ${testStatus}
-
-            Github run id: ${{github.run_id}}
-
-            🔗 **Artifacts**: [Download](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
-            `
+            const body = `## Visual Regression Test Report ${testStatus}
+
+            Github run id: ${{github.run_id}}
+
+            🔗 **Artifacts**: [Run page](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
+            `
Dockerfile.snapshot-tests (4)

32-35: Prefer npm ci for reproducible, faster installs in CI.

Locks to package-lock and avoids mutation.

-RUN cd tools/snapshot-tests && npm install
+RUN cd tools/snapshot-tests && npm ci

49-49: No-op RUN layer.

RUN cd shared/links-metadata does nothing in a separate layer; remove it to keep the image lean.

-RUN cd shared/links-metadata

3-9: Verify necessity of installing Node 22 over Playwright base image.

Mixing Node runtimes increases size and risk. If Node 22 isn’t required, drop this and use the Node bundled in the Playwright image.

-RUN apt-get update && apt-get install -y --no-install-recommends \
-    git \
-    curl \
-    && rm -rf /var/lib/apt/lists/* \
-    && curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
-    && apt-get install -y nodejs \
-    && rm -rf /var/lib/apt/lists/*
+RUN apt-get update && apt-get install -y --no-install-recommends git curl \
+    && rm -rf /var/lib/apt/lists/*

If Node 22 is required, consider using a Playwright base tag that already bundles the desired Node version to avoid manual installs.


42-48: Avoid copying .git into the image.

It bloats layers and may leak history. Only copy build inputs.

-COPY .git ./.git
-COPY .gitmodules ./
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b8803c and 2c03df6.

📒 Files selected for processing (4)
  • .github/workflows/visual-regression.yml (1 hunks)
  • Dockerfile.snapshot-tests (1 hunks)
  • docker-compose.yml (1 hunks)
  • package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • package.json
  • docker-compose.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: visual-tests

@chmurson chmurson merged commit f453093 into main Oct 7, 2025
8 of 9 checks passed
@chmurson chmurson deleted the adding-snapshot-tests branch October 7, 2025 10:14
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c03df6 and 4e85ac0.

📒 Files selected for processing (2)
  • .github/workflows/visual-regression.yml (1 hunks)
  • Dockerfile.snapshot-tests (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • Dockerfile.snapshot-tests
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: visual-tests

Comment on lines +49 to +54
const body = `## Visual Regression Test Report ${testStatus}

Github run id: ${{github.run_id}}

🔗 **Artifacts**: [Download](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Dedent the PR comment body to avoid code-block rendering

The template literal inherits the 12-space YAML indentation, so every line after the header is treated as a Markdown code block. The report link ends up inside that block and is no longer clickable, breaking the workflow’s UX. Build the string without leading spaces (e.g., join an array of lines) so the comment renders normally.

-            const body = `## Visual Regression Test Report ${testStatus}
-
-            Github run id: ${{github.run_id}}
-
-            🔗 **Artifacts**: [Download](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
-            `
+            const body = [
+              `## Visual Regression Test Report ${testStatus}`,
+              '',
+              `GitHub run id: ${{ github.run_id }}`,
+              '',
+              `🔗 **Artifacts**: [Download](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})`
+            ].join('\n');
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const body = `## Visual Regression Test Report ${testStatus}
Github run id: ${{github.run_id}}
🔗 **Artifacts**: [Download](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
`
const body = [
`## Visual Regression Test Report ${testStatus}`,
'',
`GitHub run id: ${{ github.run_id }}`,
'',
`🔗 **Artifacts**: [Download](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})`
].join('\n');
🤖 Prompt for AI Agents
.github/workflows/visual-regression.yml around lines 49 to 54: the template
literal for the PR comment body is indented in YAML so each line gains leading
spaces and renders as a Markdown code block; rebuild the body without leading
spaces (for example, construct it by joining an array of lines or using
unindented concatenation) so the header and subsequent lines are not prefixed by
spaces and the artifact link renders as a normal clickable link.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant