Skip to content

[codex] Fix project health checks#531

Open
yusufm wants to merge 2 commits intosiddharthvaddem:mainfrom
yusufm:codex/fix-project-health-checks
Open

[codex] Fix project health checks#531
yusufm wants to merge 2 commits intosiddharthvaddem:mainfrom
yusufm:codex/fix-project-health-checks

Conversation

@yusufm
Copy link
Copy Markdown
Contributor

@yusufm yusufm commented May 3, 2026

Summary

  • split browser-only exporter tests out of the jsdom unit test run and fix stale unit assertions/imports
  • sync i18n locale files with the English baseline and add CI coverage for unit, i18n, browser, and Electron e2e checks
  • remove the direct uuid dependency, re-enable Electron web security for the editor window, and stabilize Electron e2e teardown

Validation

  • npm run lint
  • npx tsc --noEmit
  • npm run test
  • npm run test:browser
  • npm run i18n:check
  • npm audit --omit=dev
  • npm run build-vite
  • npm run test:e2e
  • git diff --check

Summary by CodeRabbit

  • Tests

    • Added i18n validation and an E2E job to CI; improved E2E shutdown stability and test helpers.
    • Updated unit/integration test discovery to exclude browser-specific tests.
    • Expanded tutorial translation tests to more locales; adjusted a visual helper test expectation.
  • Internationalization

    • Reorganized French, Turkish, and Traditional Chinese settings translations; added/removed specific locale keys.
  • Bug Fixes

    • Restored web security for the editor window.
  • Chores

    • Removed an unused dependency.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 3, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8d9bc129-2d1b-4004-ad7f-fa91c2988834

📥 Commits

Reviewing files that changed from the base of the PR and between e048c05 and 36c87f6.

📒 Files selected for processing (1)
  • tests/e2e/gif-export.spec.ts

📝 Walkthrough

Walkthrough

This PR replaces uuidv4() with crypto.randomUUID() and removes the uuid dependency; removes an explicit webSecurity: false flag from the editor BrowserWindow; memoizes a cleanup helper in the screen-recorder hook; expands/adjusts several i18n locale files and tests; tightens Vitest discovery and augments CI with i18n checks and an Electron E2E job; improves Playwright Electron shutdown logic and updates a blur-test expectation.

Changes

UUID Modernization & Security

Layer / File(s) Summary
Dependency Removal
package.json
Removes uuid dependency ("uuid": "^13.0.0").
Core Implementation
src/components/video-editor/timeline/TimelineEditor.tsx
Replaces uuidv4() usage with crypto.randomUUID() for keyframe ID generation; removes uuid import.
Web Security Hardening
electron/windows.ts
Removes webSecurity: false from the editor window webPreferences.

i18n Locale Restructuring

Layer / File(s) Summary
Locale File Updates
src/i18n/locales/fr/settings.json, src/i18n/locales/zh-TW/settings.json, src/i18n/locales/tr/launch.json, src/i18n/locales/tr/settings.json
Moves/remaps zoom-speed keys into a top-level speed section and adds/adjusts zoom.focusMode and Turkish audio/language keys; removes several noise-reduction keys from Turkish files.
Test Coverage Expansion
src/i18n/__tests__/tutorialHelpTranslations.test.ts
Adds ja-JP and zh-TW dialog imports and includes them in dialogsByLocale for key validation.

useScreenRecorder Hook Optimization

Layer / File(s) Summary
Hook Refactor
src/hooks/useScreenRecorder.ts
Introduces safeHideCountdownOverlay as a useCallback-memoized async helper and updates the useEffect cleanup to depend on it (removes prior non-memoized definition).

Test Infrastructure & E2E Improvements

Layer / File(s) Summary
CI Workflow Updates
.github/workflows/ci.yml
Adds npm run i18n:check and npm run test to the test job; adds a new e2e (Electron E2E) job that runs npm ci, npm run build-vite, and xvfb-run npm run test:e2e.
Test Configuration
vitest.config.ts
Adds test.exclude = ["src/**/*.browser.test.{ts,tsx}"] to avoid discovering browser-specific tests in Vitest.
E2E Test Robustness
tests/e2e/gif-export.spec.ts
Adds waitForProcessExit and closeElectronApp(app) helpers that race process exit with a timeout and SIGKILL fallback; reorders/wraps HUD→editor handoff with a pre-created editorWindowPromise and try/catch; uses closeElectronApp(app) in teardown.
Test Assertion Update
src/lib/blurEffects.test.ts
Changes expected black blur overlay color alpha from 0.18 to 0.56.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • siddharthvaddem

"kinda cursed, now a bit cleaner" —
crypto births ids with a quiet hum,
locales shuffle like cards in a drum,
hooks memoize so cleanups run,
CI runs e2e under xvfb's drum,
and one webSecurity flag quietly succumbs. 🚀

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title '[codex] Fix project health checks' is vague and doesn't clearly convey what the actual changes are—it doesn't summarize the main objectives like UUID removal, web security re-enabling, or i18n/CI improvements. Consider a more specific title that highlights key changes, e.g., 'Remove uuid dependency, re-enable web security, and fix project health checks' or similar.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The PR description covers the key changes well (uuid removal, web security, i18n sync, CI setup, e2e teardown) and includes comprehensive validation steps, but doesn't follow the template sections (motivation, type of change, screenshots, testing steps).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

@yusufm yusufm marked this pull request as ready for review May 3, 2026 19:57
@yusufm yusufm requested a review from siddharthvaddem as a code owner May 3, 2026 19:57
Copy link
Copy Markdown
Contributor

@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 (5)
src/i18n/__tests__/tutorialHelpTranslations.test.ts (1)

37-46: 💤 Low value

nit: key order in dialogsByLocale diverges from SUPPORTED_LOCALES

zh-TW and ja-JP are appended at the end instead of matching the canonical order in SUPPORTED_LOCALES. not a bug — the satisfies constraint catches any gaps at compile time — but keeping them in sync makes future diffs easier to grok.

✨ Optional ordering alignment
 const dialogsByLocale = {
 	en: enDialogs,
 	"zh-CN": zhCNDialogs,
+	"zh-TW": zhTWDialogs,
 	es: esDialogs,
 	fr: frDialogs,
 	tr: trDialogs,
 	"ko-KR": koKRDialogs,
-	"zh-TW": zhTWDialogs,
 	"ja-JP": jaJPDialogs,
 } satisfies Record<Locale, { tutorial: Record<string, unknown> }>;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/i18n/__tests__/tutorialHelpTranslations.test.ts` around lines 37 - 46,
The object literal dialogsByLocale is not in the same key order as the canonical
SUPPORTED_LOCALES, which makes diffs harder to read; reorder the entries in
dialogsByLocale to exactly match the sequence in SUPPORTED_LOCALES (use the same
locale strings and order), keeping the same values (enDialogs, zhCNDialogs,
zhTWDialogs, esDialogs, frDialogs, trDialogs, koKRDialogs, jaJPDialogs) so the
satisfies Record<Locale, { tutorial: Record<string, unknown> }> check still
passes.
src/hooks/useScreenRecorder.ts (1)

411-417: 💤 Low value

LGTM — clean fix for the stale-closure + excess re-run problem.

Memoizing safeHideCountdownOverlay with useCallback(…, []) is exactly right. Before this, a plain const was recreated every render; including it in the effect's dep array (line 461) would have re-registered the onStopRecordingFromTray listener on every render, and omitting it would have been a stale-closure lint violation. Both hazards gone now.

One nit: window.electronAPI is accessed without optional chaining on line 413, while several other call sites in the same file use window.electronAPI?.xxx (e.g. lines 305, 422). The try/catch makes it safe, but it's kinda inconsistent. Up to you whether you want to unify the style.

🧹 Optional: align with the optional-chaining pattern used elsewhere
-		await window.electronAPI.hideCountdownOverlay(runId);
+		await window.electronAPI?.hideCountdownOverlay(runId);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/hooks/useScreenRecorder.ts` around lines 411 - 417, Update
safeHideCountdownOverlay to use optional chaining when calling the Electron API
to match the style elsewhere: in the useCallback for safeHideCountdownOverlay,
replace the direct access window.electronAPI.hideCountdownOverlay(runId) with a
guarded call (e.g. window.electronAPI?.hideCountdownOverlay) or an early-return
if window.electronAPI is undefined, so the call site is consistent with other
uses like the ones around lines referencing window.electronAPI?.xxx; keep the
existing try/catch and behaviour otherwise.
src/components/video-editor/timeline/TimelineEditor.tsx (1)

833-838: Move UUID generation outside the state updater to avoid double-invocation in StrictMode

crypto.randomUUID() is called inside the setKeyframes functional updater. In React 18 + StrictMode (development), React double-invokes state updaters and discards the first result — so two UUIDs get generated but only one is used. No bug in production, but cleaner to generate the ID outside the updater and capture it in the closure:

✨ Suggested fix
- setKeyframes((prev) => [...prev, { id: crypto.randomUUID(), time }]);
+ const id = crypto.randomUUID();
+ setKeyframes((prev) => [...prev, { id, time }]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/video-editor/timeline/TimelineEditor.tsx` around lines 833 -
838, The addKeyframe callback currently calls crypto.randomUUID() inside the
setKeyframes functional updater which can produce duplicate/extra UUIDs in React
18 StrictMode; fix by generating the id before calling setKeyframes (e.g., const
id = crypto.randomUUID()) and then use that id inside the updater when appending
the new keyframe, keeping the existing time calculation and duplicate-time
guard; refer to addKeyframe, setKeyframes, keyframes and crypto.randomUUID when
making the change.
tests/e2e/gif-export.spec.ts (1)

97-104: ⚡ Quick win

Don't swallow non-teardown failures here.

This catch eats real failures from setCurrentVideoPath() / switchToEditor() too, so a broken IPC path turns into a generic 15s window timeout and the root cause disappears. I'd only ignore the expected context-loss case and rethrow the rest.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/e2e/gif-export.spec.ts` around lines 97 - 104, The try/catch around
hudWindow.evaluate is swallowing all failures from
window.electronAPI.setCurrentVideoPath() and switchToEditor(); update the catch
to only ignore the expected “page/context torn down” errors and rethrow any
other errors. Concretely, inside the catch for the hudWindow.evaluate call
inspect the caught error (from the evaluate call) and if its message indicates a
destroyed execution context or closed target (e.g. contains substrings like
"Execution context was destroyed", "Target closed", or "page is closed") then
swallow it, otherwise rethrow the error so real IPC/logic failures from
setCurrentVideoPath or switchToEditor surface in the test failure.
.github/workflows/ci.yml (1)

43-60: ⚡ Quick win

We're still leaving two health checks manual.

The PR validation list includes npm audit --omit=dev and git diff --check, but this workflow still won't enforce either. If the point here is "project health checks", I'd wire those in too so green CI actually means the full checklist passed.

possible follow-up
   test:
     name: Test
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v4
       - uses: actions/setup-node@v4
         with:
           node-version: 22
           cache: npm
       - run: npm ci
+      - run: npm audit --omit=dev
+      - run: git diff --check
       - run: npm run i18n:check
       - run: npm run test
       - run: npm run test:browser:install
       - run: npm run test:browser
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yml around lines 43 - 60, The workflow is missing
enforcement of two project health checks: run the commands npm audit --omit=dev
and git diff --check as CI steps so failures block merges; add these steps
(using the literal commands npm audit --omit=dev and git diff --check) after the
existing npm ci step in both the primary job's steps (the earlier npm ci run)
and the e2e job (after the e2e job's npm ci) so the workflow will fail when
those checks fail.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@vitest.config.ts`:
- Line 9: The test.exclude assignment overrides Vitest's built-in excludes (like
/node_modules/ and /.git/), so keep those defaults and add your browser-only
pattern instead: use configDefaults.exclude and merge or append the glob
"src/**/*.browser.test.{ts,tsx}" rather than replacing test.exclude in the
vitest config (refer to test.exclude, configDefaults.exclude and the browser
glob to locate where to change).

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 43-60: The workflow is missing enforcement of two project health
checks: run the commands npm audit --omit=dev and git diff --check as CI steps
so failures block merges; add these steps (using the literal commands npm audit
--omit=dev and git diff --check) after the existing npm ci step in both the
primary job's steps (the earlier npm ci run) and the e2e job (after the e2e
job's npm ci) so the workflow will fail when those checks fail.

In `@src/components/video-editor/timeline/TimelineEditor.tsx`:
- Around line 833-838: The addKeyframe callback currently calls
crypto.randomUUID() inside the setKeyframes functional updater which can produce
duplicate/extra UUIDs in React 18 StrictMode; fix by generating the id before
calling setKeyframes (e.g., const id = crypto.randomUUID()) and then use that id
inside the updater when appending the new keyframe, keeping the existing time
calculation and duplicate-time guard; refer to addKeyframe, setKeyframes,
keyframes and crypto.randomUUID when making the change.

In `@src/hooks/useScreenRecorder.ts`:
- Around line 411-417: Update safeHideCountdownOverlay to use optional chaining
when calling the Electron API to match the style elsewhere: in the useCallback
for safeHideCountdownOverlay, replace the direct access
window.electronAPI.hideCountdownOverlay(runId) with a guarded call (e.g.
window.electronAPI?.hideCountdownOverlay) or an early-return if
window.electronAPI is undefined, so the call site is consistent with other uses
like the ones around lines referencing window.electronAPI?.xxx; keep the
existing try/catch and behaviour otherwise.

In `@src/i18n/__tests__/tutorialHelpTranslations.test.ts`:
- Around line 37-46: The object literal dialogsByLocale is not in the same key
order as the canonical SUPPORTED_LOCALES, which makes diffs harder to read;
reorder the entries in dialogsByLocale to exactly match the sequence in
SUPPORTED_LOCALES (use the same locale strings and order), keeping the same
values (enDialogs, zhCNDialogs, zhTWDialogs, esDialogs, frDialogs, trDialogs,
koKRDialogs, jaJPDialogs) so the satisfies Record<Locale, { tutorial:
Record<string, unknown> }> check still passes.

In `@tests/e2e/gif-export.spec.ts`:
- Around line 97-104: The try/catch around hudWindow.evaluate is swallowing all
failures from window.electronAPI.setCurrentVideoPath() and switchToEditor();
update the catch to only ignore the expected “page/context torn down” errors and
rethrow any other errors. Concretely, inside the catch for the
hudWindow.evaluate call inspect the caught error (from the evaluate call) and if
its message indicates a destroyed execution context or closed target (e.g.
contains substrings like "Execution context was destroyed", "Target closed", or
"page is closed") then swallow it, otherwise rethrow the error so real IPC/logic
failures from setCurrentVideoPath or switchToEditor surface in the test failure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1bb9bd07-eb2b-44a9-bb20-3ac077136f6a

📥 Commits

Reviewing files that changed from the base of the PR and between 7e00cdb and e048c05.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (13)
  • .github/workflows/ci.yml
  • electron/windows.ts
  • package.json
  • src/components/video-editor/timeline/TimelineEditor.tsx
  • src/hooks/useScreenRecorder.ts
  • src/i18n/__tests__/tutorialHelpTranslations.test.ts
  • src/i18n/locales/fr/settings.json
  • src/i18n/locales/tr/launch.json
  • src/i18n/locales/tr/settings.json
  • src/i18n/locales/zh-TW/settings.json
  • src/lib/blurEffects.test.ts
  • tests/e2e/gif-export.spec.ts
  • vitest.config.ts
💤 Files with no reviewable changes (5)
  • electron/windows.ts
  • package.json
  • src/i18n/locales/zh-TW/settings.json
  • src/i18n/locales/tr/settings.json
  • src/i18n/locales/fr/settings.json

Comment thread vitest.config.ts
globals: true,
environment: "jsdom",
include: ["src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
exclude: ["src/**/*.browser.test.{ts,tsx}"],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Vitest 4.x config: does setting test.excludeindefineConfigreplace the default exclude list, and isconfigDefaults.exclude the supported way to extend it?

💡 Result:

Yes, setting test.exclude in defineConfig replaces the default exclude list. The official Vitest documentation explicitly states: "manually setting exclude in your config will replace the default value." The default is ['/node_modules/', '/.git/']. Yes, configDefaults.exclude is the supported way to extend it. The docs provide this exact example: import { configDefaults, defineConfig } from 'vitest/config' export default defineConfig({ test: { exclude: [ ...configDefaults.exclude, 'packages/template/*', './temp/', ], }, }) This behavior applies to Vitest 4.x, as confirmed by the current official documentation at vitest.dev/config/exclude (published 2026-03-04) and v4.vitest.dev/config/exclude.

Citations:


Preserve Vitest's default excludes here.

Setting test.exclude manually replaces Vitest's default exclude list (which includes /node_modules/ and /.git/), so this drops the built-in patterns and can make the test runner pick up folders it shouldn't. lowkey risky for CI noise/perf. Fold your browser glob into configDefaults.exclude instead per the official docs.

nit: cleaner fix
-import { defineConfig } from "vitest/config";
+import { configDefaults, defineConfig } from "vitest/config";
 
 export default defineConfig({
 	test: {
 		globals: true,
 		environment: "jsdom",
 		include: ["src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
-		exclude: ["src/**/*.browser.test.{ts,tsx}"],
+		exclude: [...configDefaults.exclude, "src/**/*.browser.test.{ts,tsx}"],
 	},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@vitest.config.ts` at line 9, The test.exclude assignment overrides Vitest's
built-in excludes (like /node_modules/ and /.git/), so keep those defaults and
add your browser-only pattern instead: use configDefaults.exclude and merge or
append the glob "src/**/*.browser.test.{ts,tsx}" rather than replacing
test.exclude in the vitest config (refer to test.exclude, configDefaults.exclude
and the browser glob to locate where to change).

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