Skip to content

Navigable UI Flow Tree with Screenshot Links #91

Description

@ojfbot

Overview

Create a navigable tree structure in the dashboard that visualizes the complete UI flow hierarchy with clickable action links and screenshot previews.

Goal: Provide an intuitive, tree-based navigation system that shows the complete interaction flow with visual context and allows users to jump directly to any point in the UI journey.

Parent: #71 (Visual Regression Testing Pipeline)
Builds on: #76 (GitHub Pages Dashboard), #90 (Interactive Draw.io Canvas)


Problem Statement

Current State:

  • Test steps displayed as flat list
  • No visual hierarchy of user interactions
  • Difficult to understand flow branching and decisions
  • Screenshot context requires manual correlation

Desired State:

  • Tree structure showing interaction hierarchy
  • Visual flow from start to end
  • Expandable/collapsible branches
  • Inline screenshot previews
  • Click to navigate or zoom

Features

1. Hierarchical Flow Tree (Priority: High)

Complexity: Medium
Estimated Effort: 2-3 days

Tree Structure:

📱 Bio Dashboard - Desktop
├─ 🌐 Navigate to /dashboard
│  └─ 📸 [dashboard-home.png]
├─ 👆 Click "Bio" tab
│  ├─ 📸 [bio-tab-before.png]
│  ├─ ⚡ Tab switches
│  └─ 📸 [bio-tab-after.png]
├─ 📤 Upload file
│  ├─ 👆 Click upload button
│  │  └─ 📸 [upload-dialog-open.png]
│  ├─ 📝 Select file: resume.pdf
│  │  └─ 📸 [file-selected.png]
│  ├─ ✅ Click confirm
│  │  └─ 📸 [upload-progress.png]
│  └─ ✅ Upload complete
│     └─ 📸 [file-uploaded.png]
└─ 🗑️ Delete file
   ├─ 👆 Click delete icon
   ├─ ⚠️ Confirm deletion
   └─ ✅ File removed
      └─ 📸 [file-deleted.png]

Implementation:

interface UIFlowNode {
  id: string;
  type: 'navigation' | 'action' | 'state' | 'screenshot';
  label: string;
  icon: string;
  screenshot?: {
    path: string;
    thumbnail: string;
    capturePoint: 'before' | 'after';
  };
  children: UIFlowNode[];
  metadata: {
    selector?: string;
    interaction?: string;
    expectedOutcome?: string;
    duration?: number;
  };
}

export function FlowTree({ root }: { root: UIFlowNode }) {
  return (
    <div className="flow-tree">
      <TreeNode node={root} level={0} />
    </div>
  );
}

2. Inline Screenshot Previews (Priority: High)

Complexity: Low
Estimated Effort: 1 day

Requirements:

  • Show thumbnail next to each screenshot node
  • Hover to preview larger version
  • Click to open in lightbox gallery
  • Load thumbnails lazily
  • Show diff indicator for failures

UI Component:

function ScreenshotPreview({ screenshot, diff }: Props) {
  return (
    <div className="screenshot-preview">
      <img
        src={screenshot.thumbnail}
        alt={screenshot.path}
        className={diff ? 'has-diff' : ''}
        onClick={() => openLightbox(screenshot.path)}
      />
      {diff && (
        <div className="diff-badge">
          {diff.pixelsDifferent} px ({diff.percentDifferent}%)
        </div>
      )}
    </div>
  );
}

3. Expandable/Collapsible Branches (Priority: High)

Complexity: Low
Estimated Effort: 1 day

Requirements:

  • Click to expand/collapse branches
  • Keyboard navigation (arrows, space, enter)
  • Expand all / Collapse all buttons
  • Remember expansion state per test run
  • Smooth animations

State Management:

function useTreeExpansion(treeId: string) {
  const [expanded, setExpanded] = useState<Set<string>>(() => {
    // Load from localStorage
    const stored = localStorage.getItem(`tree:${treeId}:expanded`);
    return stored ? new Set(JSON.parse(stored)) : new Set();
  });

  const toggleNode = (nodeId: string) => {
    setExpanded(prev => {
      const next = new Set(prev);
      if (next.has(nodeId)) {
        next.delete(nodeId);
      } else {
        next.add(nodeId);
      }
      // Save to localStorage
      localStorage.setItem(
        `tree:${treeId}:expanded`,
        JSON.stringify([...next])
      );
      return next;
    });
  };

  return { expanded, toggleNode };
}

4. Clickable Action Links (Priority: High)

Complexity: Medium
Estimated Effort: 2 days

Requirements:

  • Click action node → Jump to test step details
  • Click screenshot → Open lightbox at that image
  • Click navigation node → Show URL/route info
  • Click state node → Show expected vs actual state
  • Highlight active node when scrolled into view

Navigation Handler:

function TreeNodeAction({ node, isActive }: Props) {
  const handleClick = () => {
    switch (node.type) {
      case 'action':
        scrollToTestStep(node.metadata.stepIndex);
        break;
      case 'screenshot':
        openLightbox(node.screenshot.path);
        break;
      case 'navigation':
        showRouteDetails(node.metadata.route);
        break;
      case 'state':
        showStateComparison(node.metadata.expectedState);
        break;
    }
  };

  return (
    <button
      className={`tree-node-action ${isActive ? 'active' : ''}`}
      onClick={handleClick}
      aria-label={`${node.type}: ${node.label}`}
    >
      {getIcon(node.type)} {node.label}
    </button>
  );
}

5. Visual Flow Indicators (Priority: Medium)

Complexity: Low
Estimated Effort: 1 day

Requirements:

  • Show flow direction (top-down or left-right)
  • Connecting lines between nodes
  • Branch points highlighted
  • Success/failure indicators
  • Timing information

CSS Implementation:

.tree-node {
  position: relative;
  padding-left: 24px;
}

.tree-node::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--cds-border-subtle);
}

.tree-node::after {
  content: '';
  position: absolute;
  left: 0;
  top: 16px;
  width: 16px;
  height: 2px;
  background: var(--cds-border-subtle);
}

.tree-node.success::before {
  background: var(--cds-support-success);
}

.tree-node.failure::before {
  background: var(--cds-support-error);
}

6. Search and Filter (Priority: Medium)

Complexity: Medium
Estimated Effort: 1-2 days

Requirements:

  • Search by action name
  • Filter by node type (actions only, screenshots only)
  • Filter by success/failure
  • Highlight search matches in tree
  • Auto-expand to show matches

UI/UX Design

Layout Options

Option 1: Side Panel

┌────────────────┬───────────────────────────────────┐
│ Flow Tree      │ Screenshot Gallery / Details      │
│ ────────────── │                                   │
│ ▼ Bio Dashboard│   [Main content area]             │
│  ├─ Navigate   │                                   │
│  ├─ Click Bio  │                                   │
│  ├─▶Upload     │                                   │
│  │  ├─ Open   │                                   │
│  │  ├─ Select │                                   │
│  │  └─ Confirm│                                   │
│  └─ Delete     │                                   │
│                │                                   │
│ [Expand All]   │                                   │
│ [Collapse All] │                                   │
└────────────────┴───────────────────────────────────┘

Option 2: Top Panel

┌──────────────────────────────────────────────────┐
│ Flow Tree (Horizontal)                           │
│ ────────────────────────────────────────────────│
│ [Start] → [Navigate] → [Click] → [Upload] → ... │
└──────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────┐
│ Details / Screenshots                            │
│                                                  │
└──────────────────────────────────────────────────┘

Recommendation: Side panel (Option 1) for better vertical space utilization


Data Model

UI Flow Tree Schema

// Generated from draw.io diagram + test manifest
interface UIFlowTree {
  id: string; // Test run ID
  rootNode: UIFlowNode;
  metadata: {
    testName: string;
    branch: string;
    commit: string;
    timestamp: string;
    totalSteps: number;
    passed: boolean;
  };
}

// Example tree structure
const exampleTree: UIFlowTree = {
  id: '1765676217672-c7b32fe',
  rootNode: {
    id: 'root',
    type: 'navigation',
    label: 'Bio Dashboard - Desktop',
    icon: '📱',
    children: [
      {
        id: 'step-1',
        type: 'navigation',
        label: 'Navigate to /dashboard',
        icon: '🌐',
        metadata: { route: '/dashboard' },
        children: [
          {
            id: 'screenshot-1',
            type: 'screenshot',
            label: 'Dashboard home',
            icon: '📸',
            screenshot: {
              path: 'screenshots/dashboard-home.png',
              thumbnail: 'screenshots/dashboard-home-thumb.png',
              capturePoint: 'after'
            },
            children: []
          }
        ]
      },
      // ... more nodes
    ]
  },
  metadata: {
    testName: 'Bio Dashboard Flow',
    branch: 'main',
    commit: 'c7b32fe',
    timestamp: '2025-12-14T01:10:17.672Z',
    totalSteps: 10,
    passed: true
  }
};

Generation from Manifest

// Generate tree from test manifest + draw.io metadata
function generateFlowTree(
  manifest: TestManifest,
  diagram: DrawioDiagram
): UIFlowTree {
  // Parse diagram interactions
  const interactions = parseDrawioInteractions(diagram);

  // Build tree from interaction sequence
  const rootNode = buildTreeFromInteractions(interactions, manifest);

  // Add screenshot nodes
  addScreenshotNodes(rootNode, manifest.screenshots);

  return {
    id: manifest.id,
    rootNode,
    metadata: extractMetadata(manifest)
  };
}

Implementation Plan

Phase 1: Core Tree Component (2-3 days)

  • Build recursive tree component
  • Add expand/collapse functionality
  • Implement tree state management
  • Add basic styling

Phase 2: Screenshot Integration (1 day)

  • Embed thumbnail previews
  • Add hover enlargement
  • Integrate with lightbox
  • Show diff indicators

Phase 3: Navigation (2 days)

  • Implement click handlers for all node types
  • Add scroll-to-step functionality
  • Highlight active nodes
  • Bidirectional sync with test list

Phase 4: Polish (1-2 days)

  • Search and filter
  • Visual flow indicators
  • Keyboard navigation
  • Performance optimization

Acceptance Criteria

  • Tree structure displays complete UI flow hierarchy
  • Screenshots appear as inline thumbnails
  • Expand/collapse works smoothly
  • Clicking nodes navigates to corresponding content
  • Search highlights matches in tree
  • Visual flow indicators show success/failure
  • Keyboard navigation fully supported
  • Tree state persists across page reloads
  • Performance: Tree renders in <500ms for 100+ nodes
  • Accessibility: Screen reader compatible

Technical Considerations

Performance

  • Use virtualization for large trees (>1000 nodes)
  • Lazy-load thumbnails
  • Memoize tree node components
  • Debounce search input

Accessibility

  • ARIA tree role and attributes
  • Keyboard navigation (arrows, home, end)
  • Focus management
  • Screen reader announcements

Related Issues


Success Metrics

  • Users can understand entire UI flow at a glance
  • Navigation to specific steps is <2 clicks
  • Tree expansion state helps users resume where they left off
  • Screenshot previews provide immediate visual context

This feature provides a powerful alternative navigation paradigm that makes complex UI flows easy to explore and understand!

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    UIUser interfaceenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions