tauri-mcp-testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTauri MCP E2E Testing
Tauri MCP 端到端测试
CRITICAL: For E2E testing of Tauri applications, ALWAYS use MCP tools. NEVER use Chrome DevTools MCP - that's for browser pages only.
tauri_*重要提示: 对Tauri应用进行端到端测试时,请始终使用系列MCP工具。切勿使用Chrome DevTools MCP——它仅适用于浏览器页面。
tauri_*Quick Reference
快速参考
| Task | MCP Tool |
|---|---|
| Connect to app | |
| Take screenshot | |
| Find elements | |
| Click/scroll/swipe | |
| Type text | |
| Wait for element | |
| Execute JS | |
| Get CSS styles | |
| Test IPC commands | |
| Monitor IPC calls | |
| Read console logs | |
| Manage windows | |
| 任务 | MCP工具 |
|---|---|
| 连接至应用 | |
| 截取屏幕截图 | |
| 查找元素 | |
| 点击/滚动/滑动 | |
| 输入文本 | |
| 等待元素加载 | |
| 执行JavaScript | |
| 获取CSS样式 | |
| 测试IPC命令 | |
| 监控IPC调用 | |
| 读取控制台日志 | |
| 管理窗口 | |
Prerequisites
前置条件
- MCP Bridge Plugin installed in the Tauri app
- App running in development mode ()
pnpm tauri dev - Port 9223 accessible (default MCP Bridge port)
If connection fails, run to get plugin installation guide.
tauri_get_setup_instructions- Tauri应用中已安装MCP Bridge插件
- 应用处于开发模式运行状态()
pnpm tauri dev - 9223端口可访问(默认MCP Bridge端口)
如果连接失败,请运行获取插件安装指南。
tauri_get_setup_instructionsCore 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 done1. 启动会话 → 连接至运行中的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, identifierstypescript
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
故障排除
| Issue | Solution |
|---|---|
| Connection refused | Ensure app is running with |
| No elements found | Check selector, take screenshot to verify DOM |
| IPC not captured | Start monitor BEFORE the action |
| Timeout on wait | Increase timeout, check if element ever appears |
| JS returns undefined | Use IIFE syntax: |
| Plugin not found | Run |
| 问题 | 解决方案 |
|---|---|
| 连接被拒绝 | 确保应用通过 |
| 未找到元素 | 检查选择器,截取截图验证DOM结构 |
| IPC调用未被捕获 | 在执行操作前启动监控 |
| 等待超时 | 增加超时时间,检查元素是否会出现 |
| JavaScript返回undefined | 使用立即执行函数表达式语法: |
| 未找到插件 | 运行 |
Reference Files
参考文件
| Topic | File |
|---|---|
| Session management | references/session-management.md |
| Webview testing | references/webview-testing.md |
| IPC testing | references/ipc-testing.md |
| Debugging | references/debugging.md |
| 主题 | 文件 |
|---|---|
| 会话管理 | references/session-management.md |
| Webview测试 | references/webview-testing.md |
| IPC测试 | references/ipc-testing.md |
| 调试 | references/debugging.md |
Related Skills
相关技能
- — General Tauri 2.0 patterns (commands, state, plugins, security)
tauri-app-dev - — VMark-specific IPC patterns (invoke/emit bridges, menu accelerators)
tauri-v2-integration - — VMark Rust backend implementation
rust-tauri-backend
- —— Tauri 2.0通用开发模式(命令、状态、插件、安全)
tauri-app-dev - —— 针对VMark的特定IPC模式(调用/触发桥接、菜单快捷键)
tauri-v2-integration - —— VMark Rust后端实现
rust-tauri-backend