Skip to content

Release v0.3.5 — Phase 48: Mobile UX Pass - #900

Merged
menvil merged 51 commits into
mainfrom
release/v0.3.5-phase48-mobile-ux-pass
Jun 9, 2026
Merged

Release v0.3.5 — Phase 48: Mobile UX Pass#900
menvil merged 51 commits into
mainfrom
release/v0.3.5-phase48-mobile-ux-pass

Conversation

@menvil

@menvil menvil commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Release v0.3.5 — Phase 48: Mobile UX Pass

Phase 48: Mobile UX (RG-755–RG-774)

  • Viewport helpers and responsive layout fixes across feed, comments, profile, notifications, auth pages
  • 40px tap targets for language/theme switchers
  • min-w-0 overflow-hidden overflow prevention on flex/grid children
  • break-words on notification dropdown, truncate on profile display name
  • data-screenshot attributes on key pages for visual baseline testing
  • Mobile QA checklist added to PR template
  • Mobile UX documentation and phase review checklist

Post-release fixes

  • Post detail panel invisible on mid-feed click: overflow-hidden on feed-page root div broke position: sticky on the detail panel; removed it and improved scrollToSelectedPost to handle mobile (scroll to detail panel) and desktop (scroll to card, sticky panel stays visible). Added double-rAF for layout settle.
  • Feed pagination: switched PostFeed from ->get() to ->paginate(12) with WithPagination — eliminates full feed load (~5 MB). Custom page window: always shows first 3 and last 2 pages with ellipsis.
  • Pagination theme colors: Livewire's WithPagination uses livewire::tailwind view (resources/views/vendor/livewire/tailwind.blade.php), not pagination::tailwind. Previous overrides had no effect. New view uses @once <style> with raw CSS variables for guaranteed theme-reactive colors and wire:click for in-place navigation.
  • Header dropdowns: removed overflow-hidden that was clipping absolutely-positioned dropdown menus.
  • Dropdown shadows: reduced shadow intensity and added --rg-shadow-dropdown token.

🤖 Generated with Claude Code


Summary by cubic

Phase 48 delivers a mobile UX pass for v0.3.5 that removes 375px overflows, enforces 40px tap targets (incl. pagination), and converts the post drawer into a bottom sheet. It paginates the feed with WithPagination and theme-safe livewire::tailwind/pagination::tailwind views, fixes the sticky post detail panel, and adds docs, a Mobile QA checklist, and viewport-based tests (RG-755–RG-774).

  • New Features

    • Mobile layout pass across feed, comments, profile, notifications, and auth using min-w-0 plus break-words/truncate; controls meet 40px tap targets; drawer becomes a bottom sheet on mobile.
    • Feed switched to ->paginate(12) with WithPagination; custom pagination in livewire::tailwind/pagination::tailwind uses CSS variables for theme-safe colors, a compact window (first 3, current, last 2) with ellipsis, and 40px buttons.
    • Added data-screenshot targets, Mobile QA checklist in the PR template, Mobile UX guidelines/audit/baselines, and new browser/feature tests with viewport helpers.
  • Bug Fixes

    • Post detail panel: removed ancestor overflow that broke sticky; improved scrollToSelectedPost with double rAF and mobile vs. desktop scroll targets.
    • Header, dropdowns, and comments: removed clipping overflow-hidden; added --rg-shadow-dropdown; notifications dropdown constrained to max-w-[calc(100vw-2rem)] with break-words; ensured min-w-0 on containers; header fits at 375px with truncated brand and abbreviated locale; locale trigger is h-10.
    • Review follow-ups: fixed Tailwind v4 ! modifier syntax in rating options; standardized pagination buttons to 40px in both livewire::tailwind and pagination::tailwind; moved stable testids to app-header/post-show-page; stabilized browser overflow tests with a 500ms pause.

Written for commit 73c5b0c. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

Улучшения мобильного интерфейса (Phase 48)

  • Новые возможности

    • Добавлена пагинация в ленту постов.
    • Оптимизирован ящик с полной адаптацией под мобильные устройства (режим нижней панели).
    • Интегрированы переключатели языка и темы в шапку приложения.
  • Исправления

    • Устранено горизонтальное переполнение на экранах 375px.
    • Улучшены перенос текста и обрезка длинных строк.
    • Увеличены области касания до 40px для удобства.
    • Оптимизирована разметка модалей и выпадающих меню.
  • Документация

    • Добавлены рекомендации по мобильному дизайну.
    • Созданы контрольные списки и аудиты мобильного UX.

menvil and others added 30 commits June 9, 2026 22:09
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…gressions

RG-755: Audit Mobile UX Regressions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…t-browser-test-helpers

RG-756: Add Mobile Viewport Browser Test Helpers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…zontal-overflow-smoke-test

RG-757: Add Mobile No Horizontal Overflow Smoke Test
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ader-and-navigation

RG-758: Optimize Mobile Header And Navigation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ed-spacing

RG-759: Optimize Mobile Feed Spacing
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…st-card-layout

RG-760: Optimize Mobile Post Card Layout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…st-show-layout

RG-761: Optimize Mobile Post Show Layout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…wer-to-full-screen-sheet

RG-762: Convert Mobile Drawer To Full-Screen Sheet
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ting-options-layout

RG-763: Optimize Mobile Rating Options Layout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…load-form

RG-764: Optimize Mobile Upload Form
Add overflow-hidden/min-w-0 to comments section; comment item grid
already uses minmax(0,1fr) and break-words for safe mobile layout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…mments-layout

RG-765: Optimize mobile comments layout
Truncate long display names to prevent overflow; add tests for profile
header structure and mobile-safe identity container.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ofile-layout

RG-766: Optimize mobile profile layout
Constrain dropdown to max-w-[calc(100vw-2rem)] to prevent viewport
overflow on narrow screens; add break-words to notification content.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tifications-dropdown

RG-767: Optimize mobile notifications dropdown
Bump locale switcher trigger from h-9 to h-10 (40px) to meet minimum
tap target requirement on mobile screens.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nguage-and-theme-switchers

RG-768: Optimize mobile language and theme switchers
Add data-testid to register form; login already uses flex-wrap for
mobile-safe action row; guest layout uses px-4 and max-w-md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…th-pages

RG-769: Optimize mobile auth pages
menvil and others added 18 commits June 9, 2026 22:42
Add data-screenshot attributes to key views: feed-page, profile-header,
and auth-page for visual regression test tooling.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…screenshot-targets

RG-770: Add mobile visual screenshot targets
Add phase-48-visual-baselines.md documenting accepted visual state,
screenshot targets, viewports, and acceptance criteria for 375px.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…al-baselines

RG-771: Update mobile visual baselines
Add Mobile QA section with 5 checklist items covering 375px overflow,
tap targets, text wrapping, drawer behavior, and header switchers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…klist-to-pr-template

RG-772: Add mobile QA checklist to PR template
Add mobile-ux-guidelines.md covering overflow prevention, tap targets,
text wrapping, responsive display, drawer behavior, and breakpoints.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…mentation

RG-773: Add mobile UX documentation
Add complete review checklist with all 20 tasks marked done, final
acceptance criteria, and phase completion date.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…-ux-review-checklist

RG-774: Add phase 48 mobile UX review checklist
overflow-hidden on the feed-page root div broke position:sticky on the
detail panel — any overflow value other than visible on an ancestor
kills sticky in descendants. The detail panel appeared at the top of the
document instead of staying fixed in the viewport while the user was
scrolled down.

On mobile (< lg) the detail panel is in document flow below the feed,
so scrollToSelectedPost now scrolls to the panel instead of the card.
A double-rAF ensures positions are read after the two-column layout
has fully settled.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix post detail panel invisible when clicking mid-feed post
Previous vendor view used Tailwind utility classes (bg-rg-card etc.)
built from PHP variables — Tailwind's scanner cannot detect classes
stored in runtime variables, so they were absent from the CSS bundle,
making the pagination ignore the active theme.

New approach: define rg-page-btn / rg-page-btn-active / rg-page-btn-off
as @layer components rules in app.css using raw CSS variables
(--rg-card, --rg-text-2, --rg-accent-soft, etc.). These are always
emitted regardless of content scanning, and inherit the correct values
from the html[data-theme] overrides at runtime.

Also reduced button size from h-8 (32px) to h-[26px] and icons from
size-3.5 to size-3 for a more compact pagination bar.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix pagination: compact size and reliable theme responsiveness
Theme-responsive colors: moved styles into @once <style> block inside
the blade view using raw CSS variables (var(--rg-card), var(--rg-text-2),
etc.). This bypasses Tailwind's content scanner and @layer cascade
entirely — styles are inlined in the HTML and resolved by the browser
at runtime against the active html[data-theme] values.

Page window logic: always shows pages 1-2-3, current page if it falls
outside that group, and last two pages, with ellipsis between
non-consecutive groups. Single-page gaps are filled to avoid a lone
ellipsis (e.g. "3 … 5" becomes "3 4 5"). When total pages ≤ 7
all pages are shown without ellipsis.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix pagination colors and page window
Livewire's WithPagination uses the livewire::tailwind view
(resources/views/vendor/livewire/tailwind.blade.php), not the standard
Laravel pagination::tailwind view. Previous overrides were placed at
the wrong path and had no effect — the default Livewire view with
hardcoded bg-white was rendered instead.

New vendor view:
- Correct path: resources/views/vendor/livewire/tailwind.blade.php
- wire:click="gotoPage/previousPage/nextPage" preserved for Livewire
- @once <style> block with CSS variables guarantees theme-responsive
  colors without any Tailwind build dependency
- Custom page window: always shows 1-2-3, current page if in the
  middle, last two pages; fills single-page gaps to avoid lone ellipsis
- Disables scrollTo auto-scroll (handled by feed-page Alpine logic)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix pagination: correct Livewire vendor view path
@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@menvil, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 37 minutes and 15 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, 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 include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d56fc279-8b45-4a07-952a-5239ebda3021

📥 Commits

Reviewing files that changed from the base of the PR and between a5f1845 and 73c5b0c.

📒 Files selected for processing (11)
  • docs/mobile/mobile-ux-guidelines.md
  • resources/views/components/voting/rating-options.blade.php
  • resources/views/layouts/app.blade.php
  • resources/views/livewire/feed/feed-page.blade.php
  • resources/views/livewire/posts/post-show.blade.php
  • resources/views/vendor/pagination/tailwind.blade.php
  • tests/Browser/MobileOverflowSmokeTest.php
  • tests/Feature/Docs/Phase48MobileViewportHelperTest.php
  • tests/Feature/Mobile/MobileFeedStructureTest.php
  • tests/Feature/Mobile/MobileHeaderTest.php
  • tests/Feature/Mobile/MobileUploadFormTest.php
📝 Walkthrough

Walkthrough

Комплексная фаза 48 мобильного UX с внедрением пагинации в ленту постов (Livewire WithPagination + два Blade-шаблона пагинации), обновлением CSS-стилей (кнопки пагинации, переменные теней), исправлением мобильных вёрсток (min-w-0 для overflow, break-words/truncate для текста, tap targets 40px), добавлением data-testid/data-screenshot для тестирования и созданием инфраструктуры мобильных тестов (MobileViewports, 20+ Feature-тестов, браузерные smoke-тесты на 375px) с полной документацией (guidelines, audit, checklists, baselines).

Changes

Phase 48 Mobile UX Pass

Layer / File(s) Summary
Документация и аудит мобильного UX
docs/mobile/mobile-ux-guidelines.md, docs/mobile/phase-48-mobile-ux-audit.md, docs/mobile/phase-48-review-checklist.md, docs/mobile/phase-48-visual-baselines.md
Добавлены Mobile UX Guidelines с правилами предотвращения переполнений (min-w-0, overflow-hidden), tap targets (40px), текстовыми переносами. Создан аудит 14 областей (Feed, Post Card, Post Show, Drawer, RatingVoting, Upload, Comments, Profile, Notifications, Switchers, Auth, Header, Themes) с привязкой к RG-задачам. Добавлены чек-листы фазы 48 и визуальные baseline'ы для скриншот-тестов (feed-page, profile-header, auth-page).
Пагинация в PostFeed и шаблоны навигации
app/Livewire/Feed/PostFeed.php, resources/views/livewire/feed/post-feed.blade.php, resources/views/vendor/livewire/tailwind.blade.php, resources/views/vendor/pagination/tailwind.blade.php
Добавлен трейт WithPagination в PostFeed, переведена выборка на FeedQuery→paginate() с onEachSide(1). В view добавлена блок пагинации с $paginator→links(). Созданы два шаблона пагинации: Livewire-версия (wire:click, поддержка $scrollTo, заполнение пропусков, эллипсисы) и обычная версия (href-ссылки, похожая логика страниц).
CSS-стили и переменные теней
resources/css/app.css, resources/css/theme.css
Добавлены классы пагинации (.rg-page-btn, :hover, -active, -off с pointer-events: none). Обновлены переменные теней: --rg-shadow-popover изменено, добавлена --rg-shadow-dropdown, добавлены переопределения для светлой темы, добавлено проксирование для Tailwind.
Мобильные правки разметки и компонентов
resources/views/components/ui/drawer.blade.php, resources/views/components/locale-switcher.blade.php, resources/views/components/voting/rating-options.blade.php, resources/views/livewire/comments/comments-section.blade.php, resources/views/livewire/posts/post-show.blade.php, resources/views/livewire/profile/profile-page.blade.php, resources/views/livewire/notifications/notification-bell.blade.php, resources/views/livewire/feed/feed-page.blade.php, resources/views/layouts/app.blade.php, resources/views/auth/register.blade.php, resources/views/layouts/guest.blade.php
Добавлены min-w-0 (comments-section, post-show) для предотвращения flex-overflow, break-words (notification-bell, rating-options) и truncate (profile-page) для текста, !min-h-[40px] для tap targets (rating-options), max-w-[calc(100vw-2rem)] для dropdown'ов (locale-switcher, notifications), data-testid на формы и контейнеры (drawer-shell, upload-form, register-form), адаптивный язык в locale-switcher (мобильный vs desktop), логика scrollToSelectedPost для мобильных (feed-page).
Инфраструктура и smoke-тесты
tests/Browser/Support/MobileViewports.php, tests/Browser/MobileOverflowSmokeTest.php, tests/Feature/Docs/Phase48*Test.php
Создан MobileViewports (константы 375px, 390px, 430px, 768px; методы all(), mobileOnly()). Добавлены браузерные smoke-тесты на отсутствие горизонтального overflow при 375px (/, /posts/, /login, /register, /profile/). Добавлены документационные Feature-тесты, валидирующие наличие и содержимое guidelines, audit, checklists, baselines, PR template, viewport helper.
Комплексные мобильные Feature-тесты
tests/Feature/Mobile/Mobile*Test.php (20 тестовых файлов)
Добавлены Feature-тесты для Auth (forms, flex-wrap), Comments (section, grid, break-words), Drawer (shell, layout, close), Feed (spacing, markers), Header (mobile, switchers, upload), Notifications (bell, dropdown, break-words), PostCard (card, title, break-words), PostShow (page, meta, hero, break-words), Profile (header, identity, truncate), RatingVoting (list, options count, tap-targets), ScreenshotTargets (feed, auth, profile), Switchers (language, theme), UploadForm (form, spacing, button). Валидируют наличие data-testid, CSS-классы, доступность, соответствие мобильным требованиям.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • menvil/rateguru#873: Оба PR затрагивают app/Livewire/Feed/PostFeed.php, изменяя render() для пагинации и взаимодействия с данными.
  • menvil/rateguru#750: Main PR переводит PostFeed на FeedQuery→paginate(), прямо связано с контрактом и поведением FeedQuery в retrieved PR.
  • menvil/rateguru#898: Оба PR пересекаются на уровне пагинационных шаблонов resources/views/vendor/pagination/tailwind.blade.php и resources/views/vendor/livewire/tailwind.blade.php.

Suggested labels

release, mobile, testing, ui, documentation

Poem

🐰 Прыг-скок по мобильному экрану,
На 375 пиксель без изъяна!
С пагинацией, tap-targets в 40 снять,
Overflow не даст нам больше страдать.
Phase 48 прошла с тестов строем —
Мобильный UX процветает героем! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'Release v0.3.5 — Phase 48: Mobile UX Pass' accurately reflects the main change: a release and phase-specific mobile UX improvements addressing accessibility and layout issues at 375px.
Description check ✅ Passed The PR description follows the template structure with Summary, Verification, Visual Review, and Mobile QA sections. Most checklist items are included, though some checkboxes are not marked as completed (they are unchecked placeholders), which is acceptable for a pre-merge state.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/v0.3.5-phase48-mobile-ux-pass

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.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

14 issues found across 42 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="resources/css/app.css">

<violation number="1" location="resources/css/app.css:35">
P2: Dead/duplicate code: `.rg-page-btn*` classes in `app.css` are never referenced anywhere and duplicate the `rg-pgn-btn*` styles already defined inline in `resources/views/vendor/livewire/tailwind.blade.php`.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread resources/views/layouts/app.blade.php Outdated
Comment thread resources/css/app.css Outdated
Comment thread docs/mobile/mobile-ux-guidelines.md Outdated
Comment thread docs/mobile/phase-48-visual-baselines.md Outdated
Comment thread resources/views/livewire/comments/comments-section.blade.php Outdated
Comment thread resources/views/components/voting/rating-options.blade.php Outdated
Comment thread resources/css/app.css
--tw-ring-offset-shadow: 0 0 #0000;
}

.rg-page-btn {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Dead/duplicate code: .rg-page-btn* classes in app.css are never referenced anywhere and duplicate the rg-pgn-btn* styles already defined inline in resources/views/vendor/livewire/tailwind.blade.php.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At resources/css/app.css, line 35:

<comment>Dead/duplicate code: `.rg-page-btn*` classes in `app.css` are never referenced anywhere and duplicate the `rg-pgn-btn*` styles already defined inline in `resources/views/vendor/livewire/tailwind.blade.php`.</comment>

<file context>
@@ -31,4 +31,44 @@
         --tw-ring-offset-shadow: 0 0 #0000;
     }
+
+    .rg-page-btn {
+        display: inline-flex;
+        align-items: center;
</file context>

Comment thread tests/Feature/Docs/Phase48ReviewChecklistTest.php Outdated
Comment thread tests/Feature/Mobile/MobileUploadFormTest.php Outdated
Comment thread tests/Feature/Mobile/MobileUploadFormTest.php Outdated
menvil and others added 2 commits June 10, 2026 00:09
Post-release fixes (previously uncommitted):
- app.blade.php: remove overflow-hidden from header flex container — clips
  all absolutely-positioned dropdown menus (P0)
- theme.css: add --rg-shadow-dropdown token and light-theme shadow overrides
- PostFeed: switch ->get() to ->paginate(12) with WithPagination trait;
  pass $paginator to view for pagination links display

Code violations:
- comments-section: remove overflow-hidden — clips the sort dropdown
  (.absolute.right-0.z-20.mt-2); min-w-0 alone is sufficient (P2)
- rating-options: replace hardcoded data-testid="rating-options" with
  data-testid="{{ $testIdPrefix }}-list" so multiple groups on one page
  produce unique IDs (P2)
- app.css + livewire pagination view: increase tap target from 26px to
  40px to meet project ≥40px mobile requirement (P1)

Doc violations:
- phase-48-visual-baselines.md: fix route /profile/:user → /u/{username} (P2)
- mobile-ux-guidelines.md: replace overflow-hidden recommendation with
  min-w-0 + warning about sticky/dropdown breakage (P1);
  fix breakpoints table — 375px is a test viewport, not a mobile: prefix (P2)

Test violations:
- MobileSwitchersTest: scope h-10 check to locale-switcher-trigger context
  instead of full page body (P2 false positive)
- MobileFeedSpacingTest: rename tests to accurately describe HTML structure
  checks, not mobile-specific behavior (P2)
- MobileRatingVotingTest: use post->id in container testid assertion;
  replace substr_count with preg_match_all to match only individual option
  buttons, not the container (P2)
- MobileUploadFormTest: rename misleading test descriptions (P3)
- Phase48ReviewChecklistTest: rename to "references first and last task IDs" (P3)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix Phase 48 review violations and commit post-release fixes
@menvil

menvil commented Jun 9, 2026

Copy link
Copy Markdown
Owner Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@menvil

menvil commented Jun 9, 2026

Copy link
Copy Markdown
Owner Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 16

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/mobile/mobile-ux-guidelines.md`:
- Around line 70-73: The fenced code block in
docs/mobile/mobile-ux-guidelines.md lacks a language identifier; update the
triple-backtick fence that surrounds the lines starting with "mobile: 
inset-x-0..." and "desktop: md:inset-y-0..." to include a language tag (e.g.,
css or text) so the block becomes ```css (or ```text) to ensure proper Markdown
rendering and syntax highlighting.

In `@resources/views/components/voting/rating-options.blade.php`:
- Line 24: Update the Tailwind "important" modifier usage in the $sizeClass
assignment: replace prefix-style modifiers with suffix-style ones per Tailwind
v4. In the expression that sets $sizeClass (the ternary using $variant ===
'compact' and the else branch), change "!h-7 !min-w-9 !px-2 !text-xs" to "h-7!
min-w-9! px-2! text-xs!" and change "!min-h-[40px]" to "min-h-[40px]!" so all
utilities use the trailing "!" form.

In `@resources/views/layouts/app.blade.php`:
- Line 19: Уберите пустой элемент <span class="sr-only"> с атрибутом
data-testid="mobile-header" и переместите data-testid="mobile-header" на
реальный структурный элемент заголовка (например, на элемент header,
используемый в шаблоне — смотрите текущий header вокруг span), чтобы не
оставлять пустой скрытый элемент и сохранить тестовый идентификатор на
функциональном семантическом элементе; удалите сам пустой span и убедитесь, что
header остаётся доступным для скринридеров (не добавляйте видимый текст туда).

In `@resources/views/livewire/feed/feed-page.blade.php`:
- Around line 15-37: Add a short inline comment above the nested
requestAnimationFrame calls explaining why two RAF ticks are required (e.g., to
allow the detail panel's layout to fully settle before
measuring/getBoundingClientRect and performing smooth scroll), referencing the
nested requestAnimationFrame block that uses this.$refs.detailScroll/detail and
the subsequent measurements of detail and feed/card
(querySelector('[data-post-id=' + postId + ']')) so future readers know this is
intentional and not accidental.

In `@resources/views/livewire/posts/post-show.blade.php`:
- Line 29: The empty <span class="sr-only" data-testid="post-show-page"> is
semantically incorrect; move the data-testid attribute from that empty <span> to
an actual functional container such as the <div data-testid="post-show">
(element at line ~16) or the <main> element (around line ~30) so the test id
attaches to a meaningful DOM element and remove the empty sr-only span; update
or remove the <span data-testid="post-show-page"> accordingly to avoid leaving
an empty, screen-reader-only element.

In `@resources/views/vendor/pagination/tailwind.blade.php`:
- Around line 7-8: Pagination buttons in
resources/views/vendor/pagination/tailwind.blade.php use height: 26px and
min-width: 26px which breaks the 40px mobile tap target requirement; change
those values to 40px to match the Livewire template and also update the
.rg-pgn-ellipsis selector (used for the ellipsis/gap control) so its height and
min-width match 40px for consistent visual alignment across both pagination
variants.

In `@tests/Browser/MobileOverflowSmokeTest.php`:
- Around line 9-59: These mobile overflow smoke tests call
visit(...)->resize(...)->script(...) immediately and can miss async Livewire
hydration adding overflow; update each test case that measures overflow (the it
blocks using visit(...)->resize(...)->script(...) with
MobileViewports::SMALL_MOBILE) to wait for Livewire (e.g., insert a
->waitForLivewire() before ->script()) or add a short ->pause(500) to ensure
async content finished before measuring scrollWidth - window.innerWidth.

In `@tests/Feature/Docs/Phase48MobileViewportHelperTest.php`:
- Around line 3-13: The test is inspecting raw file contents which is brittle;
update the test to import or reference the MobileViewports class
(MobileViewports) and assert its public API returns the expected viewport sizes
(e.g., that the relevant public constants or methods return values containing
375, 390, 768) instead of searching the file text; remove the file_get_contents
and file_exists assertions and replace them with assertions against
MobileViewports' public methods or constants (e.g., call the getter or read the
constant names provided by MobileViewports) to verify the actual API behavior.

In `@tests/Feature/Mobile/MobileAuthTest.php`:
- Around line 10-14: The current test in MobileAuthTest.php ("login action row
uses flex-wrap to prevent overflow on mobile") uses assertSee('flex-wrap',
false) which can match substrings like "flex-wrap-reverse"; replace that
assertion with a regex-based check that validates the class attribute contains
the exact token, e.g. assert that the response body matches
/class="[^"]*\bflex-wrap\b[^"]*"/ (or equivalent TestResponse regex helper) to
ensure the class token is present, or alternatively convert the test into a
browser/edge-rendering test that verifies there is no horizontal overflow on a
narrow viewport.

In `@tests/Feature/Mobile/MobileCommentsTest.php`:
- Around line 26-38: The test "long comment text uses break-words to prevent
overflow" in MobileCommentsTest.php is brittle because it asserts a specific
Tailwind class; change it to verify behavior instead: convert this unit-level
Livewire html() test into a browser-style test (e.g., Laravel Dusk or Pest +
Panther) that mounts the CommentsSection component (or the page rendering it)
with the long-word Comment and then asserts the comment element does not
overflow horizontally by checking element.scrollWidth <= element.clientWidth or
by using getComputedStyle(element).overflowWrap !== 'normal'; alternatively, if
you must keep a server-side assertion, relax the expectation to accept any
wrapping-related style/class by checking the HTML for either 'break-words' or
'overflow-wrap' occurrences rather than a single Tailwind token.
- Around line 16-24: The test in MobileCommentsTest.php is tied to an exact CSS
class (grid-cols-[32px_minmax(0,1fr)]) on the CommentsSection component; replace
this fragile implementation assertion with a browser-level behavior check:
convert the test to a Dusk/Pest browser test that renders the page containing
CommentsSection (the Livewire component referenced as CommentsSection::class),
resize the viewport to a mobile width (e.g., 375px), query the comments
container (add a stable data-testid or CSS selector on the CommentsSection root
if needed), and assert via JS that element.scrollWidth <= element.clientWidth
(or use browser->script to compare scrollWidth and clientWidth). Alternatively,
move this check to your visual-regression suite if preferred.

In `@tests/Feature/Mobile/MobileDrawerTest.php`:
- Around line 5-13: The test it('renders drawer shell with mobile full screen
classes') is asserting specific CSS classes ('w-full', 'bottom-0',
'max-h-[90vh]') which couples it to implementation; change the test to assert
behavior instead — replace the class assertions with a behavior-focused check
such as rendering the drawer in a headless browser with a small viewport (use a
browser test / Dusk/Pest browser test) and assert the drawer fills the viewport
or is anchored to the bottom, or assert a semantic indicator (e.g., presence of
data-testid="drawer-shell" plus an attribute or state like aria-modal/role or a
mobile-mode flag) that denotes mobile layout; update the test name accordingly
and remove the brittle class assertions in MobileDrawerTest.php inside the
it(...) block so future style refactors won't break the test.

In `@tests/Feature/Mobile/MobileFeedSpacingTest.php`:
- Around line 5-23: The test file MobileFeedSpacingTest contains tests that
assert structural data-testid attributes (the tests with descriptions 'feed page
includes expected structural testid markers', 'feed page includes rating filters
container', and 'feed page includes feed layout container') so rename the file
(and any matching class/test suite name if present) from MobileFeedSpacingTest
to MobileFeedStructureTest to reflect its purpose, or alternatively change the
test descriptions to reference spacing if you intend to keep the Spacing name;
update references/imports accordingly.

In `@tests/Feature/Mobile/MobilePostCardTest.php`:
- Around line 28-35: The test name and assertion are misleading: update the test
in MobilePostCardTest (the it(...) block that currently reads "renders post card
with overflow-hidden container") to explicitly verify the mobile post card does
not contain the problematic CSS; either rename the test to reflect the
expectation and replace ->assertSee('overflow-hidden', false) with
->assertDontSee('overflow-hidden') or, better, add/target a specific marker
(e.g. data-testid on the post card component) and assert the response for that
marker does not include "overflow-hidden" so you only check the post card
container (use the Post::factory()->published()->create(),
$this->get(route('feed')) and the response assertions around the specific
container).

In `@tests/Feature/Mobile/MobileSwitchersTest.php`:
- Around line 13-22: The current test uses strpos/substr ($triggerPos, $snippet)
to search for 'h-10' near 'locale-switcher-trigger', which is fragile and can
yield false positives; replace the substring approach by parsing the returned
HTML ($html from $this->get(route('feed'))) with a DOM parser/Crawler (e.g.,
Symfony\Component\DomCrawler\Crawler), locate the element by its data-testid or
selector for locale-switcher-trigger (e.g.,
'[data-testid="locale-switcher-trigger"]' or the element with class/ID used in
the markup), then assert directly that that element's class attribute contains
'h-10' (or that the element matches the selector
'[data-testid="locale-switcher-trigger"].h-10'); update the test to remove
$triggerPos/$snippet and use the Crawler-based lookup and assertion instead.

In `@tests/Feature/Mobile/MobileUploadFormTest.php`:
- Around line 15-24: Тест в MobileUploadFormTest.php ("upload form contains
vertical field spacing") жёстко зависит от реализации (assert
expect($html)->toContain('space-y-4')); уберите или замените эту проверку и
вместо неё либо (а) переведите проверку в браузерный тест (Laravel Dusk) который
рендерит компонент UploadPostForm и использует $browser->script/getComputedStyle
или измеряет расстояние между соседними полями, затем ассертом проверяет
реальный vertical spacing (например gap/margin в пикселях или > 0), либо (б)
замените на семантическую проверку структуры (наличие контейнера upload-form и
ожидаемых полей) если визуальная проверка не требуется; в коде ищите
MobileUploadFormTest::it('upload form contains vertical field spacing'),
Livewire::actingAs(...)->test(UploadPostForm::class)->html() и удалите/замените
строку expect($html)->toContain('space-y-4') согласно одному из подходов.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: 7382b449-3fe2-4126-8ba6-bbb667ad784f

📥 Commits

Reviewing files that changed from the base of the PR and between b01895f and a5f1845.

📒 Files selected for processing (45)
  • .github/pull_request_template.md
  • app/Livewire/Feed/PostFeed.php
  • docs/mobile/mobile-ux-guidelines.md
  • docs/mobile/phase-48-mobile-ux-audit.md
  • docs/mobile/phase-48-review-checklist.md
  • docs/mobile/phase-48-visual-baselines.md
  • resources/css/app.css
  • resources/css/theme.css
  • resources/views/auth/register.blade.php
  • resources/views/components/locale-switcher.blade.php
  • resources/views/components/ui/drawer.blade.php
  • resources/views/components/voting/rating-options.blade.php
  • resources/views/layouts/app.blade.php
  • resources/views/layouts/guest.blade.php
  • resources/views/livewire/comments/comments-section.blade.php
  • resources/views/livewire/feed/feed-page.blade.php
  • resources/views/livewire/feed/post-feed.blade.php
  • resources/views/livewire/feed/upload-post-form.blade.php
  • resources/views/livewire/notifications/notification-bell.blade.php
  • resources/views/livewire/posts/post-show.blade.php
  • resources/views/livewire/profile/profile-page.blade.php
  • resources/views/vendor/livewire/tailwind.blade.php
  • resources/views/vendor/pagination/tailwind.blade.php
  • tests/Browser/MobileOverflowSmokeTest.php
  • tests/Browser/Support/MobileViewports.php
  • tests/Feature/Docs/Phase48MobileBaselinesTest.php
  • tests/Feature/Docs/Phase48MobileOverflowSmokeTest.php
  • tests/Feature/Docs/Phase48MobileUxAuditTest.php
  • tests/Feature/Docs/Phase48MobileUxDocTest.php
  • tests/Feature/Docs/Phase48MobileViewportHelperTest.php
  • tests/Feature/Docs/Phase48PrTemplateTest.php
  • tests/Feature/Docs/Phase48ReviewChecklistTest.php
  • tests/Feature/Mobile/MobileAuthTest.php
  • tests/Feature/Mobile/MobileCommentsTest.php
  • tests/Feature/Mobile/MobileDrawerTest.php
  • tests/Feature/Mobile/MobileFeedSpacingTest.php
  • tests/Feature/Mobile/MobileHeaderTest.php
  • tests/Feature/Mobile/MobileNotificationsTest.php
  • tests/Feature/Mobile/MobilePostCardTest.php
  • tests/Feature/Mobile/MobilePostShowTest.php
  • tests/Feature/Mobile/MobileProfileTest.php
  • tests/Feature/Mobile/MobileRatingVotingTest.php
  • tests/Feature/Mobile/MobileScreenshotTargetsTest.php
  • tests/Feature/Mobile/MobileSwitchersTest.php
  • tests/Feature/Mobile/MobileUploadFormTest.php

Comment thread docs/mobile/mobile-ux-guidelines.md Outdated
Comment thread resources/views/components/voting/rating-options.blade.php Outdated
Comment thread resources/views/layouts/app.blade.php Outdated
<div class="mx-auto flex h-[60px] w-full max-w-[1440px] items-center gap-4 px-5 md:grid md:grid-cols-[1fr_minmax(0,480px)_auto]">
<a href="{{ url('/') }}" class="shrink-0 self-center rounded-rgControl px-2 py-1 text-[22px] font-extrabold tracking-normal text-rg-text transition-colors hover:text-rg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-rg-accent focus-visible:ring-offset-2 focus-visible:ring-offset-rg-bg" data-testid="site-brand">
{{ $projectSettings->siteName() }}
<span data-testid="mobile-header" class="sr-only"></span>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Пустой sr-only элемент семантически некорректен.

Класс sr-only предназначен для скрытия визуального контента, оставляя его доступным для программ чтения с экрана. Пустой <span class="sr-only"> без текстового содержимого не несёт семантической нагрузки и может вызвать путаницу в инструментах доступности.

Рекомендация: переместите data-testid="mobile-header" на функциональный элемент заголовка (например, на <header> на строке 18) вместо создания отдельного пустого маркера.

♻️ Предлагаемое исправление
-            <header class="sticky top-0 z-40 border-b border-rg-border bg-rg-topbar" data-testid="app-header">
-                <span data-testid="mobile-header" class="sr-only"></span>
+            <header class="sticky top-0 z-40 border-b border-rg-border bg-rg-topbar" data-testid="app-header" data-mobile-testid="mobile-header">
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@resources/views/layouts/app.blade.php` at line 19, Уберите пустой элемент
<span class="sr-only"> с атрибутом data-testid="mobile-header" и переместите
data-testid="mobile-header" на реальный структурный элемент заголовка (например,
на элемент header, используемый в шаблоне — смотрите текущий header вокруг
span), чтобы не оставлять пустой скрытый элемент и сохранить тестовый
идентификатор на функциональном семантическом элементе; удалите сам пустой span
и убедитесь, что header остаётся доступным для скринридеров (не добавляйте
видимый текст туда).

Comment thread resources/views/livewire/feed/feed-page.blade.php
Comment thread resources/views/livewire/posts/post-show.blade.php Outdated
Comment on lines +5 to +13
it('renders drawer shell with mobile full screen classes', function () {
$html = Blade::render('<x-ui.drawer title="Post details">Content</x-ui.drawer>');

expect($html)
->toContain('data-testid="drawer-shell"')
->toContain('w-full')
->toContain('bottom-0')
->toContain('max-h-[90vh]');
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff

Тест проверяет конкретные CSS-классы вместо поведения.

Утверждения toContain('w-full'), toContain('bottom-0'), toContain('max-h-[90vh]') привязывают тест к текущей реализации стилей. Если drawer будет переработан с сохранением визуального результата (полный экран на мобильном), тест всё равно упадёт. Для валидации мобильного поведения эффективнее browser-тесты с реальным viewport или visual regression.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/Feature/Mobile/MobileDrawerTest.php` around lines 5 - 13, The test
it('renders drawer shell with mobile full screen classes') is asserting specific
CSS classes ('w-full', 'bottom-0', 'max-h-[90vh]') which couples it to
implementation; change the test to assert behavior instead — replace the class
assertions with a behavior-focused check such as rendering the drawer in a
headless browser with a small viewport (use a browser test / Dusk/Pest browser
test) and assert the drawer fills the viewport or is anchored to the bottom, or
assert a semantic indicator (e.g., presence of data-testid="drawer-shell" plus
an attribute or state like aria-modal/role or a mobile-mode flag) that denotes
mobile layout; update the test name accordingly and remove the brittle class
assertions in MobileDrawerTest.php inside the it(...) block so future style
refactors won't break the test.

Comment on lines +5 to +23
it('feed page includes expected structural testid markers', function () {
Post::factory()->published()->create(['title' => 'Feed Spacing Test']);

$this->get(route('feed'))
->assertOk()
->assertSee('data-testid="feed-page"', false);
});

it('feed page includes rating filters container', function () {
$this->get(route('feed'))
->assertOk()
->assertSee('data-testid="feed-rating-filters"', false);
});

it('feed page includes feed layout container', function () {
$this->get(route('feed'))
->assertOk()
->assertSee('data-testid="feed-layout"', false);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Название файла не соответствует содержанию тестов.

Файл называется MobileFeedSpacingTest, но тесты проверяют наличие структурных data-testid атрибутов, а не spacing (отступы/промежутки). Если планируется добавить проверки spacing позже, оставьте как есть; иначе переименуйте в MobileFeedStructureTest для ясности.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/Feature/Mobile/MobileFeedSpacingTest.php` around lines 5 - 23, The test
file MobileFeedSpacingTest contains tests that assert structural data-testid
attributes (the tests with descriptions 'feed page includes expected structural
testid markers', 'feed page includes rating filters container', and 'feed page
includes feed layout container') so rename the file (and any matching class/test
suite name if present) from MobileFeedSpacingTest to MobileFeedStructureTest to
reflect its purpose, or alternatively change the test descriptions to reference
spacing if you intend to keep the Spacing name; update references/imports
accordingly.

Comment on lines +28 to +35
it('renders post card with overflow-hidden container', function () {
Post::factory()->published()->create();

$response = $this->get(route('feed'));

$response->assertOk()
->assertSee('overflow-hidden', false);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Название и логика теста не соответствуют цели мобильного UX.

Тест с названием "renders post card with overflow-hidden container" проверяет, что overflow-hidden присутствует где-то на странице feed через assertSee('overflow-hidden', false). Однако:

  1. В контексте Phase 48 цель — предотвратить горизонтальный overflow и убрать overflow-hidden из проблемных мест (PR description упоминает "Removed overflow-hidden that broke position:sticky").
  2. Текущий assertSee слишком широкий — он срабатывает, если overflow-hidden встречается где угодно в HTML, включая допустимые места (например, в других компонентах).
  3. Неясно, что именно проверяет тест: наличие overflow-hidden (плохо) или его отсутствие (хорошо)?

Рекомендация: либо переименовать тест и уточнить его назначение, либо заменить на assertDontSee('overflow-hidden') для контейнера карточки поста, либо использовать более точный селектор/data-testid для проверки конкретного контейнера.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/Feature/Mobile/MobilePostCardTest.php` around lines 28 - 35, The test
name and assertion are misleading: update the test in MobilePostCardTest (the
it(...) block that currently reads "renders post card with overflow-hidden
container") to explicitly verify the mobile post card does not contain the
problematic CSS; either rename the test to reflect the expectation and replace
->assertSee('overflow-hidden', false) with ->assertDontSee('overflow-hidden')
or, better, add/target a specific marker (e.g. data-testid on the post card
component) and assert the response for that marker does not include
"overflow-hidden" so you only check the post card container (use the
Post::factory()->published()->create(), $this->get(route('feed')) and the
response assertions around the specific container).

Comment on lines +13 to +22
it('locale switcher trigger meets 40px tap target height', function () {
$html = $this->get(route('feed'))->content();

$triggerPos = strpos($html, 'locale-switcher-trigger');
expect($triggerPos)->not->toBeFalse('locale-switcher-trigger not found');

// Check that h-10 (40px) appears within the trigger element's markup
$snippet = substr($html, max(0, $triggerPos - 300), 500);
expect($snippet)->toContain('h-10');
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Хрупкая логика проверки высоты tap target через substring.

Тест использует strpos и substr для поиска класса h-10 в окрестности locale-switcher-trigger:

$snippet = substr($html, max(0, $triggerPos - 300), 500);
expect($snippet)->toContain('h-10');

Проблемы:

  1. Ложноположительные срабатывания: тест пройдёт, если h-10 встречается где угодно в окне ±300 символов от триггера, даже если этот класс принадлежит другому элементу.
  2. Хрупкость к изменению разметки: если в радиусе 300 символов появится другой элемент с h-10, тест будет проходить некорректно.

Рекомендуется использовать более точный подход:

  • Парсинг HTML через DOMDocument/Symfony\Component\DomCrawler\Crawler для извлечения конкретного элемента по data-testid
  • Проверка класса непосредственно у locale-switcher-trigger
  • Или использование CSS-селектора: [data-testid="locale-switcher-trigger"].h-10
♻️ Рекомендуемое решение с использованием Crawler
 it('locale switcher trigger meets 40px tap target height', function () {
-    $html = $this->get(route('feed'))->content();
+    $response = $this->get(route('feed'));
+    $response->assertOk();

-    $triggerPos = strpos($html, 'locale-switcher-trigger');
-    expect($triggerPos)->not->toBeFalse('locale-switcher-trigger not found');
-
-    // Check that h-10 (40px) appears within the trigger element's markup
-    $snippet = substr($html, max(0, $triggerPos - 300), 500);
-    expect($snippet)->toContain('h-10');
+    $crawler = new \Symfony\Component\DomCrawler\Crawler($response->content());
+    $trigger = $crawler->filter('[data-testid="locale-switcher-trigger"]');
+    
+    expect($trigger->count())->toBeGreaterThan(0, 'locale-switcher-trigger not found');
+    expect($trigger->attr('class'))->toContain('h-10');
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/Feature/Mobile/MobileSwitchersTest.php` around lines 13 - 22, The
current test uses strpos/substr ($triggerPos, $snippet) to search for 'h-10'
near 'locale-switcher-trigger', which is fragile and can yield false positives;
replace the substring approach by parsing the returned HTML ($html from
$this->get(route('feed'))) with a DOM parser/Crawler (e.g.,
Symfony\Component\DomCrawler\Crawler), locate the element by its data-testid or
selector for locale-switcher-trigger (e.g.,
'[data-testid="locale-switcher-trigger"]' or the element with class/ID used in
the markup), then assert directly that that element's class attribute contains
'h-10' (or that the element matches the selector
'[data-testid="locale-switcher-trigger"].h-10'); update the test to remove
$triggerPos/$snippet and use the Crawler-based lookup and assertion instead.

Comment thread tests/Feature/Mobile/MobileUploadFormTest.php Outdated
- Fix Tailwind v4 !-modifier syntax in rating-options (prefix → suffix)
- Move mobile-header testid from empty sr-only span to app-header element
- Move post-show-page testid from empty sr-only span to <main> element
- Raise vendor/pagination height from 26px to 40px (match Livewire pagination)
- Add language tag to fenced code block in mobile-ux-guidelines.md
- Add inline comment explaining double rAF in feed-page scrollToSelectedPost
- Add ->pause(500) in browser overflow tests before JS scroll measurement
- Refactor viewport helper test to assert MobileViewports constants directly
- Rename MobileFeedSpacingTest → MobileFeedStructureTest
- Remove implementation-coupled space-y-4 assertion from upload form test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@menvil
menvil merged commit 3a3b5f4 into main Jun 9, 2026
1 of 2 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.

1 participant