Skip to content

fix(mobile): hydration-safe code wrap default, anchor action mobile styles, code-renderer tests#30

Merged
baanish merged 8 commits into
mainfrom
cursor/mobile-toolbar-wrap-e5a6
Apr 15, 2026
Merged

fix(mobile): hydration-safe code wrap default, anchor action mobile styles, code-renderer tests#30
baanish merged 8 commits into
mainfrom
cursor/mobile-toolbar-wrap-e5a6

Conversation

@baanish
Copy link
Copy Markdown
Owner

@baanish baanish commented Apr 8, 2026

Three issues raised in review on the original mobile toolbar PR.

SSR/CSR hydration fix — code-renderer.tsx

window.matchMedia was called inside the useState initializer, producing false on the server and potentially true on the client, causing a hydration mismatch. State now initializes deterministically to compact; a useEffect after mount enables wrap when (max-width: 640px) matches:

const [wrapLines, setWrapLines] = useState(compact);

useEffect(() => {
  if (compact || !window.matchMedia) return;
  if (window.matchMedia(MOBILE_CODE_MEDIA_QUERY).matches) {
    setWrapLines(true);
  }
}, [compact]);

Anchor action mobile styles — globals.css

.artifact-action:not(a) was excluding anchor-based action elements from the mobile flex/padding/overflow rules. Changed to .artifact-action and merged the separate button.artifact-action { max-width: 100% } into the single rule so all action variants (buttons and anchors) get consistent treatment at ≤640px.

CodeRenderer tests — tests/components/code-renderer.test.tsx

Added 4 tests: wide viewport → "Enable wrap" initial state, narrow viewport → "Disable wrap" after mount effect, toggle changes label, compact mode hides the toolbar.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed toolbar label truncation and layout issues on narrow mobile viewports.
  • Improvements

    • Enhanced responsive toolbar behavior with horizontal scrolling and better wrapping across viewers.
    • Code wrap control now remembers user choice, adapts to viewport changes, and honors manual overrides.
  • Tests

    • Added unit and end-to-end tests covering wrap control, responsive toolbar layouts, and compact-mode behavior.
  • Documentation

    • Clarified testing coverage guidance for mobile toolbar and default wrap checks.

- Scope flex/ellipsis rules to toolbar buttons so labels do not clip;
  pair raw/rendered toggle on one row with horizontal scroll fallback.
- Add overflow-x on code/diff/csv/json renderer toolbars at <=640px.
- Default CodeMirror line wrapping on when viewport is <=640px (compact
  unchanged); desktop still starts with wrap off.

Co-authored-by: Aanish Bhirud <baanish@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 8, 2026

Warning

Rate limit exceeded

@cursor[bot] has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 55 minutes and 27 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 55 minutes and 27 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a0bc1b5b-11a3-44b4-8abc-a38470a292f7

📥 Commits

Reviewing files that changed from the base of the PR and between cf729f1 and 1840872.

📒 Files selected for processing (3)
  • src/app/globals.css
  • src/components/renderers/code-renderer.tsx
  • tests/components/code-renderer.test.tsx
📝 Walkthrough

Walkthrough

Mobile toolbar CSS updated for wrapping, truncation, and horizontal scrolling; CodeRenderer now persists wrap preference and listens to a 640px media query; unit and Playwright tests added/extended to validate wrap and toolbar behavior; vitest config and an e2e helper timeout option were adjusted; docs updated.

Changes

Cohort / File(s) Summary
Responsive Toolbar Styling
src/app/globals.css
Add mobile-specific rules: max-width/min-width, flex-wrap, horizontal scrolling (overflow-x: auto, iOS momentum), thin scrollbar styling, single-line truncation, targeted overrides for .viewer-toolbar, .artifact-action, .diff-view-toggle, and renderer toolbars; extra override for ≤360px.
Wrap Preference & Media Listener
src/components/renderers/code-renderer.tsx
Add useLayoutEffect, MOBILE_CODE_MEDIA_QUERY, and wrapPreferenceRef (`"auto"
Unit Tests for CodeRenderer
tests/components/code-renderer.test.tsx
New Vitest+RTL tests with mocked CodeMirror and language utils, controllable window.matchMedia helper; verify initial wrap state by viewport, button label toggling, auto-updates when no manual preference, persistence after manual toggle, and absence of wrap control in compact mode.
Playwright e2e Tests & Helper
tests/e2e/viewer.spec.ts, tests/e2e/helpers.ts
Add mobile UX Playwright tests for wrap control visibility and toolbar toggle layout at narrow viewports; waitForViewerState gains optional options?: { timeout?: number } and uses it for assertion timeout.
Test Docs and Config
docs/testing.md, vitest.config.ts
Docs: clarify Playwright responsibility includes mobile toolbar and default code-wrap checks. Vitest: set esbuild JSX runtime to automatic.

Sequence Diagram

sequenceDiagram
    participant User
    participant CodeRenderer
    participant MediaQuery
    participant WrapPrefRef

    rect rgba(100,150,200,0.5)
    Note over CodeRenderer,MediaQuery: Initialization (mount, not compact)
    CodeRenderer->>WrapPrefRef: read/init ("auto" | "on" | "off")
    CodeRenderer->>MediaQuery: register matchMedia("(max-width: 640px)")
    MediaQuery-->>CodeRenderer: emit initial matches state
    CodeRenderer->>CodeRenderer: set wrapLines based on pref & matches
    end

    rect rgba(200,150,100,0.5)
    Note over User,CodeRenderer: User toggles wrap
    User->>CodeRenderer: click wrap button
    CodeRenderer->>WrapPrefRef: set to "on" or "off"
    CodeRenderer->>CodeRenderer: update wrapLines accordingly
    end

    rect rgba(150,200,100,0.5)
    Note over MediaQuery,CodeRenderer: Viewport change
    MediaQuery-->>CodeRenderer: change event
    alt WrapPrefRef == "auto"
        CodeRenderer->>CodeRenderer: update wrapLines to match media.matches
    else WrapPrefRef == "on" or "off"
        CodeRenderer->>CodeRenderer: ignore media change (preserve user choice)
    end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Toolbars fold and scroll, labels trim to fit,
I toggle wrap, remember each little bit,
Media whispers narrow, wide — I listen, not replace,
Tests hop in to prove the pace,
A rabbit's nibble keeps the user's grace. 🌿

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and specifically summarizes the main changes: hydration-safe code wrap behavior, mobile styles for actions, and test additions.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/mobile-toolbar-wrap-e5a6

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.

@baanish baanish marked this pull request as ready for review April 8, 2026 22:27
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 8, 2026

Deploying agent-render with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1840872
Status: ✅  Deploy successful!
Preview URL: https://c9aed2bb.agent-render.pages.dev
Branch Preview URL: https://cursor-mobile-toolbar-wrap-e.agent-render.pages.dev

View logs

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves the mobile viewing experience in the artifact viewer by addressing (1) toolbar button clipping on narrow screens and (2) the default line-wrapping behavior for code artifacts on small viewports.

Changes:

  • Updates the mobile (≤640px) toolbar layout rules to avoid flex-induced label clipping and to add horizontal overflow handling.
  • Adjusts CodeRenderer to default wrapLines based on compact mode or a mobile-width media query.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/components/renderers/code-renderer.tsx Initializes code line-wrapping based on a 640px media query when not in compact mode.
src/app/globals.css Refines mobile toolbar flex behavior to prevent button label clipping and enables horizontal scrolling for toolbars.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +24 to +35
const NARROW_CODE_BREAKPOINT = 640;
const MOBILE_CODE_MEDIA_QUERY = `(max-width: ${NARROW_CODE_BREAKPOINT}px)`;

function getDefaultWrapLines(compact: boolean) {
if (compact) {
return true;
}
if (typeof window === "undefined") {
return false;
}
return window.matchMedia(MOBILE_CODE_MEDIA_QUERY).matches;
}
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

Initializing wrapLines from window.matchMedia in the useState initializer can cause an SSR/CSR hydration mismatch: the server render always returns false (no window), while narrow clients may render with wrap enabled on first paint (changing the toolbar label and editor config). Consider keeping the initial state deterministic (e.g., compact) and then syncing to the media query in a useEffect after mount, or using useSyncExternalStore with a safe server snapshot. Also consider guarding window.matchMedia existence (tests/non-browser environments) before calling it.

Copilot uses AI. Check for mistakes.
Comment on lines 167 to 170
export function CodeRenderer({ artifact, compact = false, onReady }: CodeRendererProps) {
const hostRef = useRef<HTMLDivElement | null>(null);
const [wrapLines, setWrapLines] = useState(compact);
const [wrapLines, setWrapLines] = useState(() => getDefaultWrapLines(compact));
const [languageExtension, setLanguageExtension] = useState<Awaited<ReturnType<typeof loadLanguageSupport>>>(null);
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

The new default wrap behavior is responsive to (max-width: 640px) but there are no component tests covering it. Consider adding a CodeRenderer test (similar to tests/components/diff-renderer.test.tsx) that stubs window.matchMedia and asserts the initial button label/state for narrow vs wide viewports, plus that compact still forces wrapping.

Copilot uses AI. Check for mistakes.
Comment thread src/app/globals.css Outdated
Comment on lines +1896 to +1906
/* Avoid flex-shrink on toolbar buttons so labels are not clipped; pair rows only inside raw/rendered toggle */
.artifact-action:not(a) {
flex: 0 0 auto;
min-height: 2.55rem;
padding: 0.46rem 0.65rem;
font-size: 0.71rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-width: 0;
}
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

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

In the 640px breakpoint, switching from .artifact-action to .artifact-action:not(a) means anchor-based actions won’t receive the mobile sizing/overflow rules (min-height, padding, font-size, ellipsis). There are existing <a className="artifact-action"> usages (e.g. link-creator “Open in new tab”), so this may lead to inconsistent button sizing on mobile. Consider including a.artifact-action in the rule (or targeting the toolbar context more narrowly) so all action variants get consistent mobile treatment.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 3 additional findings.

Open in Devin Review

@baanish
Copy link
Copy Markdown
Owner Author

baanish commented Apr 9, 2026

@copilot apply changes based on the comments in this thread

…es, code-renderer tests

Agent-Logs-Url: https://github.com/baanish/agent-render/sessions/28d4f0a2-dd44-4cee-9c7d-7af53206edf5

Co-authored-by: baanish <47579874+baanish@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 9, 2026

@copilot apply changes based on the comments in this thread

Applied all three changes in commit 09c544c:

  1. Hydration fix (code-renderer.tsx): Removed window.matchMedia from the useState initializer. State now starts as compact (deterministic on server and client), and a useEffect runs after mount to enable wrap when the viewport matches (max-width: 640px). Also added an explicit React import required for JSX in the test environment.

  2. CSS anchor fix (globals.css): Changed .artifact-action:not(a).artifact-action so anchor-based actions (e.g. "Open in new tab") receive the same mobile flex, padding, font-size, and overflow rules as button actions. Merged the separate button.artifact-action { max-width: 100% } into the single rule.

  3. Tests (tests/components/code-renderer.test.tsx): Added 4 tests covering: wide viewport → "Enable wrap" default, narrow viewport → "Disable wrap" after mount, toggle changes label, compact mode hides toolbar entirely.

Copilot AI changed the title fix(mobile): toolbar clipping and default code wrap on narrow viewports fix(mobile): hydration-safe code wrap default, anchor action mobile styles, code-renderer tests Apr 9, 2026
if (window.matchMedia(MOBILE_CODE_MEDIA_QUERY).matches) {
setWrapLines(true);
}
}, [compact]);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: Missing media query listener - The useEffect only checks matchMedia once at mount but doesn't listen for viewport changes. If the user resizes the window from wide to narrow after mount, wrapLines won't update to reflect the new viewport width.

@kilo-code-bot
Copy link
Copy Markdown

kilo-code-bot Bot commented Apr 9, 2026

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 0

Changes Verified

The current diff includes all the fixes from previous reviews:

  1. CodeRenderer (src/components/renderers/code-renderer.tsx):

    • useLayoutEffect with proper media query listener (addEventListener("change"))
    • wrapPreferenceRef to persist user preference across viewport changes
    • Fallback to document.documentElement.classList.contains("dark") when resolvedTheme is undefined
  2. CSS (src/app/globals.css):

    • Mobile toolbar improvements with proper selector scoping (.viewer-toolbar .artifact-action)
    • JSON renderer toolbar also included in mobile fixes
    • Proper 360px breakpoint rules for very narrow viewports
  3. Tests:

    • Unit tests for code-renderer wrap behavior
    • 3 new E2E tests for mobile toolbar and code wrap

Files Reviewed (6 files)

  • docs/testing.md - Documentation
  • src/app/globals.css - Mobile toolbar CSS
  • src/components/renderers/code-renderer.tsx - Hydration-safe wrap
  • tests/components/code-renderer.test.tsx - Unit tests
  • tests/e2e/helpers.ts - Test helper
  • tests/e2e/viewer.spec.ts - E2E tests

Fix these issues in Kilo Cloud


Reviewed by minimax-m2.5 · 360,670 tokens

devin-ai-integration[bot]

This comment was marked as resolved.

- Track manual wrap toggles (on/off) vs auto so resize updates defaults
  until the user overrides.
- Subscribe to (max-width: 640px) change events; compact mode resets to auto.
- Extend tests with controllable matchMedia and resize scenarios.

Co-authored-by: Aanish Bhirud <baanish@users.noreply.github.com>
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 (1)
tests/components/code-renderer.test.tsx (1)

127-224: Consider one Playwright regression for the mobile toolbar layout path.

These unit tests validate behavior, but they won’t catch truncation/overflow regressions introduced by the mobile toolbar CSS updates.

Based on learnings: Verify visual changes with Playwright when they affect layout or renderer presentation.

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

In `@tests/components/code-renderer.test.tsx` around lines 127 - 224, Add a
Playwright visual/regression test that exercises the mobile toolbar layout of
the CodeRenderer to catch truncation/overflow regressions: write an end-to-end
test that mounts the CodeRenderer (using the same props/helpers: CodeRenderer,
createArtifact, createControllableMatchMedia) with a narrow viewport, captures a
screenshot of the toolbar (and compact vs non-compact states), and asserts
against a baseline image; include a step to toggle wrap (simulate the user
toggle used in the unit tests) and capture another screenshot so layout changes
from the mobile toolbar and wrap state are covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/components/code-renderer.test.tsx`:
- Around line 196-209: The test "keeps the user choice when the viewport changes
after a manual toggle" doesn't prove override protection because the viewport
change used doesn't conflict with the user's manual toggle; change the test to
use a conflicting viewport transition: initialize media with
createControllableMatchMedia(true) (so the natural state is the opposite),
render the CodeRenderer, perform the manual toggle via the enable/disable button
(e.g., click the button to flip the natural state), then call
media.setNarrowMatches(false) to transition to the opposite viewport and assert
the button still reflects the user's manual choice (use the same role/name
lookups for the button); this ensures the manual preference set in the test
overrides subsequent automatic viewport-driven changes.

---

Nitpick comments:
In `@tests/components/code-renderer.test.tsx`:
- Around line 127-224: Add a Playwright visual/regression test that exercises
the mobile toolbar layout of the CodeRenderer to catch truncation/overflow
regressions: write an end-to-end test that mounts the CodeRenderer (using the
same props/helpers: CodeRenderer, createArtifact, createControllableMatchMedia)
with a narrow viewport, captures a screenshot of the toolbar (and compact vs
non-compact states), and asserts against a baseline image; include a step to
toggle wrap (simulate the user toggle used in the unit tests) and capture
another screenshot so layout changes from the mobile toolbar and wrap state are
covered.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8d19a1c8-eea2-4319-b2fb-45b6cbcb7554

📥 Commits

Reviewing files that changed from the base of the PR and between eb2cafb and 9dc349d.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • src/app/globals.css
  • src/components/renderers/code-renderer.tsx
  • tests/components/code-renderer.test.tsx

Comment on lines +196 to +209
it("keeps the user choice when the viewport changes after a manual toggle", async () => {
const media = createControllableMatchMedia(false);
render(<CodeRenderer artifact={createArtifact()} />);

const enableBtn = await screen.findByRole("button", { name: /enable wrap/i });
await userEvent.click(enableBtn);

expect(screen.getByRole("button", { name: /disable wrap/i })).toBeVisible();

media.setNarrowMatches(true);

await waitFor(() => {
expect(screen.getByRole("button", { name: /disable wrap/i })).toBeVisible();
});
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

Manual-override test does not prove override protection.

This scenario can pass even if manual preference is ignored, because switching to narrow after manually enabling wrap still results in “Disable wrap” in both cases. Use a conflicting transition to make the assertion meaningful.

Suggested test adjustment
 describe("wrap preference after manual toggle", () => {
   beforeEach(() => {
-    createControllableMatchMedia(false);
+    createControllableMatchMedia(true);
   });

   it("keeps the user choice when the viewport changes after a manual toggle", async () => {
-    const media = createControllableMatchMedia(false);
+    const media = createControllableMatchMedia(true);
     render(<CodeRenderer artifact={createArtifact()} />);

-    const enableBtn = await screen.findByRole("button", { name: /enable wrap/i });
-    await userEvent.click(enableBtn);
+    const disableBtn = await screen.findByRole("button", { name: /disable wrap/i });
+    await userEvent.click(disableBtn);

-    expect(screen.getByRole("button", { name: /disable wrap/i })).toBeVisible();
+    expect(screen.getByRole("button", { name: /enable wrap/i })).toBeVisible();

+    media.setNarrowMatches(false);
     media.setNarrowMatches(true);

     await waitFor(() => {
-      expect(screen.getByRole("button", { name: /disable wrap/i })).toBeVisible();
+      expect(screen.getByRole("button", { name: /enable wrap/i })).toBeVisible();
     });
   });
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/components/code-renderer.test.tsx` around lines 196 - 209, The test
"keeps the user choice when the viewport changes after a manual toggle" doesn't
prove override protection because the viewport change used doesn't conflict with
the user's manual toggle; change the test to use a conflicting viewport
transition: initialize media with createControllableMatchMedia(true) (so the
natural state is the opposite), render the CodeRenderer, perform the manual
toggle via the enable/disable button (e.g., click the button to flip the natural
state), then call media.setNarrowMatches(false) to transition to the opposite
viewport and assert the button still reflects the user's manual choice (use the
same role/name lookups for the button); this ensures the manual preference set
in the test overrides subsequent automatic viewport-driven changes.

cursoragent and others added 3 commits April 14, 2026 18:39
- Stack raw/rendered toolbar buttons full-width at <=360px (override pair flex).
- Run wrap preference + matchMedia listener in useLayoutEffect so first paint
  matches narrow viewports without an extra CodeMirror teardown.
- Set wrap preference ref outside setState on toolbar click.
- Restore window.matchMedia in code-renderer tests afterEach for isolation.

Co-authored-by: Aanish Bhirud <baanish@users.noreply.github.com>
- Add Playwright mobile checks: code wrap defaults on, markdown toolbar
  button widths, 340px stacked raw/rendered toggle.
- waitForViewerState accepts optional longer timeout for cold preview starts.
- Vitest: esbuild automatic JSX so components need no default React import.
- CodeRenderer: drop unused React import; document ref + compact contract.
- Unit tests: single createControllableMatchMedia per test (no duplicate
  beforeEach); docs/testing.md notes mobile layout e2e coverage.

Co-authored-by: Aanish Bhirud <baanish@users.noreply.github.com>
Resolve code-renderer import conflict: keep next-themes useTheme from main
and useLayoutEffect from feature branch for mobile wrap defaults.

Co-authored-by: Aanish Bhirud <baanish@users.noreply.github.com>
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.

🧹 Nitpick comments (1)
tests/e2e/viewer.spec.ts (1)

143-146: Scope Raw/Rendered button locators to the toolbar for stronger test isolation.

Using page-level role queries can become ambiguous if similarly named controls are added elsewhere. Prefer toolbar-scoped locators in both tests.

♻️ Suggested locator scoping update
-    const rendered = page.getByRole("button", { name: /^Rendered$/ });
-    const raw = page.getByRole("button", { name: /^Raw$/ });
+    const rendered = toolbar.getByRole("button", { name: /^Rendered$/ });
+    const raw = toolbar.getByRole("button", { name: /^Raw$/ });
+    const toolbar = page.locator(".viewer-toolbar");
-    const rendered = page.getByRole("button", { name: /^Rendered$/ });
-    const raw = page.getByRole("button", { name: /^Raw$/ });
+    const rendered = toolbar.getByRole("button", { name: /^Rendered$/ });
+    const raw = toolbar.getByRole("button", { name: /^Raw$/ });

Also applies to: 170-171

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

In `@tests/e2e/viewer.spec.ts` around lines 143 - 146, The test uses page-level
role queries for the Rendered/Raw buttons which can be ambiguous; scope them to
the toolbar locator by replacing the page-level queries for rendered and raw
with toolbar-scoped queries (use toolbar.getByRole or toolbar.locator with role)
so the variables rendered and raw are located within the const toolbar locator;
make the same change for the other occurrences referenced (lines around where
rendered/raw are defined again).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/e2e/viewer.spec.ts`:
- Around line 143-146: The test uses page-level role queries for the
Rendered/Raw buttons which can be ambiguous; scope them to the toolbar locator
by replacing the page-level queries for rendered and raw with toolbar-scoped
queries (use toolbar.getByRole or toolbar.locator with role) so the variables
rendered and raw are located within the const toolbar locator; make the same
change for the other occurrences referenced (lines around where rendered/raw are
defined again).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c1c6fa00-849a-4f37-a1ff-34cc319ff7de

📥 Commits

Reviewing files that changed from the base of the PR and between 95c856c and cf729f1.

📒 Files selected for processing (7)
  • docs/testing.md
  • src/app/globals.css
  • src/components/renderers/code-renderer.tsx
  • tests/components/code-renderer.test.tsx
  • tests/e2e/helpers.ts
  • tests/e2e/viewer.spec.ts
  • vitest.config.ts
✅ Files skipped from review due to trivial changes (3)
  • docs/testing.md
  • vitest.config.ts
  • src/app/globals.css
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/components/code-renderer.test.tsx
  • src/components/renderers/code-renderer.tsx

- Keep compact touch sizing on .artifact-action at <=640px globally; scope
  flex/ellipsis to .viewer-toolbar so renderer toolbars are not unintentionally affected.
- Add pair-row rules for JSON tree/raw toggle on mobile; stack at <=360px like viewer raw/rendered.
- Fix misleading CSS comment about specificity (source order, not higher specificity).
- Drop unnecessary React import from code-renderer unit tests.

Co-authored-by: Aanish Bhirud <baanish@users.noreply.github.com>
@baanish baanish merged commit 4e7d511 into main Apr 15, 2026
6 checks passed
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.

4 participants