fix: make web e2e use the desktop shell contract#417
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThis PR separates visual shell identity into an optional ChangesShell Identity Separation & Web Desktop Shell Rendering
Sequence Diagram(s)sequenceDiagram
participant Entry as entry.tsx
participant Platform as context/platform
participant Layout as pages/layout.tsx
participant Titlebar as components/titlebar.tsx
participant CSS as index.css
Entry->>Platform: initialize runtime platform + shell ({kind:"desktop", os})
Platform-->>Layout: provide platform + shell via usePlatform()
Platform-->>Titlebar: provide platform + shell via usePlatform()
Layout->>Layout: apply shellAttrs() -> set `data-shell` / `data-shell-os`
Titlebar->>Titlebar: evaluate isDesktopShell()/isMacShell() -> set classes/drag-region
CSS->>Layout: apply `[data-shell="desktop"]` styles
CSS->>Titlebar: apply `[data-shell="desktop"][data-shell-os="macos"]` rules
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Review rate limit: 6/10 reviews remaining, refill in 18 minutes and 34 seconds. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/app/playwright.config.ts`:
- Around line 31-34: The test run can be flaky because VITE_PAWWORK_SHELL_OS is
force-set to "macos" even when reuseExistingServer (reuseExistingServer/reuse)
is true and the existing dev server may have been started with a different OS
value; change the config so the env.VITE_PAWWORK_SHELL_OS is only injected when
not reusing an existing server (i.e., guard the env assignment with the
reuse/reuseExistingServer flag) or alternatively detect reuseExistingServer and
skip/assertions that require macOS; update the logic around
reuseExistingServer/reuse and env to conditionally set VITE_PAWWORK_SHELL_OS or
bypass macOS-specific checks (referencing reuseExistingServer/reuse and
env.VITE_PAWWORK_SHELL_OS).
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: c8644c9f-e8de-4c0e-842a-39e753d0637f
📒 Files selected for processing (10)
packages/app/e2e/app/shell-frame.spec.tspackages/app/playwright.config.tspackages/app/src/components/titlebar.tsxpackages/app/src/context/platform.tsxpackages/app/src/entry.tsxpackages/app/src/index.csspackages/app/src/pages/layout.tsxpackages/app/src/shell-frame-contract.test.tspackages/desktop-electron/src/main/window-chrome.test.tspackages/desktop-electron/src/renderer/index.tsx
There was a problem hiding this comment.
Code Review
This pull request introduces a visual shell contract to decouple the application's runtime identity from its appearance, allowing the web platform to adopt a desktop-like shell. Key changes include the addition of a shell property to the Platform context, new helper functions for shell detection, and updates to CSS and components to use data-shell attributes. Feedback focuses on further reducing logic duplication by extracting shell kind and OS resolution into shared helper functions and applying them within the Titlebar and Layout components.
There was a problem hiding this comment.
🧹 Nitpick comments (2)
packages/app/src/shell-frame-contract.test.ts (2)
62-64: ⚡ Quick winMake favicon color assertions case-insensitive.
Hex casing in SVG can change during formatting/minification without changing branding. Case-insensitive matching keeps the contract semantic.
Suggested tightening
- expect(favicon).toContain("#FF6B2B") - expect(favicon).toContain("#FFF8F0") - expect(favicon).not.toContain("#131010") + expect(favicon).toMatch(/#ff6b2b/i) + expect(favicon).toMatch(/#fff8f0/i) + expect(favicon).not.toMatch(/#131010/i)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/app/src/shell-frame-contract.test.ts` around lines 62 - 64, The assertions on favicon hex colors are currently case-sensitive; update the checks in shell-frame-contract.test (the expectations that reference favicon) to perform case-insensitive matching—either convert favicon to a consistent case (e.g., const normalized = favicon.toLowerCase() and assert normalized contains '#ff6b2b' and '#fff8f0' and does not contain '#131010') or use case-insensitive regex (e.g., expect(favicon).toMatch(/#ff6b2b/i), etc.) so formatting/minification-driven casing changes won’t break the contract test.
48-54: ⚡ Quick winStrengthen web-runtime contract assertion to avoid partial-match false positives.
Current checks can pass even if
platform: "web"and desktop shell wiring are not in the sameplatformobject shape. Consider asserting the object contract in one structural match (and optionally asserting no desktop runtime identity in that object).Suggested tightening
- expect(entry).toContain('platform: "web"') - expect(entry).toContain('shell: { kind: "desktop"') - expect(entry).toContain("getShellOs") + expect(entry).toMatch( + /const\s+platform:\s*Platform\s*=\s*\{[\s\S]*?platform:\s*"web"[\s\S]*?shell:\s*\{\s*kind:\s*"desktop",\s*os:\s*getShellOs\(\)\s*\}/, + )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/app/src/shell-frame-contract.test.ts` around lines 48 - 54, The current test uses separate contains checks that can match fragments in different places; update the assertions to assert the platform object's shape in a single structural match so the "platform: \"web\"" and absence of a desktop shell identity appear together (e.g., parse or regex-match the exported `platform` object string and assert it contains something like platform: "web" along with no desktop shell wiring), and keep the other exports (`getShellOs`, `PlatformShell`, `isDesktopShell`, `isMacShell`, `isWindowsShell`) asserted as before; target the same symbols (`entry`, `platform`, `getShellOs`, `PlatformShell`, `isDesktopShell`, `isMacShell`, `isWindowsShell`) when updating the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/app/src/shell-frame-contract.test.ts`:
- Around line 62-64: The assertions on favicon hex colors are currently
case-sensitive; update the checks in shell-frame-contract.test (the expectations
that reference favicon) to perform case-insensitive matching—either convert
favicon to a consistent case (e.g., const normalized = favicon.toLowerCase() and
assert normalized contains '#ff6b2b' and '#fff8f0' and does not contain
'#131010') or use case-insensitive regex (e.g.,
expect(favicon).toMatch(/#ff6b2b/i), etc.) so formatting/minification-driven
casing changes won’t break the contract test.
- Around line 48-54: The current test uses separate contains checks that can
match fragments in different places; update the assertions to assert the
platform object's shape in a single structural match so the "platform: \"web\""
and absence of a desktop shell identity appear together (e.g., parse or
regex-match the exported `platform` object string and assert it contains
something like platform: "web" along with no desktop shell wiring), and keep the
other exports (`getShellOs`, `PlatformShell`, `isDesktopShell`, `isMacShell`,
`isWindowsShell`) asserted as before; target the same symbols (`entry`,
`platform`, `getShellOs`, `PlatformShell`, `isDesktopShell`, `isMacShell`,
`isWindowsShell`) when updating the test.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 8aae4b36-1a25-4af4-8531-277712faad31
⛔ Files ignored due to path filters (2)
packages/ui/src/assets/favicon/favicon-v3.svgis excluded by!**/*.svgpackages/ui/src/assets/favicon/favicon.svgis excluded by!**/*.svg
📒 Files selected for processing (1)
packages/app/src/shell-frame-contract.test.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/app/src/shell-frame-contract.test.ts`:
- Around line 53-55: The test's regex in shell-frame-contract.test.ts is too
order-sensitive (it assumes shell properties appear as kind then os); update the
expectation around the existing expect(entry).toMatch(...) to use an
order-independent pattern (e.g., use lookahead assertions or separate checks) so
it only asserts platform: "web" and that shell contains kind: "desktop" and os:
getShellOs() regardless of property order; modify the regex in the
expect(entry).toMatch call to verify the presence of those tokens rather than
their sequence.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 7ea8c008-8000-4b55-ba7e-b76be371acd2
📒 Files selected for processing (4)
packages/app/src/components/titlebar.tsxpackages/app/src/context/platform.tsxpackages/app/src/pages/layout.tsxpackages/app/src/shell-frame-contract.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/app/src/context/platform.tsx
- packages/app/src/pages/layout.tsx
Summary
Make the Web runtime keep
platform: "web"while rendering through the Desktop visual shell contract. Layout, titlebar, and shell CSS now key visual appearance fromplatform.shell, exposedata-shell/data-shell-os, and Web Playwright E2E pins the shell OS to macOS through a runtime override so the main GUI safety net exercises the shipped desktop geometry even when Playwright reuses an existing dev server.Also updates inherited OpenCode favicon assets to PawWork branding, because the Web preview is part of the same browser-facing shell surface being validated here.
Why
#269 moved from a visual parity issue to a GUI test-confidence issue after the #412/#413 regressions. Web E2E is the broadest UI safety net, but it previously rendered the Web shell rather than the Desktop shell users run in Electron.
Related Issue
Closes #269
Human Review Status
Pending. A human should make the final merge decision after reviewing the final diff and verification evidence. Do not merge until
desktop-smokeis fully green.Review Focus
Please check:
platform.platformremains the runtime identity (webordesktop)platform.shellowns visual shell appearance and OS-specific shell geometryRisk Notes
Low-to-medium UI shell risk. This changes the Web visual shell path, shared shell data attributes, and Web favicon assets, but does not change route shapes, preload IPC, updater behavior, native dialogs, or packaged resource checks.
How To Verify
Screenshots or Recordings
Not attached. This PR intentionally reuses the existing Desktop shell visuals and verifies the visible geometry through Playwright assertions (
data-platform=web,data-shell=desktop,data-shell-os=macos, and 44px titlebar height within a 43.5-44.5px tolerance). It also verifies Web-only capability behavior by checking Electron-only update/open-directory actions are disabled and the browser-safe project picker fallback still opens.Checklist
dev, and my PR title and commit messages use Conventional Commits in EnglishSummary by CodeRabbit
Tests
Bug Fixes
Refactor
UX