Files
Codeman/docs/mobile-testing-report.md
Codeman maintainer c9c8ffddde test(mobile): read PHONE_MAX as an exclusive bound everywhere, drop the stale 430px baselines
Follow-up to #390. PHONE_MAX had become 599, an inclusive bound, while
three of its four consumers still read it as exclusive (width < PHONE_MAX
for phone); the one site that switched to <= disagreed with
getDeviceType(). It is 600 again with < at every site. The breakpoint
table in docs/mobile-testing-report.md says 600, and the three 430px
visual baselines are removed: they depict the tablet tier now, and the
visual suite recreates a missing baseline on its next run on the machine
that owns them. device-matrix.test.ts is also run through Prettier, which
the commit hook demanded and the format gate (src/ only) never did.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-14 15:53:22 +02:00

8.4 KiB

Mobile E2E Testing Report

Date: 2026-01-31 Status: All 32 tests passing

Overview

Comprehensive mobile E2E testing was performed using Playwright with Chromium in mobile emulation mode. Tests validate touch interactions, responsive design, mobile-specific UI behaviors, and edge cases across various device viewports.

Test Coverage Summary

Test File Tests Description
mobile-safari.e2e.ts 6 Core mobile Safari/iPhone tests
mobile-comprehensive.e2e.ts 13 UI components, modals, interactions
mobile-edge-cases.e2e.ts 13 Edge cases: orientation, narrow screens, safe areas

Bugs Found and Fixed

1. Monitor Panel Overlapping Toolbar on Mobile

File: src/web/public/styles.css (lines 7969-7982)

Problem: The monitor panel was positioned at bottom: var(--toolbar-height) (40px), but the mobile toolbar has height: auto with flex-wrap: wrap, causing it to be taller than 40px. This resulted in the monitor panel header intercepting tap events on the "Run Claude" button.

Error message:

<div class="monitor-panel-title">Monitor</div> from <div id="monitorPanel" class="monitor-panel">…</div> subtree intercepts pointer events

Fix: Hide monitor and subagents panels on phones by default:

@media (max-width: 430px) {
  .monitor-panel,
  .subagents-panel {
    display: none !important;
  }
}

Rationale: On phone screens (<430px), there isn't enough space for these panels anyway. Users can still access session info via the header and session options modal.


2. WebKit Browser Missing System Dependencies

File: test/e2e/fixtures/mobile-browser.fixture.ts

Problem: WebKit requires system libraries (libgtk-4, libgstreamer, etc.) that may not be installed on all systems, causing mobile tests to fail.

Fix: Added fallback to Chromium with mobile emulation:

try {
  browser = await webkit.launch({ headless: true });
  userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X)...';
} catch {
  // WebKit failed, use Chromium with mobile emulation
  browser = await chromium.launch({ headless: true, args: [...] });
  userAgent = 'Mozilla/5.0 (Linux; Android 14; Pixel 8)...';
}

3. Race Condition in Session Tab Detection

File: test/e2e/workflows/mobile-safari.e2e.ts

Problem: Test waited for .session-tab selector but then checked .session-tab.active, causing timing issues where the tab existed but wasn't yet marked as active.

Fix: Wait for the active tab directly:

// Before (race condition)
await page.waitForSelector('.session-tab', { timeout: ... });
const tabVisible = await page.isVisible('.session-tab.active');

// After (correct)
await page.waitForSelector('.session-tab.active', { timeout: ... });
const tabVisible = await page.isVisible('.session-tab.active');

Known Limitations

No Kill All Button on Mobile

Status: By design (not a bug)

The "Kill All" button is located in the Monitor panel, which is hidden on mobile devices (<430px). Users can close sessions individually via the close button on each session tab.

Consideration for future: Could add a "Kill All" option in the app settings modal or a long-press context menu on session tabs.

No Help Button on Mobile

Status: By design

There is no dedicated help button in the mobile UI. Help is accessible via:

  • Keyboard shortcut (? key)
  • App settings modal

Test Coverage

mobile-safari.e2e.ts (Port 3191)

Test Description
Touch-friendly UI rendering Verifies touch-device and device-mobile body classes
44px minimum touch targets Ensures buttons meet WCAG AA touch target requirements
Tap gestures for session creation Creates session via tap on Run Claude button
Always-visible close buttons Verifies opacity:1 on touch devices (no hover dependency)
Header hiding on small screens Brand, stats, font controls hidden on phones
Tablet viewport rendering iPad Pro 11" (834x1194) renders with device-desktop + touch-device

mobile-comprehensive.e2e.ts (Port 3192)

Test Description
Welcome overlay buttons Touch-friendly welcome overlay with 44px+ button height
Run Claude button prominence Button visible with flex: 1 on mobile
Case dropdown visibility Dropdown accessible and functional
Version display hiding .toolbar-center hidden on phones
Horizontal tab scrolling Session tabs allow overflow-x: auto scrolling
Tab switching on tap Tapping tabs switches active session
Full-screen modals Modals use 100% width/height on phones
Create case modal Case creation modal accessible via + button
Notification button Notification bell visible and tappable
Settings button Settings gear has adequate touch target
Close confirmation modal Close button triggers confirmation dialog
Token count display Token counter visible in header
Ralph wizard full-screen Wizard modal renders full-screen

mobile-edge-cases.e2e.ts (Port 3193)

Test Description
Landscape orientation handling 874x402 landscape mode with proper classes
Terminal in landscape Terminal renders with adequate height
Very narrow viewport (280px) Galaxy Fold folded state usable
Narrow screen toolbar Toolbar doesn't overflow on 280px
Session options via gear icon Gear icon visible, modal opens on tap
Modal tab switching Session options modal tabs work on touch
Terminal tap interactions Terminal responds to touch events
Primary touch targets Main buttons meet 44px height requirement
iOS safe area CSS variables --safe-area-* variables defined
Double-tap zoom prevention touch-action styles applied
Modal body scrolling overflow-y: auto for touch scrolling
Viewport meta tag Proper mobile viewport configuration
Android Pixel viewport 412x915 Pixel 7a renders correctly

Mobile CSS Breakpoints

Breakpoint Class Description
< 600px device-mobile Phone - most features hidden/simplified
600-768px device-tablet Tablet - intermediate layout
> 768px device-desktop Desktop - full features

Touch devices also get touch-device class regardless of screen size.


Viewports Tested

Device Width Height Scale Notes
iPhone 17 Pro 402 874 3x Primary phone test
iPhone 17 Pro Landscape 874 402 3x Orientation testing
iPhone 17 Pro Max 440 956 3x Larger phone
iPad Pro 11" 834 1194 2x Tablet testing
Galaxy Fold (folded) 280 653 3x Extreme narrow test
Pixel 7a 412 915 2.625x Android testing

Running Mobile Tests

# Install Playwright browsers (Chromium is required, WebKit optional)
npx playwright install chromium

# Run individual test files
npx vitest run test/e2e/workflows/mobile-safari.e2e.ts
npx vitest run test/e2e/workflows/mobile-comprehensive.e2e.ts
npx vitest run test/e2e/workflows/mobile-edge-cases.e2e.ts

# Run all mobile tests together
npx vitest run test/e2e/workflows/mobile-safari.e2e.ts test/e2e/workflows/mobile-comprehensive.e2e.ts test/e2e/workflows/mobile-edge-cases.e2e.ts

Port Allocations

Port Test File
3191 mobile-safari.e2e.ts
3192 mobile-comprehensive.e2e.ts
3193 mobile-edge-cases.e2e.ts

Key Mobile UI Behaviors

  1. Monitor/Subagents panels: Hidden on phones (<430px)
  2. Toolbar: Wraps content with flex-wrap: wrap, variable height
  3. Session tabs: Horizontal scroll with hidden scrollbar
  4. Modals: Full-screen on phones (100% width/height)
  5. Touch targets: Minimum 44px height for WCAG compliance
  6. Close buttons: Always visible (opacity: 1) on touch devices
  7. Header: Brand, stats, font controls hidden on phones
  8. Safe areas: CSS variables for iOS notch handling

Future Improvements

  1. Add swipe gesture tests for tab navigation
  2. Add virtual keyboard handling tests (show/hide behavior)
  3. Add orientation change tests (dynamic portrait/landscape switching)
  4. Add safe area inset tests for iOS notch handling with actual device values
  5. Consider showing a condensed monitor indicator on mobile
  6. Add "Kill All" option accessible from mobile UI
  7. Test pull-to-refresh prevention on iOS Safari