mcpField
T
tui-validate

tui-validate

github.com/mikeyobrien测试与质量3.2k49 次安装2 周前更新
代码仓库

关于 tui-validate

tui-validate 是用于测试终端用户界面的技能,通过捕获终端输出并借助 LLM 进行语义或视觉判断。它为应用开发和测试流程提供预设及自定义标准。

主要功能

  1. 01捕获文件、命令、tmux 或缓冲区输出
  2. 02支持语义、严格和视觉验证模式
  3. 03内置 Ralph 和通用 TUI 验证标准
  4. 04保存为 SVG、PNG 或文本

适用场景

  1. 01检查代码变更后的 TUI 布局
  2. 02验证交互后的界面状态
  3. 03生成经过验证的终端截图
  4. 04对终端应用执行视觉回归检查

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mikeyobrien/ralph-orchestrator --skill tui-validate

安装后在 Claude Code 中输入/tui-validate确认已加载。

详细介绍

TUI Validate

概述

此技能通过捕获 TUI 应用的输出,并使用 LLM-as-judge 进行语义验证,来验证终端用户界面(TUI)应用。它借助 Charmbracelet 的 freeze 生成高保真终端截图,并提供结构化的验证标准。

理念:此技能不采用脆弱的字符串匹配,而是利用语义理解来验证 TUI 输出是否“看起来正确”——检查布局、内容是否存在以及视觉层级,避免因细微的格式变化而失败。

适用场景

  • 更改后验证 TUI 渲染效果
  • 检查 UI 组件是否正确显示
  • 对终端应用进行视觉回归测试
  • 验证特定交互后的 TUI 状态
  • 创建带验证的文档截图

先决条件

必需:

  • 已安装 freeze CLI 工具(brew install charmbracelet/tap/freeze)
  • 用于交互式 TUI 捕获的 tmux(可选,适用于实时应用)

验证:

# Check freeze is installed
freeze --version

# Check tmux is installed (for interactive capture)
tmux -V

参数

  • target(必需):要验证的目标。可以是以下之一:

    • file:<path> - 要验证的 ANSI 输出文件
    • command:<cmd> - 要执行并捕获输出的命令
    • tmux:<session> - 要捕获的实时 tmux 会话
    • buffer:<text> - 要验证的原始文本/ANSI
  • criteria(必需):验证标准。可以是:

    • 预定义的标准名称(参见内置标准)
    • 描述检查内容的自定义标准字符串
  • output_format(可选,默认值:"svg"):截图格式

    • svg - 矢量格式,最适合文档
    • png - 光栅格式,最适合视觉差异比较
    • text - 仅提取文本,速度最快
  • save_screenshot(可选,默认值:false):是否保存截图

    • 如果为 true,则在当前目录中保存为 {target_name}.{format}
  • judge_mode(可选,默认值:"semantic"):验证方式

    • semantic - LLM 根据含义和布局进行判断
    • strict - 同时检查确切内容是否存在
    • visual - 要求使用 PNG,并检查视觉效果

内置标准

ralph-header

验证 Ralph TUI 页眉组件:

  • 迭代计数器,格式为 [iter N] 或 [iter N/M]
  • MM:SS 格式的已用时间
  • 带表情符号和名称的帽子指示器
  • 模式指示器(▶ auto 或 ⏸ paused)
  • 可选的滚动模式指示器 [SCROLL]
  • 可选的空闲倒计时 idle: Ns
ralph-footer

验证 Ralph TUI 页脚组件:

  • 活动指示器(◉ active、◯ idle 或 ■ done)
  • 最近事件主题显示
  • 激活时显示搜索模式
ralph-full

验证完整的 Ralph TUI 布局:

  • 顶部的页眉区域(3 行)
  • 终端内容区域(高度可变)
  • 底部的页脚区域(3 行)
  • 适当的视觉层级和边框
tui-basic

通用 TUI 验证:

  • 存在可见内容(非空白)
  • 没有渲染瑕疵或乱码字符
  • 终端尺寸适当

执行流程

1. 捕获阶段

根据目标类型捕获 TUI 输出:

对于文件目标:

freeze {file_path} -o /tmp/tui-capture.{format}

对于命令目标:

freeze --execute "{command}" -o /tmp/tui-capture.{format}

对于 tmux 目标:

tmux capture-pane -pet {session} | freeze -o /tmp/tui-capture.{format}

对于缓冲区目标:

echo "{buffer}" | freeze -o /tmp/tui-capture.{format}

约束:

  • 在尝试捕获之前,必须确认已安装 freeze
  • 必须妥善处理捕获失败并报告错误
  • 必须根据输出格式使用合适的 freeze 标志
  • 应使用 --theme base16 以确保渲染一致
  • 应使用 --width 和 --height 设置合理的尺寸
2. 提取阶段

提取内容以供 LLM 分析:

对于文本/语义验证:

  • 如果格式为 text,直接使用捕获的文本
  • 如果格式为 svg 或 png,还要捕获文本版本以供内容分析

对于视觉验证:

  • 必须使用 PNG 格式
  • 将直接使用视觉能力分析图像

约束:

  • 当 judge_mode 为 visual 时,必须同时提取视觉和文本表示
  • 相关情况下,必须保留 ANSI 转义序列以验证颜色
3. 验证阶段

使用 LLM-as-judge,并采用适当的标准:

语义验证提示词模板:

Analyze this terminal UI output and determine if it meets the following criteria:

CRITERIA:
{criteria_description}

TERMINAL OUTPUT:
{captured_text}

Evaluate each criterion and provide:
1. PASS or FAIL for each requirement
2. Brief explanation for any failures
3. Overall verdict: PASS or FAIL

Be lenient on exact formatting but strict on:
- Required content presence
- Logical layout and hierarchy
- No rendering errors or artifacts

视觉验证提示词模板(含图像):

Examine this terminal screenshot and validate:

CRITERIA:
{criteria_description}

Check for:
1. Visual hierarchy and layout
2. Color coding correctness
3. No rendering artifacts or broken characters
4. Proper alignment and spacing

Verdict: PASS or FAIL with explanation

约束:

  • 必须给出明确的 PASS 或 FAIL 判定
  • 失败时必须提供具体反馈
  • 对空白字符/格式差异必须宽容
  • 对内容是否齐全及语义是否正确必须严格
  • 即使判定为 PASS,也应指出任何警告
4. 报告阶段

报告验证结果:

PASS 时:

✅ TUI Validation PASSED

Criteria: {criteria_name}
Target: {target}
Mode: {judge_mode}

All requirements satisfied.
{optional_notes}

FAIL 时:

❌ TUI Validation FAILED

Criteria: {criteria_name}
Target: {target}
Mode: {judge_mode}

Issues found:
- {issue_1}
- {issue_2}

Screenshot saved: {path_if_saved}

约束:

  • 必须始终给出明确判定
  • 失败时必须列出具体问题
  • 如果已保存截图,必须提供截图路径
  • 应针对常见问题提出修复建议

示例

示例 1:从文件验证 Ralph Header

输入:

/tui-validate file:test_output.txt criteria:ralph-header

流程:

  1. 读取包含 ANSI 输出的 test_output.txt
  2. 使用 freeze 截图:freeze test_output.txt -o /tmp/capture.svg
  3. 提取文本内容
  4. 通过 LLM judge 应用 ralph-header 标准
  5. 报告 PASS/FAIL 及详情
示例 2:在 tmux 中验证实时 TUI

输入:

/tui-validate tmux:ralph-session criteria:ralph-full save_screenshot:true

流程:

  1. 截取 tmux 窗格:tmux capture-pane -pet ralph-session | freeze -o ralph-session.svg
  2. 同时截取文本:tmux capture-pane -pet ralph-session > /tmp/text.txt
  3. 应用 ralph-full 标准,检查标题、内容和页脚
  4. 将截图保存到 ralph-session.svg
  5. 报告验证结果
示例 3:自定义标准验证

输入:

/tui-validate command:"cargo run --example tui_demo" criteria:"Shows a bordered box with 'Hello World' text centered inside" output_format:png judge_mode:visual

流程:

  1. 执行命令并截图:freeze --execute "cargo run --example tui_demo" -o /tmp/capture.png
  2. 使用视觉模型分析 PNG
  3. 检查是否存在带边框的框和居中文字
  4. 报告视觉验证结果
示例 4:快速文本验证

输入:

/tui-validate buffer:"[iter 3/10] 04:32 | 🔨 Builder | ▶ auto" criteria:ralph-header output_format:text

流程:

  1. 直接分析文本(使用缓冲区的文本模式无需 freeze)
  2. 检查迭代格式、已用时间、提示帽和模式指示器
  3. 报告验证结果

标准定义

ralph-header(完整定义)
name: ralph-header
description: Ralph TUI header component validation
requirements:
  - name: iteration_counter
    description: Shows iteration in [iter N] or [iter N/M] format
    required: true
    pattern: '\[iter \d+(/\d+)?\]'

  - name: elapsed_time
    description: Shows elapsed time in MM:SS format
    required: true
    pattern: '\d{2}:\d{2}'

  - name: hat_indicator
    description: Shows current hat with emoji prefix
    required: true
    examples: ["🔨 Builder", "📋 Planner", "🎯 Executor"]

  - name: mode_indicator
    description: Shows loop mode status
    required: true
    values: ["▶ auto", "⏸ paused"]

  - name: scroll_indicator
    description: Shows [SCROLL] when in scroll mode
    required: false
    pattern: '\[SCROLL\]'

  - name: idle_countdown
    description: Shows idle timeout when present
    required: false
    pattern: 'idle: \d+s'
ralph-footer(完整定义)
name: ralph-footer
description: Ralph TUI footer component validation
requirements:
  - name: activity_indicator
    description: Shows current activity state
    required: true
    values: ["◉ active", "◯ idle", "■ done"]

  - name: event_topic
    description: Shows last event topic
    required: false
    examples: ["task.start", "build.done", "loop.terminate"]

  - name: search_display
    description: Shows search query and match count when searching
    required: false
    pattern: 'Search: .+ \d+/\d+'
ralph-full(完整定义)
name: ralph-full
description: Complete Ralph TUI layout validation
requirements:
  - name: header_section
    description: Header at top with iteration, time, hat, and mode
    required: true
    references: ralph-header

  - name: content_section
    description: Main terminal content area
    required: true
    checks:
      - Has visible content or is ready for content
      - Properly bounded between header and footer

  - name: footer_section
    description: Footer at bottom with activity status
    required: true
    references: ralph-footer

  - name: visual_hierarchy
    description: Clear visual separation between sections
    required: true
    checks:
      - Borders or spacing between sections
      - Consistent width across sections

故障排除

找不到 freeze
# macOS
brew install charmbracelet/tap/freeze

# Linux (via Go)
go install github.com/charmbracelet/freeze@latest

# Verify installation
freeze --version
tmux 截取失败
  • 确认 tmux 会话存在:tmux list-sessions
  • 检查窗格编号:tmux list-panes -t {session}
  • 尝试截取指定窗格:tmux capture-pane -pet {session}:{pane}
截图中出现渲染异常
  • 尝试在 freeze 中使用不同的终端模拟器设置
  • 使用 --theme 标志统一颜色
  • 确保终端尺寸符合 TUI 的预期
LLM judge 过于严格/宽松
  • 调整标准,使其更加具体
  • 对精确匹配要求使用 strict 模式
  • 对布局/内容存在性检查使用 semantic 模式

与测试集成

此技能可以集成到测试套件中:

// In tests/tui_validation.rs
#[test]
#[ignore] // Run with: cargo test -- --ignored
fn validate_header_rendering() {
    // 1. Render header to buffer
    let output = render_header_to_string(&test_state);

    // 2. Save to temp file
    std::fs::write("/tmp/header_test.txt", &output).unwrap();

    // 3. Run tui-validate skill (via CLI or programmatic)
    // /tui-validate file:/tmp/header_test.txt criteria:ralph-header

    // 4. Assert validation passed
}

最佳实践

  1. 使用语义验证检查布局 - 不要因细微的格式差异而失败
  2. 使用严格验证检查内容要求 - 确保包含关键信息
  3. 失败时保存截图 - 有助于调试
  4. 使用不同的终端尺寸进行测试 - TUI 应具备响应能力
  5. 结合单元测试使用 - 使用此技能进行集成/视觉验证,使用单元测试检查逻辑

评论

支持 Markdown