From bee-dev-team
Gate 4 of the React Native frontend development cycle - ensures all components have Jest snapshot tests covering all states, both platforms (iOS and Android), and edge cases using React Native Testing Library renders.
npx claudepluginhub luanrodrigues/ia-frmwrk --plugin bee-dev-teamThis skill uses the workspace's default tool permissions.
Ensure all React Native frontend components have **Jest snapshot tests** covering all states, both platforms (iOS and Android), and edge cases. Detect visual regressions before code review.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Ensure all React Native frontend components have Jest snapshot tests covering all states, both platforms (iOS and Android), and edge cases. Detect visual regressions before code review.
Core principle: If a user can see it, it must have a snapshot. All states, both platforms. Platform differences (platform-specific colors, fonts, iconography) MUST be captured.
<block_condition>
This skill ORCHESTRATES. React Native Frontend QA Analyst Agent (visual mode) EXECUTES.
| Who | Responsibility |
|---|---|
| This Skill | Gather requirements, dispatch agent, track iterations |
| QA Analyst Frontend React Native Agent | Write snapshot tests, verify states, check duplication |
MANDATORY: Load testing-visual-rn.md standards via WebFetch.
<fetch_required> https://raw.githubusercontent.com/luanrodrigues/ia-frmwrk/master/dev-team/docs/standards/frontend-react-native/testing-visual.md </fetch_required>
REQUIRED INPUT:
- unit_id: [task/subtask being tested]
- implementation_files: [.tsx files from Gate 0]
OPTIONAL INPUT:
- ux_criteria_path: [path to ux-criteria.md]
- gate3_handoff: [full Gate 3 output]
if any REQUIRED input is missing:
→ STOP and report: "Missing required input: [field]"
Task tool:
subagent_type: "bee:qa-analyst-frontend-react-native"
model: "opus"
prompt: |
**MODE:** VISUAL TESTING (Gate 4)
**Standards:** Load testing-visual.md (frontend-react-native)
**Input:**
- Unit ID: {unit_id}
- Implementation Files: {implementation_files}
- UX Criteria: {ux_criteria_path or "N/A"}
- Framework: React Native (Expo or bare)
- Testing Tool: Jest + React Native Testing Library (RNTL)
**Requirements:**
1. Create snapshot tests for all React Native components using Jest + RNTL (render())
2. Cover all states (Default, Empty, Loading, Error, Success, Disabled)
3. Add platform-specific snapshots for components that use Platform.select() or Platform.OS
4. Test edge cases (long text, 0 items, special characters, RTL layout if applicable)
5. Verify no sindarian-rn component duplication in components/ui/
6. Use render() from RNTL with appropriate mocks for navigation and native modules
**React Native-Specific Snapshot Requirements:**
- Test all prop combinations that produce visually distinct outputs
- Snapshot conditional rendering branches explicitly (show/hide logic)
- Snapshot Platform.select() variations: render once with Platform.OS = 'ios', once with 'android'
- Snapshot StyleSheet variations (pressed state, focused state via accessibility)
- Verify Animated component initial state is captured correctly (mocked or with runAllTimers)
- Store-connected components: test with different Zustand state slices (mockStore or manual state injection)
- Async components: use waitFor + act() before taking snapshot
- Icon components: mock vector icon libraries to prevent snapshot noise
- Native modules: mock with jest.mock() to prevent native call errors in snapshot tests
- Text components with dynamic content: use representative long strings and empty strings
**Output Sections Required:**
- ## Visual Testing Summary
- ## Snapshot Coverage
- ## Component Duplication Check
- ## Handoff to Next Gate
Parse agent output:
if "Status: PASS" in output:
→ Gate 4 PASSED
→ Return success with metrics
if "Status: FAIL" in output:
→ If missing snapshots: re-dispatch agent to add missing
→ If duplication found: re-dispatch implementation agent to fix
→ Re-run visual tests (max 3 iterations)
→ If still failing: ESCALATE to user
## Visual Testing Summary
**Status:** {PASS|FAIL}
**Components with Snapshots:** {count}
**Total Snapshots:** {count}
**Snapshot Failures:** {count}
## Snapshot Coverage
| Component | States | Platforms | Edge Cases | Status |
|-----------|--------|-----------|------------|--------|
| {component} | {X/Y} | {iOS+Android or N/A} | {description} | {PASS|FAIL} |
## Component Duplication Check
| Component in components/ui/ | In sindarian-rn? | Status |
|-----------------------------|-----------------|--------|
| {component} | {Yes|No} | {PASS|FAIL} |
## Handoff to Next Gate
- Ready for Gate 5 (E2E Testing): {YES|NO}
- Iterations: {count}
See shared-patterns/shared-anti-rationalization.md for universal anti-rationalizations. Gate-specific:
| Rationalization | Why It's WRONG | Required Action |
|---|---|---|
| "Snapshots are brittle" | Brittle = catches unintended changes. That's the point. | Write snapshot tests |
| "We test visually on device" | Manual testing misses regressions. Automated is repeatable. | Add snapshot tests |
| "Only default state matters" | Error and loading states are user-facing. | Test all states |
| "iOS and Android look the same" | Platform.select() produces different output per platform. | Add platform snapshots |
| "This React Native Paper component is better" | sindarian-rn is PRIMARY. Don't duplicate. | Check sindarian-rn first |
| "Conditional branches are covered by unit tests" | Unit tests verify logic. Snapshots verify rendered output. | Snapshot each conditional branch |
| "Animated initial state is too complex to snapshot" | Mock Animated or use runAllTimers() to capture initial state. | Snapshot with controlled animation state |
| "Zustand state is mocked, snapshot is wrong" | Inject realistic state via mockStore or manual Zustand state that represents real usage. | Snapshot with realistic store state |
| "Vector icons cause snapshot noise" | Mock icon libraries in Jest setup to get stable snapshots. | Mock icon libraries |