tauri-mcp-testing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Tauri MCP E2E Testing

Tauri MCP 端到端测试

CRITICAL: For E2E testing of Tauri applications, ALWAYS use
tauri_*
MCP tools. NEVER use Chrome DevTools MCP - that's for browser pages only.
重要提示: 对Tauri应用进行端到端测试时,请始终使用
tauri_*
系列MCP工具。切勿使用Chrome DevTools MCP——它仅适用于浏览器页面。

Quick Reference

快速参考

TaskMCP Tool
Connect to app
tauri_driver_session
Take screenshot
tauri_webview_screenshot
Find elements
tauri_webview_find_element
Click/scroll/swipe
tauri_webview_interact
Type text
tauri_webview_keyboard
Wait for element
tauri_webview_wait_for
Execute JS
tauri_webview_execute_js
Get CSS styles
tauri_webview_get_styles
Test IPC commands
tauri_ipc_execute_command
Monitor IPC calls
tauri_ipc_monitor
Read console logs
tauri_read_logs
Manage windows
tauri_manage_window
任务MCP工具
连接至应用
tauri_driver_session
截取屏幕截图
tauri_webview_screenshot
查找元素
tauri_webview_find_element
点击/滚动/滑动
tauri_webview_interact
输入文本
tauri_webview_keyboard
等待元素加载
tauri_webview_wait_for
执行JavaScript
tauri_webview_execute_js
获取CSS样式
tauri_webview_get_styles
测试IPC命令
tauri_ipc_execute_command
监控IPC调用
tauri_ipc_monitor
读取控制台日志
tauri_read_logs
管理窗口
tauri_manage_window

Prerequisites

前置条件

  1. MCP Bridge Plugin installed in the Tauri app
  2. App running in development mode (
    pnpm tauri dev
    )
  3. Port 9223 accessible (default MCP Bridge port)
If connection fails, run
tauri_get_setup_instructions
to get plugin installation guide.
  1. Tauri应用中已安装MCP Bridge插件
  2. 应用处于开发模式运行状态
    pnpm tauri dev
  3. 9223端口可访问(默认MCP Bridge端口)
如果连接失败,请运行
tauri_get_setup_instructions
获取插件安装指南。

Core Workflow

核心工作流程

1. START SESSION    → Connect to running Tauri app
2. VERIFY STATE     → Screenshot + find elements
3. INTERACT         → Click, type, scroll
4. WAIT             → Wait for expected results
5. VERIFY           → Check IPC, logs, DOM state
6. CLEANUP          → Stop session when done
1. 启动会话    → 连接至运行中的Tauri应用
2. 验证状态     → 截图 + 查找元素
3. 交互操作         → 点击、输入、滚动
4. 等待             → 等待预期结果出现
5. 验证           → 检查IPC、日志、DOM状态
6. 清理操作          → 测试完成后停止会话

Session Management

会话管理

Start Session

启动会话

typescript
// Connect to app on default port
tauri_driver_session({ action: 'start' })

// Connect to specific port
tauri_driver_session({ action: 'start', port: 9224 })

// Connect to remote host (mobile testing)
tauri_driver_session({ action: 'start', host: '<device-ip>', port: 9223 })
typescript
// 连接至默认端口的应用
tauri_driver_session({ action: 'start' })

// 连接至指定端口
tauri_driver_session({ action: 'start', port: 9224 })

// 连接至远程主机(移动端测试)
tauri_driver_session({ action: 'start', host: '<device-ip>', port: 9223 })

Check Status

检查状态

typescript
tauri_driver_session({ action: 'status' })
// Returns: connected apps, default app, identifiers
typescript
tauri_driver_session({ action: 'status' })
// 返回值:已连接应用、默认应用、标识符

Stop Session

停止会话

typescript
// Stop all sessions
tauri_driver_session({ action: 'stop' })

// Stop specific app
tauri_driver_session({ action: 'stop', appIdentifier: 9223 })
typescript
// 停止所有会话
tauri_driver_session({ action: 'stop' })

// 停止指定应用的会话
tauri_driver_session({ action: 'stop', appIdentifier: 9223 })

Testing Patterns

测试模式

Pattern 1: Visual Verification

模式1:视觉验证

typescript
// 1. Take screenshot to see current state
tauri_webview_screenshot()

// 2. Take screenshot of specific element
tauri_webview_screenshot({ uid: 'editor-content' })

// 3. Save to file for comparison
tauri_webview_screenshot({ filePath: 'dev-docs/archive/test-screenshots/test-screenshot.png' })
typescript
// 1. 截取当前状态的截图
tauri_webview_screenshot()

// 2. 截取指定元素的截图
tauri_webview_screenshot({ uid: 'editor-content' })

// 3. 保存至文件用于对比
tauri_webview_screenshot({ filePath: 'dev-docs/archive/test-screenshots/test-screenshot.png' })

Pattern 2: Element Interaction

模式2:元素交互

typescript
// 1. Find element first
tauri_webview_find_element({ selector: '.save-button' })

// 2. Click element
tauri_webview_interact({ action: 'click', selector: '.save-button' })

// 3. Double-click
tauri_webview_interact({ action: 'double-click', selector: '.editor' })

// 4. Long-press (touch simulation)
tauri_webview_interact({ action: 'long-press', selector: '.item', duration: 500 })

// 5. Scroll
tauri_webview_interact({ action: 'scroll', selector: '.content', scrollY: 500 })

// 6. Swipe
tauri_webview_interact({
  action: 'swipe',
  fromX: 300, fromY: 400,
  toX: 100, toY: 400,
  duration: 300
})
typescript
// 1. 先查找元素
tauri_webview_find_element({ selector: '.save-button' })

// 2. 点击元素
tauri_webview_interact({ action: 'click', selector: '.save-button' })

// 3. 双击
tauri_webview_interact({ action: 'double-click', selector: '.editor' })

// 4. 长按(模拟触摸操作)
tauri_webview_interact({ action: 'long-press', selector: '.item', duration: 500 })

// 5. 滚动
tauri_webview_interact({ action: 'scroll', selector: '.content', scrollY: 500 })

// 6. 滑动
tauri_webview_interact({
  action: 'swipe',
  fromX: 300, fromY: 400,
  toX: 100, toY: 400,
  duration: 300
})

Pattern 3: Keyboard Input

模式3:键盘输入

typescript
// Type into focused element
tauri_webview_keyboard({
  action: 'type',
  selector: '.editor-input',
  text: '# Hello World'
})

// Press key
tauri_webview_keyboard({ action: 'press', key: 'Enter' })

// Key with modifiers
tauri_webview_keyboard({
  action: 'press',
  key: 's',
  modifiers: ['Control']  // Ctrl+S
})

// Key combinations
tauri_webview_keyboard({
  action: 'press',
  key: 'z',
  modifiers: ['Meta', 'Shift']  // Cmd+Shift+Z (redo on macOS)
})
typescript
// 向已聚焦的元素输入内容
tauri_webview_keyboard({
  action: 'type',
  selector: '.editor-input',
  text: '# Hello World'
})

// 按下单个按键
tauri_webview_keyboard({ action: 'press', key: 'Enter' })

// 带修饰键的按键操作
tauri_webview_keyboard({
  action: 'press',
  key: 's',
  modifiers: ['Control']  // Ctrl+S
})

// 组合键操作
tauri_webview_keyboard({
  action: 'press',
  key: 'z',
  modifiers: ['Meta', 'Shift']  // Cmd+Shift+Z(macOS上的重做操作)
})

Pattern 4: Wait for State

模式4:等待状态

typescript
// Wait for element to appear
tauri_webview_wait_for({
  type: 'selector',
  value: '.success-toast',
  timeout: 5000
})

// Wait for text to appear
tauri_webview_wait_for({
  type: 'text',
  value: 'File saved successfully',
  timeout: 3000
})

// Wait for IPC event
tauri_webview_wait_for({
  type: 'ipc-event',
  value: 'file-saved',
  timeout: 5000
})
typescript
// 等待元素出现
tauri_webview_wait_for({
  type: 'selector',
  value: '.success-toast',
  timeout: 5000
})

// 等待文本出现
tauri_webview_wait_for({
  type: 'text',
  value: 'File saved successfully',
  timeout: 3000
})

// 等待IPC事件
tauri_webview_wait_for({
  type: 'ipc-event',
  value: 'file-saved',
  timeout: 5000
})

Pattern 5: IPC Testing

模式5:IPC测试

typescript
// Start monitoring IPC calls
tauri_ipc_monitor({ action: 'start' })

// Perform action that triggers IPC
tauri_webview_interact({ action: 'click', selector: '.save-button' })

// Get captured IPC calls
tauri_ipc_get_captured({ filter: 'save_file' })

// Execute IPC command directly
tauri_ipc_execute_command({
  command: 'get_document_state',
  args: { id: 'doc-123' }
})

// Emit event to test handlers
tauri_ipc_emit_event({
  eventName: 'file-changed',
  payload: { path: '/test/file.md' }
})

// Stop monitoring
tauri_ipc_monitor({ action: 'stop' })
typescript
// 开始监控IPC调用
tauri_ipc_monitor({ action: 'start' })

// 执行触发IPC的操作
tauri_webview_interact({ action: 'click', selector: '.save-button' })

// 获取已捕获的IPC调用
tauri_ipc_get_captured({ filter: 'save_file' })

// 直接执行IPC命令
tauri_ipc_execute_command({
  command: 'get_document_state',
  args: { id: 'doc-123' }
})

// 触发事件以测试处理器
tauri_ipc_emit_event({
  eventName: 'file-changed',
  payload: { path: '/test/file.md' }
})

// 停止监控
tauri_ipc_monitor({ action: 'stop' })

Pattern 6: JavaScript Execution

模式6:JavaScript执行

typescript
// Get value from DOM (MUST use IIFE for return values)
tauri_webview_execute_js({
  script: '(() => { return document.querySelector(".editor").textContent; })()'
})

// Check Tauri API available
tauri_webview_execute_js({
  script: '(() => { return typeof window.__TAURI__ !== "undefined"; })()'
})

// Get computed style
tauri_webview_execute_js({
  script: '(() => { return getComputedStyle(document.body).backgroundColor; })()'
})

// Trigger custom event
tauri_webview_execute_js({
  script: 'document.dispatchEvent(new CustomEvent("test-event", { detail: { test: true } }))'
})
typescript
// 从DOM中获取值(必须使用立即执行函数表达式以返回值)
tauri_webview_execute_js({
  script: '(() => { return document.querySelector(".editor").textContent; })()'
})

// 检查Tauri API是否可用
tauri_webview_execute_js({
  script: '(() => { return typeof window.__TAURI__ !== "undefined"; })()'
})

// 获取计算样式
tauri_webview_execute_js({
  script: '(() => { return getComputedStyle(document.body).backgroundColor; })()'
})

// 触发自定义事件
tauri_webview_execute_js({
  script: 'document.dispatchEvent(new CustomEvent("test-event", { detail: { test: true } }))'
})

Debugging

调试

Read Console Logs

读取控制台日志

typescript
// Get recent console logs
tauri_read_logs({ source: 'console', lines: 50 })

// Filter logs
tauri_read_logs({ source: 'console', filter: 'error', lines: 100 })

// Logs since specific time
tauri_read_logs({
  source: 'console',
  since: '2024-01-01T10:00:00Z',
  lines: 50
})
typescript
// 获取近期控制台日志
tauri_read_logs({ source: 'console', lines: 50 })

// 过滤日志
tauri_read_logs({ source: 'console', filter: 'error', lines: 100 })

// 获取指定时间后的日志
tauri_read_logs({
  source: 'console',
  since: '2024-01-01T10:00:00Z',
  lines: 50
})

Platform-Specific Logs

平台特定日志

typescript
// Desktop system logs
tauri_read_logs({ source: 'system', lines: 100 })

// Android logcat
tauri_read_logs({ source: 'android', filter: 'vmark', lines: 100 })

// iOS simulator logs
tauri_read_logs({ source: 'ios', lines: 100 })
typescript
// 桌面系统日志
tauri_read_logs({ source: 'system', lines: 100 })

// Android Logcat日志
tauri_read_logs({ source: 'android', filter: 'vmark', lines: 100 })

// iOS模拟器日志
tauri_read_logs({ source: 'ios', lines: 100 })

Window Management

窗口管理

typescript
// List all windows
tauri_manage_window({ action: 'list' })

// Get window info
tauri_manage_window({ action: 'info', windowId: 'main' })

// Resize window for responsive testing
tauri_manage_window({ action: 'resize', width: 800, height: 600 })

// Resize specific window
tauri_manage_window({
  action: 'resize',
  windowId: 'settings',
  width: 400,
  height: 300
})
typescript
// 列出所有窗口
tauri_manage_window({ action: 'list' })

// 获取窗口信息
tauri_manage_window({ action: 'info', windowId: 'main' })

// 调整窗口大小以进行响应式测试
tauri_manage_window({ action: 'resize', width: 800, height: 600 })

// 调整指定窗口大小
tauri_manage_window({
  action: 'resize',
  windowId: 'settings',
  width: 400,
  height: 300
})

Get CSS Styles

获取CSS样式

typescript
// Get all computed styles
tauri_webview_get_styles({ selector: '.editor' })

// Get specific properties
tauri_webview_get_styles({
  selector: '.editor',
  properties: ['font-size', 'color', 'background-color']
})

// Get styles from multiple elements
tauri_webview_get_styles({
  selector: '.toolbar button',
  multiple: true,
  properties: ['opacity', 'visibility']
})
typescript
// 获取所有计算样式
tauri_webview_get_styles({ selector: '.editor' })

// 获取指定样式属性
tauri_webview_get_styles({
  selector: '.editor',
  properties: ['font-size', 'color', 'background-color']
})

// 获取多个元素的样式
tauri_webview_get_styles({
  selector: '.toolbar button',
  multiple: true,
  properties: ['opacity', 'visibility']
})

Common Test Scenarios

常见测试场景

Scenario: File Operations

场景:文件操作

typescript
// 1. Connect
tauri_driver_session({ action: 'start' })

// 2. Open file dialog
tauri_webview_keyboard({ action: 'press', key: 'o', modifiers: ['Control'] })

// 3. Wait for content to load (using IPC)
tauri_ipc_monitor({ action: 'start' })
// ... file selection happens externally or via mocked dialog ...
tauri_ipc_get_captured({ filter: 'read_file' })

// 4. Verify content loaded
tauri_webview_find_element({ selector: '.editor-content' })
tauri_webview_execute_js({
  script: '(() => { return document.querySelector(".editor-content").textContent.length > 0; })()'
})
typescript
// 1. 建立连接
tauri_driver_session({ action: 'start' })

// 2. 打开文件对话框
tauri_webview_keyboard({ action: 'press', key: 'o', modifiers: ['Control'] })

// 3. 等待内容加载(通过IPC)
tauri_ipc_monitor({ action: 'start' })
// ... 文件选择通过外部操作或模拟对话框完成 ...
tauri_ipc_get_captured({ filter: 'read_file' })

// 4. 验证内容已加载
tauri_webview_find_element({ selector: '.editor-content' })
tauri_webview_execute_js({
  script: '(() => { return document.querySelector(".editor-content").textContent.length > 0; })()'
})

Scenario: Editor Typing

场景:编辑器输入

typescript
// 1. Focus editor
tauri_webview_interact({ action: 'click', selector: '.editor' })

// 2. Type content
tauri_webview_keyboard({
  action: 'type',
  selector: '.editor [contenteditable]',
  text: '# Test Document\n\nThis is a test.'
})

// 3. Verify dirty state
tauri_webview_find_element({ selector: '[data-dirty="true"]' })

// 4. Save with Ctrl+S
tauri_webview_keyboard({ action: 'press', key: 's', modifiers: ['Control'] })

// 5. Verify saved
tauri_webview_wait_for({ type: 'selector', value: '[data-dirty="false"]' })
typescript
// 1. 聚焦编辑器
tauri_webview_interact({ action: 'click', selector: '.editor' })

// 2. 输入内容
tauri_webview_keyboard({
  action: 'type',
  selector: '.editor [contenteditable]',
  text: '# Test Document\n\nThis is a test.'
})

// 3. 验证文档处于未保存状态
tauri_webview_find_element({ selector: '[data-dirty="true"]' })

// 4. 使用Ctrl+S保存
tauri_webview_keyboard({ action: 'press', key: 's', modifiers: ['Control'] })

// 5. 验证已保存
tauri_webview_wait_for({ type: 'selector', value: '[data-dirty="false"]' })

Scenario: Responsive Testing

场景:响应式测试

typescript
// Test mobile viewport
tauri_manage_window({ action: 'resize', width: 375, height: 667 })
tauri_webview_screenshot({ filePath: 'dev-docs/archive/test-screenshots/mobile.png' })
tauri_webview_find_element({ selector: '.mobile-menu-button' })

// Test tablet viewport
tauri_manage_window({ action: 'resize', width: 768, height: 1024 })
tauri_webview_screenshot({ filePath: 'dev-docs/archive/test-screenshots/tablet.png' })

// Test desktop viewport
tauri_manage_window({ action: 'resize', width: 1920, height: 1080 })
tauri_webview_screenshot({ filePath: 'dev-docs/archive/test-screenshots/desktop.png' })
typescript
// 测试移动端视口
tauri_manage_window({ action: 'resize', width: 375, height: 667 })
tauri_webview_screenshot({ filePath: 'dev-docs/archive/test-screenshots/mobile.png' })
tauri_webview_find_element({ selector: '.mobile-menu-button' })

// 测试平板端视口
tauri_manage_window({ action: 'resize', width: 768, height: 1024 })
tauri_webview_screenshot({ filePath: 'dev-docs/archive/test-screenshots/tablet.png' })

// 测试桌面端视口
tauri_manage_window({ action: 'resize', width: 1920, height: 1080 })
tauri_webview_screenshot({ filePath: 'dev-docs/archive/test-screenshots/desktop.png' })

Troubleshooting

故障排除

IssueSolution
Connection refusedEnsure app is running with
pnpm tauri dev
No elements foundCheck selector, take screenshot to verify DOM
IPC not capturedStart monitor BEFORE the action
Timeout on waitIncrease timeout, check if element ever appears
JS returns undefinedUse IIFE syntax:
(() => { return value; })()
Plugin not foundRun
tauri_get_setup_instructions
问题解决方案
连接被拒绝确保应用通过
pnpm tauri dev
运行
未找到元素检查选择器,截取截图验证DOM结构
IPC调用未被捕获在执行操作前启动监控
等待超时增加超时时间,检查元素是否会出现
JavaScript返回undefined使用立即执行函数表达式语法:
(() => { return value; })()
未找到插件运行
tauri_get_setup_instructions

Reference Files

参考文件

TopicFile
Session managementreferences/session-management.md
Webview testingreferences/webview-testing.md
IPC testingreferences/ipc-testing.md
Debuggingreferences/debugging.md
主题文件
会话管理references/session-management.md
Webview测试references/webview-testing.md
IPC测试references/ipc-testing.md
调试references/debugging.md

Related Skills

相关技能

  • tauri-app-dev
    — General Tauri 2.0 patterns (commands, state, plugins, security)
  • tauri-v2-integration
    — VMark-specific IPC patterns (invoke/emit bridges, menu accelerators)
  • rust-tauri-backend
    — VMark Rust backend implementation
  • tauri-app-dev
    —— Tauri 2.0通用开发模式(命令、状态、插件、安全)
  • tauri-v2-integration
    —— 针对VMark的特定IPC模式(调用/触发桥接、菜单快捷键)
  • rust-tauri-backend
    —— VMark Rust后端实现