Fix wxTreeCtrl test crash and update test coordinates

- Add null guard in TreeTestFrame::LogEvent() to prevent crash when
  events fire before m_log is initialized during tree population
- Update button click coordinates in tree.spec.ts for Add Item and
  Delete Selected buttons
- Update WHATWORKS.md to reflect wxTreeCtrl now fully working (7/7 tests)
- Update baseline screenshots for tree tests

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Viktor Vaczi 2025-11-29 22:28:30 +01:00
commit 90613dbe49
10 changed files with 28 additions and 25 deletions

View file

@ -11,7 +11,7 @@ Last updated: 2025-11-29
| Main App Load | WORKS | minimal_test.html loads and renders correctly | | Main App Load | WORKS | minimal_test.html loads and renders correctly |
| Standalone Apps | WORKS | 10 standalone test apps | | Standalone Apps | WORKS | 10 standalone test apps |
| wxGrid | WORKS | Grid renders with cells, labels, and event handling | | wxGrid | WORKS | Grid renders with cells, labels, and event handling |
| wxTreeCtrl | BROKEN | Crashes on startup | | wxTreeCtrl | WORKS | Tree renders with expand/collapse, selection, add/delete items |
| wxTimer | PARTIAL | Timer test app works, some tests have coordinate issues | | wxTimer | PARTIAL | Timer test app works, some tests have coordinate issues |
| wxDialog | WORKS | Modal dialogs render correctly with Asyncify | | wxDialog | WORKS | Modal dialogs render correctly with Asyncify |
@ -87,13 +87,13 @@ This section maps KiCad's wxWidgets usage to our test coverage.
--- ---
## BROKEN Features ## Previously BROKEN Features (Now Fixed)
### wxTreeCtrl - CRASHES ### wxTreeCtrl - WORKS ✓
- **Status**: Standalone tree_test crashes on startup - **Status**: Tree control fully functional with expand/collapse, selection, add/delete
- **KiCad Impact**: HIGH - KiCad uses wxTreeCtrl for hierarchy browsers, component trees - **KiCad Impact**: HIGH - KiCad uses wxTreeCtrl for hierarchy browsers, component trees
- **Evidence**: tree-01-loaded.png shows red error "Exception thrown, see JavaScript console" - **Evidence**: tree-01-loaded.png shows tree with KiCad-like hierarchy
- **Note**: May have similar root cause to the wxGrid crash (event handling during initialization) - **Fix**: Added null guard in LogEvent() - events fired before m_log was initialized
### wxMessageBox/wxDialog - WORKING ✓ ### wxMessageBox/wxDialog - WORKING ✓
- **Status**: Modal dialogs render correctly with Asyncify - **Status**: Modal dialogs render correctly with Asyncify
@ -125,7 +125,7 @@ Organized in `wasm-app/standalone/` folders:
| grid/grid_test | WORKS | 2/2 | Property grids | | grid/grid_test | WORKS | 2/2 | Property grids |
| dialog/dialog_test | WORKS | 5/5 | Alerts/confirmations | | dialog/dialog_test | WORKS | 5/5 | Alerts/confirmations |
| timer/timer_test | PARTIAL | 1/4 | Auto-save, animations | | timer/timer_test | PARTIAL | 1/4 | Auto-save, animations |
| tree/tree_test | BROKEN | 0/7 | Hierarchy browsers | | tree/tree_test | WORKS | 7/7 | Hierarchy browsers |
--- ---
@ -192,17 +192,17 @@ Organized in `wasm-app/standalone/` folders:
8. Drawing/painting (wxDC, mouse events) 8. Drawing/painting (wxDC, mouse events)
9. **wxMessageBox/wxDialog** - Modal dialogs with Asyncify 9. **wxMessageBox/wxDialog** - Modal dialogs with Asyncify
10. **wxGrid** - Property grids with cells, labels, and events 10. **wxGrid** - Property grids with cells, labels, and events
11. **wxTreeCtrl** - Hierarchy browsers with expand/collapse, selection, add/delete
### Needs Work for KiCad ### Needs Work for KiCad
1. **wxClipboard** - Copy/paste (browser limitations) 1. **wxClipboard** - Copy/paste (browser limitations)
### Untested for KiCad ### Untested for KiCad
1. wxTreeCtrl (hierarchy browser) 1. wxDataViewCtrl (advanced lists)
2. wxDataViewCtrl (advanced lists) 2. wxRichTextCtrl (formatted text)
3. wxRichTextCtrl (formatted text) 3. wxStyledTextCtrl (code editor)
4. wxStyledTextCtrl (code editor) 4. Printing support
5. Printing support 5. Drag and drop
6. Drag and drop
--- ---

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Before After
Before After

View file

@ -55,8 +55,8 @@ test.describe('wxTreeCtrl Tests', () => {
const canvas = page.locator('canvas'); const canvas = page.locator('canvas');
// Click Expand All button // Click Expand All button (buttons are centered, at approximately y=90)
await canvas.click({ position: { x: 80, y: 95 } }); await canvas.click({ position: { x: 455, y: 90 } });
await page.waitForTimeout(500); await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/tree-04-expanded.png' }); await page.screenshot({ path: 'test-results/tree-04-expanded.png' });
@ -72,8 +72,8 @@ test.describe('wxTreeCtrl Tests', () => {
const canvas = page.locator('canvas'); const canvas = page.locator('canvas');
// Click Collapse All button // Click Collapse All button (buttons are centered, at approximately y=90)
await canvas.click({ position: { x: 200, y: 95 } }); await canvas.click({ position: { x: 545, y: 90 } });
await page.waitForTimeout(500); await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/tree-05-collapsed.png' }); await page.screenshot({ path: 'test-results/tree-05-collapsed.png' });
@ -89,12 +89,12 @@ test.describe('wxTreeCtrl Tests', () => {
const canvas = page.locator('canvas'); const canvas = page.locator('canvas');
// First select an item // First select an item (tree starts around y=120)
await canvas.click({ position: { x: 100, y: 160 } }); await canvas.click({ position: { x: 100, y: 140 } });
await page.waitForTimeout(300); await page.waitForTimeout(300);
// Click Add Item button // Click Add Item button (buttons are centered, at approximately y=90)
await canvas.click({ position: { x: 310, y: 95 } }); await canvas.click({ position: { x: 680, y: 90 } });
await page.waitForTimeout(500); await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/tree-06-added.png' }); await page.screenshot({ path: 'test-results/tree-06-added.png' });
@ -110,12 +110,12 @@ test.describe('wxTreeCtrl Tests', () => {
const canvas = page.locator('canvas'); const canvas = page.locator('canvas');
// First select an item (not root) // First select an item (not root) - select "Schematic" which is around y=145
await canvas.click({ position: { x: 150, y: 200 } }); await canvas.click({ position: { x: 80, y: 145 } });
await page.waitForTimeout(300); await page.waitForTimeout(300);
// Click Delete Selected button // Click Delete Selected button (buttons are centered, at approximately y=90)
await canvas.click({ position: { x: 440, y: 95 } }); await canvas.click({ position: { x: 780, y: 90 } });
await page.waitForTimeout(500); await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/tree-07-deleted.png' }); await page.screenshot({ path: 'test-results/tree-07-deleted.png' });

View file

@ -170,6 +170,9 @@ void TreeTestFrame::PopulateTree()
void TreeTestFrame::LogEvent(const wxString& msg) void TreeTestFrame::LogEvent(const wxString& msg)
{ {
// Guard against events firing before m_log is initialized
if (!m_log)
return;
m_log->AppendText(msg + "\n"); m_log->AppendText(msg + "\n");
SetStatusText(msg); SetStatusText(msg);