| name | cua-wechat-devtools-ui-inspection |
| description | Use Cua Driver to inspect and navigate WeChat DevTools simulator for Mini Program UI visual review. Covers AX tree quirks, pixel-click strategies, and NW.js limitations. |
๐ชท Cua Driver + WeChat DevTools UI Inspection
Use when you need to visually inspect a Mini Program page in WeChat DevTools simulator โ checking UI effects, layout, animations, or background images. This is NOT for debugging gray screens (see wechat-devtools-gray-screen-debug).
Limitations (CRITICAL โ read first)
| Limitation | Detail |
|---|
| No CDP support | DevTools is NW.js (Chromium fork) โ mcp_cua_driver_page(execute_javascript) and browser_* tools do NOT work |
| AX tree is flat | DevTools NW.js window has 900+ AX elements, all as AXStaticText or AXLink โ no AXButton elements for the simulator UI |
| Simulator is a WebView | The iPhone simulator content (tabBar, page content) is rendered inside an internal WebView, not as native macOS elements |
| AX tree โ screenshot | The AX tree may update before the screenshot capture โ they can disagree on what's displayed |
| Vision coordinates are unreliable | vision_analyze often misestimates simulator content boundaries by hundreds of pixels |
Step-by-Step Inspection Flow
Step 1: Open DevTools
open /Applications/wechatwebdevtools.app --args /path/to/miniprogram
Step 2: Find the DevTools window
result = mcp_cua_driver_list_windows(on_screen_only=True)
Step 3: Get AX tree + screenshot
result = mcp_cua_driver_get_window_state(pid=DEVELOPER_PID, window_id=WINDOW_ID)
Step 4: Navigate to target page
Preferred method: AX element click โ Only works if the target is a native AX element with actions=[press].
Most simulator UI elements are AXStaticText with only [showmenu,scrolltovisible] โ these CANNOT be clicked.
Fallback: Pixel click โ Use vision_analyze with annotate=true to estimate coordinates, then click:
window_size = get_window_state(pid, window_id)
vision_analyze(image_url="/tmp/screenshot.png", question="Where is the 'ๅฟตไฝ' tab button? Give pixel coords relative to the full screenshot (0,0 top-left) of the screenshot = WxH pixels")
mcp_cua_driver_click(pid=DEVELOPER_PID, window_id=WINDOW_ID, x=ESTIMATED_X, y=ESTIMATED_Y)
Navigator alternative: Use DevTools "้กต้ข่ทฏๅพ" selector
Look in the AX tree for elements containing "้กต้ข่ทฏๅพ" โ this is a dropdown near the bottom of the simulator toolbar. Click it and select the target page path.
Ax tree grep trick: Save the raw AX tree output to a file, then grep for target page content:
with open("/tmp/ax_tree.txt") as f:
text = f.read()
if "target_page_content" in text:
print("Page already loaded in AX tree!")
Step 5: Handle tabBar navigation
The bottom tab bar (ๅฟตไฝ/ๆ
ไบ/ๆดๅค) is rendered inside the WebView โ elements appear as AXStaticText in the tree. To switch tabs:
- Check if page is already loaded: The AX tree may contain elements from BOTH the current visible page AND a pre-loaded page. Look for distinctive UI text (e.g., "ๆฅๆณ่ง", "ๅ็ก้ฟๅฝ้ไฝ", "้ปๆๅฟตไฝ").
- Click on tab: Use pixel coordinates. The tab bar is at the bottom of the simulator content area.
- Welcome page overlay: If the welcome/onboarding page covers the content, click the "ไธไธๆญฅ โ" or "่ทณ้ๅผๅฐ" button first.
Step 6: Confirm navigation
result = mcp_cua_driver_get_window_state(pid=DEVELOPER_PID, window_id=WINDOW_ID, capture_mode="vision", screenshot_out_file="/tmp/new_state.png")
vision_analyze(image_url="/tmp/new_state.png", question="Is the target page displayed? Describe the UI.")
Pitfalls
๐จ Page Path Combo Box: Unreliable Text Entry
DevTools bottom toolbar has a combo box showing current page path (e.g., pages/index/index). It appears as AXTextField in the AX tree.
The combo box text entry via CGEvent often fails silently โ the text targets the NW.js process but misses the focused element due to the nested WebView architecture. If you try type_text + press_key(return) and the page doesn't change, DON'T retry more than 2-3 times. Use the compile-mode approach instead.
Confirmed: Double-clicking a file in the resource manager DOES NOT load it in the simulator. It only opens the file for editing.
๐จ AX Tree Confirms Content Before Screenshot
A powerful diagnostic trick: grep the raw AX tree text for UI text that should only appear on the target page. If found, the page IS loaded even if the screenshot shows something else.
with open(\"/tmp/ax_tree.txt\") as f:
tree = f.read()
if \"ๆฅๆณ่ง\" in tree or \"้ปๆๅฟตไฝ\" in tree:
print(\"โ
Chanting page content detected in AX tree!\")
print(\" Screenshot may be stale โ page is actually loaded.\")
๐จ Vision Coordinate Errors
vision_analyze frequently reports wrong coordinates for the simulator content area. It may claim the simulator spans the ENTIRE DevTools window (0,0 to 1568,1057) when it's actually only the left ~430px. Never trust vision coordinates blindly โ cross-reference with the AX tree structure.
๐จ Welcome Page Overlay
The onboarding component (components/onboarding/) can overlay the main page content. It's controlled by data.settings.tutorialDone. If visible:
- Click "่ทณ้ๅผๅฐ" (Skip Guide) text link
- Or click "ไธไธๆญฅ โ" until tutorial completes
- The modal is in the WXML as
<onboarding visible="{{showOnboarding}}">
๐จ Canvas 2D โ DevTools
WeChat DevTools simulator does NOT support Canvas 2D properly. Any canvas type="2d" effects (golden light, mandala) will be invisible in the simulator. Only visible on real devices.
๐จ DevTools = NW.js (not standard Chrome)
- No CDP (Chrome DevTools Protocol) โ
page.execute_javascript fails
- No standard browser automation tools work
- Only AX tree navigation + pixel clicks are viable
๐จ TabBar Path Mapping
The bottom tab bar component (components/bottom-tab/) maps tab keys to page paths:
index โ /pages/index/index (main chanting page)
story โ /pages/story/story (stories)
more โ /pages/more/more (more menu)
If the user wants to see a DIFFERENT page (e.g., pages/virtue/chanting/chanting), either:
- Navigate via the "้กต้ข่ทฏๅพ" dropdown in the simulator toolbar
- Or trigger navigation from the parent page programmatically
๐ฏ Page Path Navigation: How It Actually Works
The "้กต้ข่ทฏๅพ" Control
DevTools bottom status bar has a combo box (NOT a pure dropdown) showing the current page path (e.g., pages/index/index). In the AX tree, this appears as a AXTextField.
Key insight: This is NOT a standard HTML combobox. It's part of the NW.js WebView chrome (DevTools chrome, not the Mini Program). The Cua Driver's type_text() CAN inject text into it via CGEvent post, but:
- Must focus the field first โ click at roughly X=50, Y=1030 (bottom-left region of DevTools window)
- Type the full path โ e.g.,
pages/virtue/chanting/chanting
- Press Return to navigate
โ ๏ธ This often fails silently โ the text appears to go nowhere because the CGEvent path targets the NW.js process but misses the focused element. Alternative approaches below.
๐ฅ BEST Approach: Compile Target Page Directly
Use DevTools top toolbar's "ๆฎ้็ทจ่ญฏ" dropdown to set the entry page BEFORE compiling:
- Click the "ๆฎ้็ทจ่ญฏ" dropdown (top toolbar, center area, roughly Y=60-80)
- Select "ๆทปๅ ็ทจ่ญฏๆจกๅผ" (Add Compile Mode)
- Set "ๅๅ้ ้ข" (Start Page) to your target path
- Click "็ทจ่ญฏ" (Compile) button
This is more reliable than trying to hot-navigate after loading.
๐ฅ BONUS: Quick Compile with Custom Entry Page
If the DevTools is ALREADY open and compiled, you can also:
- Click the "ๆฎ้็ทจ่ญฏ" dropdown โ "ๆทปๅ ็ทจ่ญฏๆจกๅผ"
- Set "ๅๅ้ ้ข" to
pages/virtue/chanting/chanting (or target)
- Click "็ขบๅฎ"
- Click "็ทจ่ญฏ" to recompile with the new entry page
This bypasses the unreliable page-path hot-swap entirely.
๐ฅ Click the Tab Bar to Switch
For tabBar pages (index/story/more), clicking the bottom tab works IF the page is a registered tab:
- The tab bar is rendered INSIDE the simulator WebView
- Elements appear as
AXStaticText with role AXLink โ check for actions=[press]
- If
AXLink with press action โ use mcp_cua_driver_click(element_index=N)
- If
AXStaticText only โ fallback to pixel click on the bottom of simulator content area
Warning: Onboarding overlay blocks tab clicks. If the welcome/onboarding modal is visible, tab bar clicks won't register. Click "่ทณ้ๅผๅฐ" first.
๐ฅ Double-Click File in Resource Manager
DOES NOT switch the simulator page โ it only opens the file for editing in the code editor panel.
โ ๏ธ DO NOT Use
mcp_cua_driver_page() โ DevTools is NW.js, not standard Chrome/Brave, so CDP/web-driver methods FAIL
browser_* tools โ same reason
- Typed text into page path without clicking first โ text goes to wrong element
Fallback: DevTools CLI with Open-Other
Use DevTools CLI to open a specific page:
open /Applications/wechatwebdevtools.app --args /path/to/miniprogram --open 'pages/virtue/chanting/chanting'
Page Path Quick Reference
| Purpose | Path |
|---|
| Main chanting page (tabBar) | pages/index/index |
| Elaborate chanting hall | pages/virtue/chanting/chanting |
| Stories list | pages/story/story |
| Story play | pages/story/play |
DevTools Window Anatomy (for coordinate estimation)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Top Toolbar (Y=0-80) โ
โ [ๆจกๆๅจ][็ผ่พๅจ][่ฐ่ฏๅจ] [ๅฐ็จๅบๆจกๅผโผ][ๆฎ้็ผ่ฏโผ] โ
โ โ
โโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโค
โSimulator โ Resource Manager โ Console/Debugger โ
โ(X=10-430) โ (X=430-800) โ (X=800-1568) โ
โ Y=80-950 โ โ โ
โ โ โ โ
โ [iPhone] โ โถ pages/ โ Warnings/Errors โ
โ preview โ index/ โ โ
โ โ story/ โ โ
โ โ virtue/ โ โ
โ โ chanting/ โ โ
โ โ *.js/wxml โ โ
โโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโค
โBottom status bar (Y=950-1057) โ
โ[้กต้ข่ทฏๅพโผ pages/index/index] [็ผ่ฏ็ถๆ] [้่ฏฏ: 2] โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
(Screen dimensions: 1568ร1057 for a roughly half-screen window)
Quick Reference: AX Tree Structure
- [0] AXWindow "ไฝๅฟ - ๅพฎไฟกๅผๅ่
ๅทฅๅ
ท"
- [1] AXTextField "็ถฒๅ่ๆๅฐๅ"
- [2] AXWebArea [actions=[showmenu,scrolltovisible]]
- [8] AXStaticText = "ๆจกๆๅจ" โ Tab buttons
- [9] AXStaticText = "็ผ่พๅจ" โ Tab buttons
- [10] AXStaticText = "่ฐ่ฏๅจ" โ Tab buttons
...
- [34] AXWebArea "Webview: pages/index/index" โ Simulator content
- [35] AXStaticText = "็ปๅพๅบๅ"
...
- [37] AXStaticText = "ๆฅๆณ่ง" โ Actually from wx Mini Program
- [38] AXStaticText = "ๅ็ก"
- [39] AXStaticText = "้ฟๅฝ้ไฝ"