Extend element registry and migrate all tests to semantic selectors

Phase 2 of element registry migration - eliminate hardcoded coordinates:

Element tracker additions:
- wxTreeCtrl items (clickTreeItem, findTreeItem)
- wxDataViewCtrl items and column headers
- wxPropertyGrid rows
- wxListBox items
- wxSpinButton arrows
- wxSlider thumb/track
- wxTextCtrl area
- wxSearchCtrl field
- wxAuiManager pane content areas
- wxCalendarCtrl dates

Test migrations:
- 24 test files updated to use element registry helpers
- Replaced coordinate-based clicks with semantic selectors
- Added find-hardcoded-coords.sh script for auditing

Remaining coordinates are legitimate (scroll positioning, drawing, test.fail blocks).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Viktor Vaczi 2025-12-30 14:17:51 +01:00
commit 64142aa8de
27 changed files with 1710 additions and 839 deletions

View file

@ -96,6 +96,11 @@ LDFLAGS_PTHREAD = $(DEBUG_LDFLAGS) $(BASE_LDFLAGS) -pthread \
JS = $(TOOLS_ROOT)/wx.js
HTML = $(TOOLS_ROOT)/template.html
# wxWidgets library directory - used as dependency to rebuild when libs change
WX_LIB_DIR = ../../build-wasm/wxwidgets-universal/lib
# Key library that changes when wxWidgets is rebuilt
WX_CORE_LIB = $(WX_LIB_DIR)/libwx_wasmunivu_core-3.2-emscripten.a
# Standalone directories
S = standalone
@ -147,301 +152,301 @@ all: minimal_test.html \
minimal_test.o: minimal_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
minimal_test.html: minimal_test.o
minimal_test.html: minimal_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_GL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Menu test (no GL)
$(S)/menu/menu_test.o: $(S)/menu/menu_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/menu/menu_test.html: $(S)/menu/menu_test.o
$(S)/menu/menu_test.html: $(S)/menu/menu_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Clipboard test (no GL)
$(S)/clipboard/clipboard_test.o: $(S)/clipboard/clipboard_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/clipboard/clipboard_test.html: $(S)/clipboard/clipboard_test.o
$(S)/clipboard/clipboard_test.html: $(S)/clipboard/clipboard_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# FileDialog test (no GL)
$(S)/filedialog/filedialog_test.o: $(S)/filedialog/filedialog_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/filedialog/filedialog_test.html: $(S)/filedialog/filedialog_test.o
$(S)/filedialog/filedialog_test.html: $(S)/filedialog/filedialog_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Layout test (no GL)
$(S)/layout/layout_test.o: $(S)/layout/layout_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/layout/layout_test.html: $(S)/layout/layout_test.o
$(S)/layout/layout_test.html: $(S)/layout/layout_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# AUI test (no GL)
$(S)/aui/aui_test.o: $(S)/aui/aui_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/aui/aui_test.html: $(S)/aui/aui_test.o
$(S)/aui/aui_test.html: $(S)/aui/aui_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Toolbar test (no GL)
$(S)/toolbar/toolbar_test.o: $(S)/toolbar/toolbar_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/toolbar/toolbar_test.html: $(S)/toolbar/toolbar_test.o
$(S)/toolbar/toolbar_test.html: $(S)/toolbar/toolbar_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Grid test (no GL)
$(S)/grid/grid_test.o: $(S)/grid/grid_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/grid/grid_test.html: $(S)/grid/grid_test.o
$(S)/grid/grid_test.html: $(S)/grid/grid_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Dialog test (no GL)
$(S)/dialog/dialog_test.o: $(S)/dialog/dialog_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/dialog/dialog_test.html: $(S)/dialog/dialog_test.o
$(S)/dialog/dialog_test.html: $(S)/dialog/dialog_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Timer test (no GL)
$(S)/timer/timer_test.o: $(S)/timer/timer_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/timer/timer_test.html: $(S)/timer/timer_test.o
$(S)/timer/timer_test.html: $(S)/timer/timer_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Tree test (no GL)
$(S)/tree/tree_test.o: $(S)/tree/tree_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/tree/tree_test.html: $(S)/tree/tree_test.o
$(S)/tree/tree_test.html: $(S)/tree/tree_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# DataView test (no GL)
$(S)/dataview/dataview_test.o: $(S)/dataview/dataview_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/dataview/dataview_test.html: $(S)/dataview/dataview_test.o
$(S)/dataview/dataview_test.html: $(S)/dataview/dataview_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# HtmlWindow test (needs HTML library)
$(S)/htmlwin/htmlwin_test.o: $(S)/htmlwin/htmlwin_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/htmlwin/htmlwin_test.html: $(S)/htmlwin/htmlwin_test.o
$(S)/htmlwin/htmlwin_test.html: $(S)/htmlwin/htmlwin_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_HTML) --pre-js $(JS) --shell-file $(HTML) -o $@
# StyledTextCtrl test (needs STC library)
$(S)/stc/stc_test.o: $(S)/stc/stc_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/stc/stc_test.html: $(S)/stc/stc_test.o
$(S)/stc/stc_test.html: $(S)/stc/stc_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_STC) --pre-js $(JS) --shell-file $(HTML) -o $@
# Print test (no GL)
$(S)/print/print_test.o: $(S)/print/print_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/print/print_test.html: $(S)/print/print_test.o
$(S)/print/print_test.html: $(S)/print/print_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# DragDrop test (no GL)
$(S)/dnd/dnd_test.o: $(S)/dnd/dnd_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/dnd/dnd_test.html: $(S)/dnd/dnd_test.o
$(S)/dnd/dnd_test.html: $(S)/dnd/dnd_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# PropertyGrid test (needs propgrid library)
$(S)/propgrid/propgrid_test.o: $(S)/propgrid/propgrid_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/propgrid/propgrid_test.html: $(S)/propgrid/propgrid_test.o
$(S)/propgrid/propgrid_test.html: $(S)/propgrid/propgrid_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_PROPGRID) --pre-js $(JS) --shell-file $(HTML) -o $@
# Pickers test (colour/font pickers, no GL)
$(S)/pickers/pickers_test.o: $(S)/pickers/pickers_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/pickers/pickers_test.html: $(S)/pickers/pickers_test.o
$(S)/pickers/pickers_test.html: $(S)/pickers/pickers_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Collapsible pane test (no GL)
$(S)/collapsible/collapsible_test.o: $(S)/collapsible/collapsible_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/collapsible/collapsible_test.html: $(S)/collapsible/collapsible_test.o
$(S)/collapsible/collapsible_test.html: $(S)/collapsible/collapsible_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# ListCtrl virtual mode test (no GL)
$(S)/listctrl/listctrl_test.o: $(S)/listctrl/listctrl_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/listctrl/listctrl_test.html: $(S)/listctrl/listctrl_test.o
$(S)/listctrl/listctrl_test.html: $(S)/listctrl/listctrl_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# InfoBar test (no GL)
$(S)/infobar/infobar_test.o: $(S)/infobar/infobar_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/infobar/infobar_test.html: $(S)/infobar/infobar_test.o
$(S)/infobar/infobar_test.html: $(S)/infobar/infobar_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# DataViewCtrl Virtual Mode test (no GL, uses base dataview)
$(S)/dataviewvirtual/dataviewvirtual_test.o: $(S)/dataviewvirtual/dataviewvirtual_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/dataviewvirtual/dataviewvirtual_test.html: $(S)/dataviewvirtual/dataviewvirtual_test.o
$(S)/dataviewvirtual/dataviewvirtual_test.html: $(S)/dataviewvirtual/dataviewvirtual_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# AuiNotebook test (needs aui)
$(S)/auinotebook/auinotebook_test.o: $(S)/auinotebook/auinotebook_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/auinotebook/auinotebook_test.html: $(S)/auinotebook/auinotebook_test.o
$(S)/auinotebook/auinotebook_test.html: $(S)/auinotebook/auinotebook_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_AUI) --pre-js $(JS) --shell-file $(HTML) -o $@
# Wizard test (needs adv)
$(S)/wizard/wizard_test.o: $(S)/wizard/wizard_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/wizard/wizard_test.html: $(S)/wizard/wizard_test.o
$(S)/wizard/wizard_test.html: $(S)/wizard/wizard_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_ADV) --pre-js $(JS) --shell-file $(HTML) -o $@
# Grid Edit test (cell editing, no GL)
$(S)/gridedit/gridedit_test.o: $(S)/gridedit/gridedit_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/gridedit/gridedit_test.html: $(S)/gridedit/gridedit_test.o
$(S)/gridedit/gridedit_test.html: $(S)/gridedit/gridedit_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Calendar test (needs adv)
$(S)/calendar/calendar_test.o: $(S)/calendar/calendar_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/calendar/calendar_test.html: $(S)/calendar/calendar_test.o
$(S)/calendar/calendar_test.html: $(S)/calendar/calendar_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_ADV) --pre-js $(JS) --shell-file $(HTML) -o $@
# Grid Renderers test (no GL)
$(S)/gridrenderers/gridrenderers_test.o: $(S)/gridrenderers/gridrenderers_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/gridrenderers/gridrenderers_test.html: $(S)/gridrenderers/gridrenderers_test.o
$(S)/gridrenderers/gridrenderers_test.html: $(S)/gridrenderers/gridrenderers_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Print Preview test (no GL)
$(S)/printpreview/printpreview_test.o: $(S)/printpreview/printpreview_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/printpreview/printpreview_test.html: $(S)/printpreview/printpreview_test.o
$(S)/printpreview/printpreview_test.html: $(S)/printpreview/printpreview_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Bitmap Buttons test (no GL)
$(S)/bitmapbuttons/bitmapbuttons_test.o: $(S)/bitmapbuttons/bitmapbuttons_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/bitmapbuttons/bitmapbuttons_test.html: $(S)/bitmapbuttons/bitmapbuttons_test.o
$(S)/bitmapbuttons/bitmapbuttons_test.html: $(S)/bitmapbuttons/bitmapbuttons_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Specialized Controls test (needs adv for treebook)
$(S)/specialized/specialized_test.o: $(S)/specialized/specialized_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/specialized/specialized_test.html: $(S)/specialized/specialized_test.o
$(S)/specialized/specialized_test.html: $(S)/specialized/specialized_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_ADV) --pre-js $(JS) --shell-file $(HTML) -o $@
# Validators test (no GL)
$(S)/validators/validators_test.o: $(S)/validators/validators_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/validators/validators_test.html: $(S)/validators/validators_test.o
$(S)/validators/validators_test.html: $(S)/validators/validators_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Owner-drawn ComboBox test (no GL)
$(S)/ownerdrawn/ownerdrawn_test.o: $(S)/ownerdrawn/ownerdrawn_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/ownerdrawn/ownerdrawn_test.html: $(S)/ownerdrawn/ownerdrawn_test.o
$(S)/ownerdrawn/ownerdrawn_test.html: $(S)/ownerdrawn/ownerdrawn_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Popup Window test (no GL)
$(S)/popup/popup_test.o: $(S)/popup/popup_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/popup/popup_test.html: $(S)/popup/popup_test.o
$(S)/popup/popup_test.html: $(S)/popup/popup_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# XML Document test (needs xml library)
$(S)/xml/xml_test.o: $(S)/xml/xml_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/xml/xml_test.html: $(S)/xml/xml_test.o
$(S)/xml/xml_test.html: $(S)/xml/xml_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_XML) --pre-js $(JS) --shell-file $(HTML) -o $@
# WASM Edge Cases test (no GL)
$(S)/wasmedge/wasmedge_test.o: $(S)/wasmedge/wasmedge_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/wasmedge/wasmedge_test.html: $(S)/wasmedge/wasmedge_test.o
$(S)/wasmedge/wasmedge_test.html: $(S)/wasmedge/wasmedge_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Font Enumeration test (no GL)
$(S)/fontenum/fontenum_test.o: $(S)/fontenum/fontenum_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/fontenum/fontenum_test.html: $(S)/fontenum/fontenum_test.o
$(S)/fontenum/fontenum_test.html: $(S)/fontenum/fontenum_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Text Decorations test (no GL)
$(S)/textdecor/textdecor_test.o: $(S)/textdecor/textdecor_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/textdecor/textdecor_test.html: $(S)/textdecor/textdecor_test.o
$(S)/textdecor/textdecor_test.html: $(S)/textdecor/textdecor_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Bitmask test (no GL)
$(S)/bitmask/bitmask_test.o: $(S)/bitmask/bitmask_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/bitmask/bitmask_test.html: $(S)/bitmask/bitmask_test.o
$(S)/bitmask/bitmask_test.html: $(S)/bitmask/bitmask_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Regions test (no GL)
$(S)/regions/regions_test.o: $(S)/regions/regions_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/regions/regions_test.html: $(S)/regions/regions_test.o
$(S)/regions/regions_test.html: $(S)/regions/regions_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Maximize test (no GL) - reproduces KiCad startup maximize issue
$(S)/maximize/maximize_test.o: $(S)/maximize/maximize_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/maximize/maximize_test.html: $(S)/maximize/maximize_test.o
$(S)/maximize/maximize_test.html: $(S)/maximize/maximize_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Early size test (no GL) - tests GetClientSize() before Show()
$(S)/earlysize/earlysize_test.o: $(S)/earlysize/earlysize_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/earlysize/earlysize_test.html: $(S)/earlysize/earlysize_test.o
$(S)/earlysize/earlysize_test.html: $(S)/earlysize/earlysize_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Thread Pool test (pthread) - reproduces KiCad deadlock when hardware_concurrency() > PTHREAD_POOL_SIZE
$(S)/threadpool/threadpool_test.o: $(S)/threadpool/threadpool_test.cpp
$(CXX) -c $(CXXFLAGS) -pthread $< -o $@
$(S)/threadpool/threadpool_test.html: $(S)/threadpool/threadpool_test.o
$(S)/threadpool/threadpool_test.html: $(S)/threadpool/threadpool_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_PTHREAD) --pre-js $(JS) --shell-file $(HTML) -o $@
# Log Error test (no GL) - reproduces KiCad's kiface error dialog
$(S)/logerror/logerror_test.o: $(S)/logerror/logerror_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/logerror/logerror_test.html: $(S)/logerror/logerror_test.o
$(S)/logerror/logerror_test.html: $(S)/logerror/logerror_test.o $(WX_CORE_LIB)
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Convenience targets

View file

@ -1,6 +1,6 @@
// wxAuiManager Tests - AUI docking system KiCad uses extensively
import { test, expect, MAIN_CANVAS, tryLoadApp, getCanvasBox } from './utils/fixtures';
import { clickAuiButton, findRenderedByLabel, findRenderedByType } from './utils/element-tracker';
import { clickAuiButton, clickAuiPaneContent, findRenderedByLabel, findRenderedByType } from './utils/element-tracker';
test.describe('wxAuiManager Tests', () => {
@ -83,22 +83,24 @@ test.describe('wxAuiManager Tests', () => {
return;
}
const box = await getCanvasBox(page);
// Click in Properties panel
await page.mouse.click(box.x + 75, box.y + 200);
// Click in Properties panel using element tracking
const propsClicked = await clickAuiPaneContent(page, 'Properties');
expect(propsClicked, 'Should be able to click Properties pane').toBe(true);
await page.waitForTimeout(200);
// Click in Layers panel (right side)
await page.mouse.click(box.x + 720, box.y + 200);
// Click in Layers panel using element tracking
const layersClicked = await clickAuiPaneContent(page, 'Layers');
expect(layersClicked, 'Should be able to click Layers pane').toBe(true);
await page.waitForTimeout(200);
// Click in Messages panel (bottom)
await page.mouse.click(box.x + 400, box.y + 550);
// Click in Messages panel using element tracking
const messagesClicked = await clickAuiPaneContent(page, 'Messages');
expect(messagesClicked, 'Should be able to click Messages pane').toBe(true);
await page.waitForTimeout(200);
// Click in center (Event Log)
await page.mouse.click(box.x + 400, box.y + 300);
// Click in Event Log panel using element tracking
const eventLogClicked = await clickAuiPaneContent(page, 'Event Log');
expect(eventLogClicked, 'Should be able to click Event Log pane').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/aui-05-multi-panel.png', fullPage: true });

View file

@ -1,5 +1,6 @@
// wxAuiNotebook Tests - Tab panels for KiCad editors
import { test, expect, tryLoadApp } from './utils/fixtures';
import { clickByLabel, clickTab } from './utils/element-tracker';
test.describe('wxAuiNotebook Tests', () => {
@ -23,13 +24,10 @@ test.describe('wxAuiNotebook Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click on PCB tab
await page.mouse.click(box.x + 200, box.y + 95);
await page.waitForTimeout(200);
}
// Click on PCB tab using element registry
const clicked = await clickTab(page, 'PCB');
expect(clicked, 'PCB tab should be found and clicked').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/auinotebook-02-tab-switch.png', fullPage: true });
});
@ -44,13 +42,10 @@ test.describe('wxAuiNotebook Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click Add Tab button
await page.mouse.click(box.x + 60, box.y + 60);
await page.waitForTimeout(200);
}
// Click Add Tab button using element registry
const clicked = await clickByLabel(page, 'Add Tab');
expect(clicked, 'Add Tab button should be found and clicked').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/auinotebook-03-add-tab.png', fullPage: true });
});
@ -65,13 +60,10 @@ test.describe('wxAuiNotebook Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click Remove Tab button
await page.mouse.click(box.x + 160, box.y + 60);
await page.waitForTimeout(200);
}
// Click Remove Tab button using element registry
const clicked = await clickByLabel(page, 'Remove Tab');
expect(clicked, 'Remove Tab button should be found and clicked').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/auinotebook-04-remove-tab.png', fullPage: true });
});
@ -86,13 +78,10 @@ test.describe('wxAuiNotebook Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click Bottom button
await page.mouse.click(box.x + 470, box.y + 60);
await page.waitForTimeout(200);
}
// Click Bottom button using element registry
const clicked = await clickByLabel(page, 'Bottom');
expect(clicked, 'Bottom button should be found and clicked').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/auinotebook-05-tab-style.png', fullPage: true });
});

View file

@ -1,5 +1,6 @@
// wxBitmapButton Tests - Bitmap buttons, toggle buttons, disabled states
import { test, expect, tryLoadApp } from './utils/fixtures';
import { clickByLabel } from './utils/element-tracker';
test.describe('wxBitmapButton Tests', () => {
@ -23,16 +24,12 @@ test.describe('wxBitmapButton Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click Select tool button
await page.mouse.click(box.x + 50, box.y + 100);
await page.waitForTimeout(100);
// Click Line tool button
await page.mouse.click(box.x + 90, box.y + 100);
await page.waitForTimeout(100);
}
// Click Select tool button using element registry
await clickByLabel(page, 'Select Tool');
await page.waitForTimeout(100);
// Click Line tool button
await clickByLabel(page, 'Line Tool');
await page.waitForTimeout(100);
await page.screenshot({ path: 'test-results/bitmapbuttons-02-toolbar-click.png', fullPage: true });
});
@ -47,13 +44,9 @@ test.describe('wxBitmapButton Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click F.Cu toggle button to turn it off
await page.mouse.click(box.x + 50, box.y + 170);
await page.waitForTimeout(200);
}
// Click F.Cu checkbox to toggle it using element registry
await clickByLabel(page, 'F.Cu');
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/bitmapbuttons-03-toggle.png', fullPage: true });
});
@ -68,17 +61,11 @@ test.describe('wxBitmapButton Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Toggle multiple layer buttons
await page.mouse.click(box.x + 50, box.y + 170);
await page.waitForTimeout(100);
await page.mouse.click(box.x + 120, box.y + 170);
await page.waitForTimeout(100);
await page.mouse.click(box.x + 190, box.y + 170);
await page.waitForTimeout(200);
}
// Toggle multiple layer checkboxes using element registry
await clickByLabel(page, 'F.Cu');
await page.waitForTimeout(100);
await clickByLabel(page, 'B.Cu');
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/bitmapbuttons-04-multi-toggle.png', fullPage: true });
});
@ -93,13 +80,9 @@ test.describe('wxBitmapButton Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click Toggle Enable State button
await page.mouse.click(box.x + 400, box.y + 240);
await page.waitForTimeout(200);
}
// Click Toggle Enable State button using element registry
await clickByLabel(page, 'Toggle Enable State');
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/bitmapbuttons-05-enable-toggle.png', fullPage: true });
});
@ -114,17 +97,13 @@ test.describe('wxBitmapButton Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click different shape buttons
await page.mouse.click(box.x + 50, box.y + 310);
await page.waitForTimeout(100);
await page.mouse.click(box.x + 100, box.y + 310);
await page.waitForTimeout(100);
await page.mouse.click(box.x + 150, box.y + 310);
await page.waitForTimeout(200);
}
// Click different shape buttons using element registry (by tooltip)
await clickByLabel(page, 'Rectangle');
await page.waitForTimeout(100);
await clickByLabel(page, 'Circle');
await page.waitForTimeout(100);
await clickByLabel(page, 'Triangle');
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/bitmapbuttons-06-shapes.png', fullPage: true });
});
@ -139,15 +118,11 @@ test.describe('wxBitmapButton Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click New, Open, Save buttons
await page.mouse.click(box.x + 50, box.y + 380);
await page.waitForTimeout(100);
await page.mouse.click(box.x + 90, box.y + 380);
await page.waitForTimeout(200);
}
// Click New, Open buttons using element registry (by tooltip)
await clickByLabel(page, 'New');
await page.waitForTimeout(100);
await clickByLabel(page, 'Open');
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/bitmapbuttons-07-artprovider.png', fullPage: true });
});

View file

@ -1,5 +1,6 @@
// wxCalendarCtrl Tests - Date selection
import { test, expect, tryLoadApp } from './utils/fixtures';
import { clickByLabel, clickCalendarDate } from './utils/element-tracker';
test.describe('wxCalendarCtrl Tests', () => {
@ -23,13 +24,10 @@ test.describe('wxCalendarCtrl Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click on a day in the calendar
await page.mouse.click(box.x + 150, box.y + 200);
await page.waitForTimeout(200);
}
// Click on day 15 in the calendar using element registry
const clicked = await clickCalendarDate(page, 15);
expect(clicked, 'Calendar date 15 should be found and clicked').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/calendar-02-select-date.png', fullPage: true });
});
@ -44,13 +42,10 @@ test.describe('wxCalendarCtrl Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click Next Month button
await page.mouse.click(box.x + 480, box.y + 170);
await page.waitForTimeout(200);
}
// Click Next Month button using element registry
const clicked = await clickByLabel(page, 'Next Month');
expect(clicked, 'Next Month button should be found').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/calendar-03-next-month.png', fullPage: true });
});
@ -65,13 +60,10 @@ test.describe('wxCalendarCtrl Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click Previous Month button
await page.mouse.click(box.x + 480, box.y + 200);
await page.waitForTimeout(200);
}
// Click Previous Month button using element registry
const clicked = await clickByLabel(page, 'Previous Month');
expect(clicked, 'Previous Month button should be found').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/calendar-04-prev-month.png', fullPage: true });
});
@ -86,16 +78,15 @@ test.describe('wxCalendarCtrl Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// First go to next month
await page.mouse.click(box.x + 480, box.y + 170);
await page.waitForTimeout(100);
// Click Today button
await page.mouse.click(box.x + 480, box.y + 140);
await page.waitForTimeout(200);
}
// First go to next month
const nextClicked = await clickByLabel(page, 'Next Month');
expect(nextClicked, 'Next Month button should be found').toBe(true);
await page.waitForTimeout(100);
// Click Today button using element registry
const todayClicked = await clickByLabel(page, 'Today');
expect(todayClicked, 'Today button should be found').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/calendar-05-today.png', fullPage: true });
});

View file

@ -1,5 +1,6 @@
// wxCollapsiblePane Tests - Collapsible sections for property panels
import { test, expect, tryLoadApp } from './utils/fixtures';
import { clickByLabel } from './utils/element-tracker';
test.describe('wxCollapsiblePane Tests', () => {
@ -55,15 +56,9 @@ test.describe('wxCollapsiblePane Tests', () => {
return;
}
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (!box) {
test.skip();
return;
}
// Click Expand All button (approximate position)
await page.mouse.click(box.x + 150, box.y + 100);
// Click Expand All button using element registry
const clicked = await clickByLabel(page, 'Expand All');
expect(clicked, 'Expand All button should be found and clicked').toBe(true);
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/collapsible-04-expand-all.png', fullPage: true });
@ -82,15 +77,9 @@ test.describe('wxCollapsiblePane Tests', () => {
return;
}
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (!box) {
test.skip();
return;
}
// Click Collapse All button (approximate position, second button)
await page.mouse.click(box.x + 300, box.y + 100);
// Click Collapse All button using element registry
const clicked = await clickByLabel(page, 'Collapse All');
expect(clicked, 'Collapse All button should be found and clicked').toBe(true);
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/collapsible-05-collapse-all.png', fullPage: true });

View file

@ -1,4 +1,5 @@
import { test, expect } from './utils/fixtures';
import { clickTab, clickByLabel, clickDataViewItem, clickDataViewItemByIndex, clickColumnHeader, clickColumnHeaderByIndex } from './utils/element-tracker';
/**
* wxDataViewCtrl Tests
@ -48,10 +49,9 @@ test.describe('wxDataViewCtrl Tests', () => {
test('List item can be selected', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click on first list item (data rows start at y≈210)
await canvas.click({ position: { x: 200, y: 215 } });
// Click on first list item using element registry
const clicked = await clickDataViewItem(page, 'Zone_GND_Top');
expect(clicked).toBe(true);
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/dataview-03-list-selected.png' });
@ -65,10 +65,8 @@ test.describe('wxDataViewCtrl Tests', () => {
test('Add Item button works for list', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click Add Item button (x≈502, y≈135)
await canvas.click({ position: { x: 502, y: 135 } });
// Click Add Item button using element registry
await clickByLabel(page, 'Add Item');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/dataview-04-list-add.png' });
@ -82,10 +80,8 @@ test.describe('wxDataViewCtrl Tests', () => {
test('Switch to Tree View tab', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click on Tree View tab (x≈105, y≈105)
await canvas.click({ position: { x: 105, y: 105 } });
// Click on Tree View tab using element registry
await clickTab(page, 'Tree View');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/dataview-05-tree-tab.png' });
@ -99,14 +95,13 @@ test.describe('wxDataViewCtrl Tests', () => {
test('Tree item can be selected', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Switch to tree tab first (x≈105, y≈105)
await canvas.click({ position: { x: 105, y: 105 } });
// Switch to tree tab first using element registry
await clickTab(page, 'Tree View');
await page.waitForTimeout(500);
// Click on a tree item (tree content area starts around y≈200)
await canvas.click({ position: { x: 150, y: 220 } });
// Click on a tree item using element registry
const clicked = await clickDataViewItem(page, 'Libraries');
expect(clicked, 'Should be able to click Libraries tree item').toBe(true);
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/dataview-06-tree-selected.png' });
@ -119,14 +114,12 @@ test.describe('wxDataViewCtrl Tests', () => {
test('Expand All button works for tree', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Switch to tree tab (x≈105, y≈105)
await canvas.click({ position: { x: 105, y: 105 } });
// Switch to tree tab using element registry
await clickTab(page, 'Tree View');
await page.waitForTimeout(500);
// Click Expand All button (x≈488, y≈136 from button-finder)
await canvas.click({ position: { x: 488, y: 136 } });
// Click Expand All button using element registry
await clickByLabel(page, 'Expand All');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/dataview-07-tree-expanded.png' });
@ -140,14 +133,12 @@ test.describe('wxDataViewCtrl Tests', () => {
test('Collapse All button works for tree', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Switch to tree tab (x≈105, y≈105)
await canvas.click({ position: { x: 105, y: 105 } });
// Switch to tree tab using element registry
await clickTab(page, 'Tree View');
await page.waitForTimeout(500);
// Click Collapse All button (x≈600, y≈136 from button-finder)
await canvas.click({ position: { x: 600, y: 136 } });
// Click Collapse All button using element registry
await clickByLabel(page, 'Collapse All');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/dataview-08-tree-collapsed.png' });
@ -161,10 +152,9 @@ test.describe('wxDataViewCtrl Tests', () => {
test('Column header click works for list', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click on Zone Name column header (y≈178)
await canvas.click({ position: { x: 80, y: 178 } });
// Click on Zone Name column header using element registry
const clicked = await clickColumnHeader(page, 'Zone Name');
expect(clicked, 'Should be able to click Zone Name column header').toBe(true);
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/dataview-09-column-click.png' });

View file

@ -1,5 +1,6 @@
// wxDataViewCtrl Virtual Mode Tests - Zone Manager/Net Inspector simulation
import { test, expect, tryLoadApp } from './utils/fixtures';
import { clickByLabel, findAllRenderedByLabel, clickDataViewItemByIndex, clickDataViewItem } from './utils/element-tracker';
test.describe('wxDataViewCtrl Virtual Mode Tests', () => {
@ -23,14 +24,10 @@ test.describe('wxDataViewCtrl Virtual Mode Tests', () => {
await page.waitForTimeout(500);
// Click 10,000 button to test large dataset
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click where the 10,000 button should be
await page.mouse.click(box.x + 200, box.y + 60);
await page.waitForTimeout(200);
}
// Click 10,000 button to test large dataset using element registry
const clicked = await clickByLabel(page, '10,000');
expect(clicked, '10,000 button should be found').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/dataviewvirtual-02-large-dataset.png', fullPage: true });
@ -50,13 +47,10 @@ test.describe('wxDataViewCtrl Virtual Mode Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click Middle button
await page.mouse.click(box.x + 340, box.y + 60);
await page.waitForTimeout(200);
}
// Click Middle button using element registry
const clicked = await clickByLabel(page, 'Middle');
expect(clicked, 'Middle button should be found').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/dataviewvirtual-03-scroll.png', fullPage: true });
});
@ -71,13 +65,11 @@ test.describe('wxDataViewCtrl Virtual Mode Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click on an item in the list
await page.mouse.click(box.x + 200, box.y + 200);
await page.waitForTimeout(200);
}
// Click on an item in the list using element registry
// Virtual list items have labels like "NET_00000", "NET_00001", etc.
const clicked = await clickDataViewItemByIndex(page, 0);
expect(clicked).toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/dataviewvirtual-04-selection.png', fullPage: true });
});
@ -92,13 +84,11 @@ test.describe('wxDataViewCtrl Virtual Mode Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click in zone manager panel (right side)
await page.mouse.click(box.x + 700, box.y + 200);
await page.waitForTimeout(200);
}
// Click in zone manager panel using element registry
// Zone items have labels like "Zone_000", "Zone_001", etc.
const clicked = await clickDataViewItem(page, 'Zone_000');
expect(clicked).toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/dataviewvirtual-05-zone-manager.png', fullPage: true });
});

View file

@ -1,8 +1,12 @@
import { test, expect, MAIN_CANVAS, waitForApp, getCanvasBox } from './utils/fixtures';
import { test, expect, waitForApp } from './utils/fixtures';
import { clickTab, clickByLabel } from './utils/element-tracker';
async function switchToDialogsTab(page: any, box: { x: number; y: number }) {
// Dialogs tab is the 7th tab (after Grid)
await page.mouse.click(box.x + 370, box.y + 35);
async function switchToDialogsTab(page: any) {
// Click Dialogs tab using element registry
const clicked = await clickTab(page, 'Dialogs');
if (!clicked) {
await clickByLabel(page, 'Dialogs');
}
await page.waitForTimeout(1000);
}
@ -12,13 +16,11 @@ test.describe('Dialogs Tab Tests', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const box = await getCanvasBox(page);
// Screenshot before switching to Dialogs tab
await page.screenshot({ path: 'test-results/dialogs-00-initial.png', fullPage: true });
// Switch to Dialogs tab
await switchToDialogsTab(page, box);
await switchToDialogsTab(page);
await page.screenshot({ path: 'test-results/dialogs-01-tab-selected.png', fullPage: true });
// Verify app is still responsive
@ -37,18 +39,16 @@ test.describe('Dialogs Tab Tests', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const box = await getCanvasBox(page);
await switchToDialogsTab(page);
await switchToDialogsTab(page, box);
// Click "Info Dialog" button (first button in wxMessageBox section)
await page.mouse.click(box.x + 80, box.y + 110);
// Click "Info" button using element registry
await clickByLabel(page, 'Info');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/dialogs-msgbox-info-open.png', fullPage: true });
// Click OK to close
await page.mouse.click(box.x + 350, box.y + 250);
await clickByLabel(page, 'OK');
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/dialogs-msgbox-info-closed.png', fullPage: true });
@ -60,18 +60,16 @@ test.describe('Dialogs Tab Tests', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const box = await getCanvasBox(page);
await switchToDialogsTab(page);
await switchToDialogsTab(page, box);
// Click "Yes/No Dialog" button (second button)
await page.mouse.click(box.x + 180, box.y + 110);
// Click "Yes/No" button using element registry
await clickByLabel(page, 'Yes/No');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/dialogs-msgbox-yesno-open.png', fullPage: true });
// Click somewhere to close (Yes or No)
await page.mouse.click(box.x + 300, box.y + 250);
// Click Yes to close
await clickByLabel(page, 'Yes');
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/dialogs-msgbox-yesno-closed.png', fullPage: true });
@ -81,18 +79,16 @@ test.describe('Dialogs Tab Tests', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const box = await getCanvasBox(page);
await switchToDialogsTab(page);
await switchToDialogsTab(page, box);
// Click "Error Dialog" button (third button)
await page.mouse.click(box.x + 280, box.y + 110);
// Click "Error" button using element registry
await clickByLabel(page, 'Error');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/dialogs-msgbox-error-open.png', fullPage: true });
// Close the dialog
await page.mouse.click(box.x + 350, box.y + 250);
// Close the dialog with OK
await clickByLabel(page, 'OK');
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/dialogs-msgbox-error-closed.png', fullPage: true });
@ -105,18 +101,16 @@ test.describe('Dialogs Tab Tests', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const box = await getCanvasBox(page);
await switchToDialogsTab(page);
await switchToDialogsTab(page, box);
// Click "Open Custom Dialog" button (in wxDialog section, around y=160)
await page.mouse.click(box.x + 100, box.y + 160);
// Click "Open Custom Dialog" button using element registry
await clickByLabel(page, 'Open Custom Dialog');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/dialogs-custom-open.png', fullPage: true });
// Click OK to close
await page.mouse.click(box.x + 300, box.y + 300);
await clickByLabel(page, 'OK');
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/dialogs-custom-closed.png', fullPage: true });
@ -129,14 +123,12 @@ test.describe('Dialogs Tab Tests', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const box = await getCanvasBox(page);
await switchToDialogsTab(page, box);
await switchToDialogsTab(page);
await page.screenshot({ path: 'test-results/dialogs-timer-initial.png', fullPage: true });
// Click "Start Timer" button (centered buttons)
await page.mouse.click(box.x + 500, box.y + 230);
// Click "Start Timer" button using element registry
await clickByLabel(page, 'Start Timer');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/dialogs-timer-started.png', fullPage: true });
@ -147,7 +139,7 @@ test.describe('Dialogs Tab Tests', () => {
await page.screenshot({ path: 'test-results/dialogs-timer-running.png', fullPage: true });
// Click "Stop Timer"
await page.mouse.click(box.x + 600, box.y + 230);
await clickByLabel(page, 'Stop Timer');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/dialogs-timer-stopped.png', fullPage: true });
@ -160,24 +152,22 @@ test.describe('Dialogs Tab Tests', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const box = await getCanvasBox(page);
await switchToDialogsTab(page);
await switchToDialogsTab(page, box);
// Start timer (centered buttons)
await page.mouse.click(box.x + 500, box.y + 230);
// Start timer using element registry
await clickByLabel(page, 'Start Timer');
await page.waitForTimeout(1500);
// Stop timer
await page.mouse.click(box.x + 600, box.y + 230);
await clickByLabel(page, 'Stop Timer');
await page.waitForTimeout(500);
// Start again
await page.mouse.click(box.x + 500, box.y + 230);
await clickByLabel(page, 'Start Timer');
await page.waitForTimeout(1500);
// Stop again
await page.mouse.click(box.x + 600, box.y + 230);
await clickByLabel(page, 'Stop Timer');
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/dialogs-timer-multiple.png', fullPage: true });
@ -191,26 +181,24 @@ test.describe('Dialogs Tab Tests', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const box = await getCanvasBox(page);
await switchToDialogsTab(page);
await switchToDialogsTab(page, box);
// 1. Click Info button
await page.mouse.click(box.x + 80, box.y + 110);
// 1. Click Info button and close
await clickByLabel(page, 'Info');
await page.waitForTimeout(400);
await page.mouse.click(box.x + 350, box.y + 250); // Close
await clickByLabel(page, 'OK');
await page.waitForTimeout(200);
// 2. Click Custom Dialog button
await page.mouse.click(box.x + 100, box.y + 160);
// 2. Click Custom Dialog button and close
await clickByLabel(page, 'Open Custom Dialog');
await page.waitForTimeout(400);
await page.mouse.click(box.x + 300, box.y + 300); // Close
await clickByLabel(page, 'OK');
await page.waitForTimeout(200);
// 3. Start and stop timer (centered buttons)
await page.mouse.click(box.x + 500, box.y + 230); // Start
// 3. Start and stop timer
await clickByLabel(page, 'Start Timer');
await page.waitForTimeout(2000);
await page.mouse.click(box.x + 600, box.y + 230); // Stop
await clickByLabel(page, 'Stop Timer');
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/dialogs-full-flow.png', fullPage: true });

View file

@ -1,8 +1,12 @@
import { test, expect, MAIN_CANVAS, waitForApp, getCanvasBox } from './utils/fixtures';
import { clickTab, clickByLabel, clickSpinUp, clickSearchCtrl } from './utils/element-tracker';
async function switchToGridTab(page: any, box: { x: number; y: number }) {
// Click Grid tab (sixth tab, after OpenGL which is at x=280)
await page.mouse.click(box.x + 315, box.y + 35);
async function switchToGridTab(page: any) {
// Click Grid tab using element registry
const clicked = await clickTab(page, 'Grid');
if (!clicked) {
await clickByLabel(page, 'Grid');
}
await page.waitForTimeout(1000);
}
@ -95,10 +99,8 @@ test.describe('Grid Tab Tests', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const box = await getCanvasBox(page);
// Switch to Grid tab
await switchToGridTab(page, box);
// Switch to Grid tab using element registry
await switchToGridTab(page);
await page.screenshot({ path: 'test-results/wxgrid-01-tab.png', fullPage: true });
// Evaluate if grid-like content exists (row/column headers, cells)
@ -139,7 +141,7 @@ test.describe('Grid Tab Tests', () => {
const box = await getCanvasBox(page);
await switchToGridTab(page, box);
await switchToGridTab(page);
// Click on a cell (would be at ~y=175 if grid existed)
await page.mouse.click(box.x + 180, box.y + 175);
@ -158,7 +160,7 @@ test.describe('Grid Tab Tests', () => {
const box = await getCanvasBox(page);
await switchToGridTab(page, box);
await switchToGridTab(page);
// Double-click to edit a cell
await page.mouse.dblclick(box.x + 180, box.y + 195);
@ -188,7 +190,7 @@ test.describe('Grid Tab Tests', () => {
const box = await getCanvasBox(page);
await switchToGridTab(page, box);
await switchToGridTab(page);
await page.screenshot({ path: 'test-results/spinctrl-01-visible.png', fullPage: true });
// SpinCtrl should be visible - check for its box and arrows in the canvas
@ -225,10 +227,11 @@ test.describe('Grid Tab Tests', () => {
const box = await getCanvasBox(page);
await switchToGridTab(page, box);
await switchToGridTab(page);
// Click up arrow on SpinCtrl
await page.mouse.click(box.x + 220, box.y + 350);
// Click up arrow on SpinCtrl using element tracking
const spinClicked = await clickSpinUp(page);
expect(spinClicked, 'Should be able to click spin up button').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/spinctrl-02-after-click.png', fullPage: true });
@ -250,7 +253,7 @@ test.describe('Grid Tab Tests', () => {
const box = await getCanvasBox(page);
await switchToGridTab(page, box);
await switchToGridTab(page);
await page.screenshot({ path: 'test-results/searchctrl-01-visible.png', fullPage: true });
// SearchCtrl should be visible - check for its text field and buttons
@ -287,10 +290,11 @@ test.describe('Grid Tab Tests', () => {
const box = await getCanvasBox(page);
await switchToGridTab(page, box);
await switchToGridTab(page);
// Click on SearchCtrl text field (center of the control)
await page.mouse.click(box.x + 420, box.y + 350);
// Click on SearchCtrl text field using element tracking
const searchClicked = await clickSearchCtrl(page);
expect(searchClicked, 'Should be able to click SearchCtrl text field').toBe(true);
await page.waitForTimeout(200);
// Type search text
@ -320,7 +324,7 @@ test.describe('Grid Tab Tests', () => {
const box = await getCanvasBox(page);
await switchToGridTab(page, box);
await switchToGridTab(page);
await page.screenshot({ path: 'test-results/grid-tab-final.png', fullPage: true });
// Verify app is still responsive after switching to Grid tab

View file

@ -1,5 +1,6 @@
// wxGrid Cell Editing Tests - Property editing simulation
import { test, expect, tryLoadApp } from './utils/fixtures';
import { clickByLabel, clickGridCell, findGridCell } from './utils/element-tracker';
test.describe('wxGrid Cell Editing Tests', () => {
@ -23,13 +24,10 @@ test.describe('wxGrid Cell Editing Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click on a cell
await page.mouse.click(box.x + 150, box.y + 180);
await page.waitForTimeout(200);
}
// Click on a cell using element registry
const clicked = await clickGridCell(page, 1, 1);
expect(clicked, 'Grid cell should be found and clicked').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/gridedit-02-select-cell.png', fullPage: true });
});
@ -44,13 +42,13 @@ test.describe('wxGrid Cell Editing Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Double-click to enter edit mode
await page.mouse.dblclick(box.x + 150, box.y + 180);
await page.waitForTimeout(300);
// Double-click to enter edit mode using element registry
const cell = await findGridCell(page, 1, 1);
expect(cell, 'Grid cell should be found').not.toBeNull();
if (cell) {
await page.mouse.dblclick(cell.centerX, cell.centerY);
}
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/gridedit-03-edit-cell.png', fullPage: true });
});
@ -65,13 +63,10 @@ test.describe('wxGrid Cell Editing Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click Add Row button
await page.mouse.click(box.x + 60, box.y + 60);
await page.waitForTimeout(200);
}
// Click Add Row button using element registry
const clicked = await clickByLabel(page, 'Add Row');
expect(clicked, 'Add Row button should be found and clicked').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/gridedit-04-add-row.png', fullPage: true });
});
@ -86,16 +81,15 @@ test.describe('wxGrid Cell Editing Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Select a row first
await page.mouse.click(box.x + 150, box.y + 180);
await page.waitForTimeout(100);
// Click Delete Row button
await page.mouse.click(box.x + 150, box.y + 60);
await page.waitForTimeout(200);
}
// Select a row first using element registry
const cellClicked = await clickGridCell(page, 1, 1);
expect(cellClicked, 'Grid cell should be found and clicked').toBe(true);
await page.waitForTimeout(100);
// Click Delete Row button using element registry
const deleteClicked = await clickByLabel(page, 'Delete Row');
expect(deleteClicked, 'Delete Row button should be found and clicked').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/gridedit-05-delete-row.png', fullPage: true });
});

View file

@ -1,5 +1,6 @@
// wxGrid Custom Cell Renderers Tests - Color cells, icon+text, striped rows
import { test, expect, tryLoadApp } from './utils/fixtures';
import { clickTab, clickGridCell } from './utils/element-tracker';
test.describe('wxGrid Custom Cell Renderers Tests', () => {
@ -37,13 +38,10 @@ test.describe('wxGrid Custom Cell Renderers Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click Icon+Text tab (second tab in notebook)
await page.mouse.click(box.x + 150, box.y + 80);
await page.waitForTimeout(200);
}
// Click Icon+Text tab using element registry
const clicked = await clickTab(page, 'Icon+Text');
expect(clicked, 'Icon+Text tab should be found').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/gridrenderers-03-icon-text.png', fullPage: true });
});
@ -58,13 +56,10 @@ test.describe('wxGrid Custom Cell Renderers Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click Striped+Checkboxes tab (third tab)
await page.mouse.click(box.x + 280, box.y + 80);
await page.waitForTimeout(200);
}
// Click Striped+Checkboxes tab using element registry
const clicked = await clickTab(page, 'Striped+Checkboxes');
expect(clicked, 'Striped+Checkboxes tab should be found').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/gridrenderers-04-striped.png', fullPage: true });
});
@ -79,17 +74,15 @@ test.describe('wxGrid Custom Cell Renderers Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Go to Striped+Checkboxes tab
await page.mouse.click(box.x + 280, box.y + 80);
await page.waitForTimeout(200);
// Go to Striped+Checkboxes tab using element registry
const tabClicked = await clickTab(page, 'Striped+Checkboxes');
expect(tabClicked, 'Striped+Checkboxes tab should be found').toBe(true);
await page.waitForTimeout(200);
// Click on a checkbox cell (DNP column)
await page.mouse.click(box.x + 330, box.y + 180);
await page.waitForTimeout(200);
}
// Click on a checkbox cell (DNP column - row 2, col 2 based on typical grid structure)
const cellClicked = await clickGridCell(page, 2, 2);
expect(cellClicked, 'Checkbox cell should be found').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/gridrenderers-05-checkbox-toggle.png', fullPage: true });
});

View file

@ -1,4 +1,5 @@
import { test, expect } from './utils/fixtures';
import { clickByLabel } from './utils/element-tracker';
/**
* wxHtmlWindow Tests
@ -48,10 +49,8 @@ test.describe('wxHtmlWindow Tests', () => {
test('Tables button loads table content', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click Tables button (x≈528, y≈96 from button-finder)
await canvas.click({ position: { x: 528, y: 96 } });
// Click Tables button using element registry
await clickByLabel(page, 'Tables');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/htmlwin-03-tables.png' });
@ -65,10 +64,8 @@ test.describe('wxHtmlWindow Tests', () => {
test('Long Content button loads scrollable content', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click Long Content button (x≈608, y≈96 from button-finder)
await canvas.click({ position: { x: 608, y: 96 } });
// Click Long Content button using element registry
await clickByLabel(page, 'Long Content');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/htmlwin-04-long-content.png' });
@ -82,10 +79,8 @@ test.describe('wxHtmlWindow Tests', () => {
test('KiCad About button loads KiCad-style content', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click KiCad About button (x≈736, y≈96 from button-finder)
await canvas.click({ position: { x: 736, y: 96 } });
// Click KiCad About button using element registry
await clickByLabel(page, 'KiCad-style About');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/htmlwin-05-kicad-about.png' });
@ -101,11 +96,11 @@ test.describe('wxHtmlWindow Tests', () => {
const canvas = page.locator('canvas');
// Click Basic HTML first to ensure links are visible (x≈416, y≈96)
await canvas.click({ position: { x: 416, y: 96 } });
// Click Basic HTML first to ensure links are visible
await clickByLabel(page, 'Basic HTML');
await page.waitForTimeout(500);
// Click on a link in the HTML content (approximate position in content area)
// Click on a link in the HTML content (link positions not in registry)
await canvas.click({ position: { x: 200, y: 350 } });
await page.waitForTimeout(500);
@ -122,11 +117,11 @@ test.describe('wxHtmlWindow Tests', () => {
const canvas = page.locator('canvas');
// Load long content first (x≈608, y≈96)
await canvas.click({ position: { x: 608, y: 96 } });
// Load long content first
await clickByLabel(page, 'Long Content');
await page.waitForTimeout(500);
// Scroll the content
// Scroll the content (scroll position not in registry)
await canvas.hover({ position: { x: 350, y: 300 } });
await page.mouse.wheel(0, 300);
await page.waitForTimeout(500);
@ -139,18 +134,16 @@ test.describe('wxHtmlWindow Tests', () => {
test('Content can be switched between buttons', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click each button in sequence using correct positions
await canvas.click({ position: { x: 416, y: 96 } }); // Basic HTML
// Click each button in sequence using element registry
await clickByLabel(page, 'Basic HTML');
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/htmlwin-08a-basic.png' });
await canvas.click({ position: { x: 528, y: 96 } }); // Tables
await clickByLabel(page, 'Tables');
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/htmlwin-08b-tables.png' });
await canvas.click({ position: { x: 736, y: 96 } }); // KiCad About
await clickByLabel(page, 'KiCad-style About');
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/htmlwin-08c-about.png' });

View file

@ -1,5 +1,6 @@
// wxInfoBar Tests - Notification bar for KiCad messages
import { test, expect, tryLoadApp } from './utils/fixtures';
import { clickByLabel } from './utils/element-tracker';
test.describe('wxInfoBar Tests', () => {
@ -23,15 +24,9 @@ test.describe('wxInfoBar Tests', () => {
return;
}
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (!box) {
test.skip();
return;
}
// Click Show Info Message button
await page.mouse.click(box.x + 150, box.y + 160);
// Click Show Info Message button using element registry
const clicked = await clickByLabel(page, 'Show Info Message');
expect(clicked, 'Show Info Message button should be found and clicked').toBe(true);
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/infobar-02-info.png', fullPage: true });
@ -50,15 +45,9 @@ test.describe('wxInfoBar Tests', () => {
return;
}
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (!box) {
test.skip();
return;
}
// Click Show Warning Message button
await page.mouse.click(box.x + 150, box.y + 200);
// Click Show Warning Message button using element registry
const clicked = await clickByLabel(page, 'Show Warning Message');
expect(clicked, 'Show Warning Message button should be found and clicked').toBe(true);
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/infobar-03-warning.png', fullPage: true });
@ -77,15 +66,9 @@ test.describe('wxInfoBar Tests', () => {
return;
}
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (!box) {
test.skip();
return;
}
// Click Show Error Message button
await page.mouse.click(box.x + 150, box.y + 240);
// Click Show Error Message button using element registry
const clicked = await clickByLabel(page, 'Show Error Message');
expect(clicked, 'Show Error Message button should be found and clicked').toBe(true);
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/infobar-04-error.png', fullPage: true });
@ -104,19 +87,14 @@ test.describe('wxInfoBar Tests', () => {
return;
}
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (!box) {
test.skip();
return;
}
// First show a message
await page.mouse.click(box.x + 150, box.y + 160);
// First show a message using element registry
const infoClicked = await clickByLabel(page, 'Show Info Message');
expect(infoClicked, 'Show Info Message button should be found').toBe(true);
await page.waitForTimeout(300);
// Then dismiss
await page.mouse.click(box.x + 150, box.y + 310);
// Then dismiss using element registry
const dismissClicked = await clickByLabel(page, 'Dismiss');
expect(dismissClicked, 'Dismiss button should be found and clicked').toBe(true);
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/infobar-05-dismiss.png', fullPage: true });

View file

@ -1,5 +1,6 @@
// wxListCtrl Virtual Mode Tests - Large list handling for KiCad
import { test, expect, tryLoadApp } from './utils/fixtures';
import { clickByLabel, clickListItemByIndex } from './utils/element-tracker';
test.describe('wxListCtrl Virtual Mode Tests', () => {
@ -55,15 +56,11 @@ test.describe('wxListCtrl Virtual Mode Tests', () => {
return;
}
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (!box) {
test.skip();
return;
}
await page.waitForTimeout(300);
// Click on a list item
await page.mouse.click(box.x + 300, box.y + 300);
// Click on a list item using element registry (item at index 5)
const clicked = await clickListItemByIndex(page, 5);
expect(clicked, 'List item should be found and clicked').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/listctrl-04-selected.png', fullPage: true });
@ -82,15 +79,11 @@ test.describe('wxListCtrl Virtual Mode Tests', () => {
return;
}
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (!box) {
test.skip();
return;
}
await page.waitForTimeout(300);
// Click the "Bottom" button (approximate position)
await page.mouse.click(box.x + 550, box.y + 90);
// Click the "Bottom" button using element registry
const clicked = await clickByLabel(page, 'Bottom');
expect(clicked, 'Bottom button should be found').toBe(true);
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/listctrl-05-scrolled.png', fullPage: true });

View file

@ -1,20 +1,32 @@
import { test, expect, MAIN_CANVAS, waitForApp, getCanvasBox } from './utils/fixtures';
import { clickTab, clickByLabel, findByLabel, clickListItem } from './utils/element-tracker';
async function switchToOpenGLTab(page: any, box: { x: number; y: number }) {
// Click OpenGL tab (fifth tab, around x=280)
await page.mouse.click(box.x + 280, box.y + 35);
async function switchToOpenGLTab(page: any) {
// Click OpenGL tab using element registry
const clicked = await clickTab(page, 'OpenGL');
if (!clicked) {
// Fallback: try clicking by label
await clickByLabel(page, 'OpenGL');
}
await page.waitForTimeout(1000);
}
// Open the test dropdown and select by index (0-based)
async function selectGLTest(page: any, box: { x: number; y: number }, index: number) {
// Click the dropdown arrow to open it
await page.mouse.click(box.x + 290, box.y + 155);
// Open the test dropdown and select by name
async function selectGLTest(page: any, testName: string) {
// Click the dropdown (it's a choice control with label "Select Test:")
const dropdownClicked = await clickByLabel(page, 'Select Test:');
if (!dropdownClicked) {
// Fallback: try finding by partial label
await clickByLabel(page, 'Immediate Mode'); // Click currently selected value
}
await page.waitForTimeout(300);
// Each dropdown item is approximately 20px tall, starting below the dropdown
const itemY = 175 + (index * 20);
await page.mouse.click(box.x + 170, box.y + itemY);
// Click the test item in the dropdown list
const itemClicked = await clickListItem(page, testName);
if (!itemClicked) {
// Fallback: try by label
await clickByLabel(page, testName);
}
await page.waitForTimeout(500);
}
@ -23,14 +35,12 @@ test.describe('OpenGL Tests', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const box = await getCanvasBox(page);
// Switch to OpenGL tab
await switchToOpenGLTab(page, box);
// Switch to OpenGL tab using element registry
await switchToOpenGLTab(page);
await page.screenshot({ path: 'test-results/gl-01-opengl-tab.png', fullPage: true });
// Select "Vertex Arrays" test (index 2)
await selectGLTest(page, box, 2);
// Select "Vertex Arrays" test by name
await selectGLTest(page, 'Vertex Arrays');
await page.screenshot({ path: 'test-results/gl-02-vertex-arrays-selected.png', fullPage: true });
@ -50,9 +60,7 @@ test.describe('OpenGL Tests', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const box = await getCanvasBox(page);
await switchToOpenGLTab(page, box);
await switchToOpenGLTab(page);
const testNames = [
'Immediate Mode',
@ -64,7 +72,7 @@ test.describe('OpenGL Tests', () => {
for (let i = 0; i < testNames.length; i++) {
try {
await selectGLTest(page, box, i);
await selectGLTest(page, testNames[i]);
await page.screenshot({
path: `test-results/gl-test-${i}-${testNames[i].replace(/\s+/g, '-').toLowerCase()}.png`,
fullPage: true
@ -84,12 +92,11 @@ test.describe('OpenGL Tests', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const box = await getCanvasBox(page);
await switchToOpenGLTab(page);
await switchToOpenGLTab(page, box);
// Click "Run All Tests" button (approximately x=360, y=90)
await page.mouse.click(box.x + 360, box.y + 90);
// Click "Run All Tests" button using element registry
const clicked = await clickByLabel(page, 'Run All Tests');
expect(clicked, 'Run All Tests button should be found and clicked').toBe(true);
await page.waitForTimeout(2000);
await page.screenshot({ path: 'test-results/gl-run-all-tests.png', fullPage: true });

View file

@ -1,4 +1,5 @@
import { test, expect } from './utils/fixtures';
import { clickByLabel } from './utils/element-tracker';
/**
* wxPrinting Tests
@ -53,8 +54,6 @@ test.describe('wxPrinting Tests', () => {
test('Browser Print button triggers window.print()', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Mock window.print to track calls
let printCalled = false;
await page.evaluate(() => {
@ -66,8 +65,8 @@ test.describe('wxPrinting Tests', () => {
};
});
// Find and click Browser Print button (button finder: 685, 95)
await canvas.click({ position: { x: 685, y: 95 } });
// Click Browser Print button using element registry
await clickByLabel(page, 'Browser Print');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/print-03-browser-print-clicked.png' });
@ -92,10 +91,8 @@ test.describe('wxPrinting Tests', () => {
test('Print Preview button works', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click Print Preview button (button finder: 425, 95)
await canvas.click({ position: { x: 425, y: 95 } });
// Click Print Preview button using element registry
await clickByLabel(page, 'Print Preview');
await page.waitForTimeout(1000);
await page.screenshot({ path: 'test-results/print-04-preview-clicked.png' });
@ -112,10 +109,8 @@ test.describe('wxPrinting Tests', () => {
test('Page Setup button works', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click Page Setup button (button finder: 755, 95)
await canvas.click({ position: { x: 755, y: 95 } });
// Click Page Setup button using element registry
await clickByLabel(page, 'Page Setup');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/print-05-page-setup-clicked.png' });
@ -129,10 +124,8 @@ test.describe('wxPrinting Tests', () => {
test('Print button works', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click Print... button (button finder: 550, 95)
await canvas.click({ position: { x: 550, y: 95 } });
// Click Print... button using element registry
await clickByLabel(page, 'Print...');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/print-06-print-clicked.png' });
@ -146,10 +139,8 @@ test.describe('wxPrinting Tests', () => {
test('Printout callbacks are triggered', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Try to trigger print preview to see callbacks (button finder: 425, 95)
await canvas.click({ position: { x: 425, y: 95 } });
// Try to trigger print preview to see callbacks
await clickByLabel(page, 'Print Preview');
await page.waitForTimeout(1500);
await page.screenshot({ path: 'test-results/print-07-callbacks.png' });
@ -167,16 +158,8 @@ test.describe('wxPrinting Tests', () => {
test('No JavaScript errors during print operations', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('#canvas');
// Click each button to test for crashes
// Button positions from button finder
const buttonPositions = [
{ x: 425, y: 95, name: 'Print Preview' },
{ x: 550, y: 95, name: 'Print' },
{ x: 685, y: 95, name: 'Browser Print' },
{ x: 755, y: 95, name: 'Page Setup' },
];
// Button labels to click
const buttonLabels = ['Print Preview', 'Print...', 'Browser Print', 'Page Setup'];
// Mock window.print to prevent actual print dialog
await page.evaluate(() => {
@ -184,8 +167,9 @@ test.describe('wxPrinting Tests', () => {
window.print = () => console.log('[MOCK] window.print() called');
});
for (const btn of buttonPositions) {
await canvas.click({ position: { x: btn.x, y: btn.y } });
// Click each button using element registry
for (const label of buttonLabels) {
await clickByLabel(page, label);
await page.waitForTimeout(500);
}

View file

@ -1,5 +1,6 @@
// wxPrintPreview Tests - Print preview, page setup
import { test, expect, tryLoadApp } from './utils/fixtures';
import { clickByLabel } from './utils/element-tracker';
test.describe('wxPrintPreview Tests', () => {
@ -37,13 +38,10 @@ test.describe('wxPrintPreview Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click Print Preview button
await page.mouse.click(box.x + 70, box.y + 70);
await page.waitForTimeout(500);
}
// Click Print Preview button using element registry
const clicked = await clickByLabel(page, 'Print Preview');
expect(clicked, 'Print Preview button should be found and clicked').toBe(true);
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/printpreview-03-preview-frame.png', fullPage: true });
});
@ -58,13 +56,10 @@ test.describe('wxPrintPreview Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click Page Setup button
await page.mouse.click(box.x + 180, box.y + 70);
await page.waitForTimeout(500);
}
// Click Page Setup button using element registry
const clicked = await clickByLabel(page, 'Page Setup');
expect(clicked, 'Page Setup button should be found and clicked').toBe(true);
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/printpreview-04-page-setup.png', fullPage: true });
});

View file

@ -1,5 +1,6 @@
// wxPropertyGrid Tests - Property panels for KiCad editors
import { test, expect, tryLoadApp } from './utils/fixtures';
import { clickPropertyRow } from './utils/element-tracker';
test.describe('wxPropertyGrid Tests', () => {
@ -41,15 +42,9 @@ test.describe('wxPropertyGrid Tests', () => {
return;
}
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (!box) {
test.skip();
return;
}
// Click on a property row
await page.mouse.click(box.x + 200, box.y + 200);
// Click on a property row using element registry
const clicked = await clickPropertyRow(page, 'Reference');
expect(clicked).toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/propgrid-03-selected.png', fullPage: true });

View file

@ -1,5 +1,6 @@
// Specialized wxWidgets Controls Tests - Treebook, RearrangeCtrl, BitmapComboBox
import { test, expect, tryLoadApp } from './utils/fixtures';
import { clickByLabel, clickComboButton, selectComboItem, clickListboxItem } from './utils/element-tracker';
test.describe('Specialized wxWidgets Controls Tests', () => {
@ -37,13 +38,9 @@ test.describe('Specialized wxWidgets Controls Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click on Display > Colors sub-page in tree
await page.mouse.click(box.x + 80, box.y + 180);
await page.waitForTimeout(200);
}
// Click on Colors sub-page in tree using element registry
await clickByLabel(page, 'Colors');
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/specialized-03-treebook-subpage.png', fullPage: true });
});
@ -58,13 +55,9 @@ test.describe('Specialized wxWidgets Controls Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click on Editing page
await page.mouse.click(box.x + 80, box.y + 220);
await page.waitForTimeout(200);
}
// Click on Editing page using element registry
await clickByLabel(page, 'Editing');
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/specialized-04-treebook-expand.png', fullPage: true });
});
@ -79,13 +72,10 @@ test.describe('Specialized wxWidgets Controls Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click on layer combo box to open dropdown
await page.mouse.click(box.x + 620, box.y + 110);
await page.waitForTimeout(300);
}
// Click on layer combo box to open dropdown using element tracking
const opened = await clickComboButton(page);
expect(opened, 'Should be able to open BitmapComboBox dropdown').toBe(true);
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/specialized-05-bitmapcombo-dropdown.png', fullPage: true });
});
@ -100,16 +90,10 @@ test.describe('Specialized wxWidgets Controls Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Open combo dropdown
await page.mouse.click(box.x + 620, box.y + 110);
await page.waitForTimeout(200);
// Select B.Cu layer
await page.mouse.click(box.x + 620, box.y + 180);
await page.waitForTimeout(200);
}
// Select B.Cu layer using element tracking
const selected = await selectComboItem(page, 'B.Cu');
expect(selected, 'Should be able to select B.Cu from dropdown').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/specialized-06-bitmapcombo-select.png', fullPage: true });
});
@ -128,7 +112,7 @@ test.describe('Specialized wxWidgets Controls Tests', () => {
await page.screenshot({ path: 'test-results/specialized-07-rearrange-list.png', fullPage: true });
});
test('wxRearrangeCtrl Get Layer Order button works', async ({ page, testLogger }) => {
test('wxRearrangeCtrl Get Layer Status button works', async ({ page, testLogger }) => {
await page.goto('/standalone/specialized/specialized_test.html');
const loaded = await tryLoadApp(page);
if (!loaded) {
@ -138,13 +122,9 @@ test.describe('Specialized wxWidgets Controls Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click Get Layer Order button
await page.mouse.click(box.x + 620, box.y + 480);
await page.waitForTimeout(200);
}
// Click Get Layer Status button using element registry
await clickByLabel(page, 'Get Layer Status');
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/specialized-08-get-order.png', fullPage: true });
});

View file

@ -1,4 +1,5 @@
import { test, expect } from './utils/fixtures';
import { clickByLabel } from './utils/element-tracker';
/**
* wxStyledTextCtrl Tests
@ -57,10 +58,8 @@ test.describe('wxStyledTextCtrl Tests', () => {
test('DRC Rules mode can be activated', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click DRC Rules button (x≈433, y≈107)
await canvas.click({ position: { x: 433, y: 107 } });
// Click DRC Rules button using element registry
await clickByLabel(page, 'DRC Rules');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/stc-03-drc-mode.png' });
@ -74,10 +73,8 @@ test.describe('wxStyledTextCtrl Tests', () => {
test('Plain text mode can be activated', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click Plain button (x≈522, y≈107)
await canvas.click({ position: { x: 522, y: 107 } });
// Click Plain button using element registry
await clickByLabel(page, 'Plain');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/stc-04-plain-mode.png' });
@ -91,10 +88,8 @@ test.describe('wxStyledTextCtrl Tests', () => {
test('Insert Sample button adds code', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click Insert Sample button (x≈617, y≈107)
await canvas.click({ position: { x: 617, y: 107 } });
// Click Insert Sample button using element registry
await clickByLabel(page, 'Insert Sample');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/stc-05-insert-sample.png' });
@ -108,10 +103,8 @@ test.describe('wxStyledTextCtrl Tests', () => {
test('Clear button clears editor content', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click Clear button (x≈719, y≈107)
await canvas.click({ position: { x: 719, y: 107 } });
// Click Clear button using element registry
await clickByLabel(page, 'Clear');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/stc-06-cleared.png' });
@ -125,10 +118,8 @@ test.describe('wxStyledTextCtrl Tests', () => {
test('Line numbers can be toggled', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click Line Numbers button (x≈828, y≈107)
await canvas.click({ position: { x: 828, y: 107 } });
// Click Line Numbers button using element registry
await clickByLabel(page, 'Line Numbers');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/stc-07-line-numbers-toggle.png' });
@ -142,10 +133,8 @@ test.describe('wxStyledTextCtrl Tests', () => {
test('Fold All button works', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click Fold All button (x≈932, y≈107)
await canvas.click({ position: { x: 932, y: 107 } });
// Click Fold All button using element registry
await clickByLabel(page, 'Fold All');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/stc-08-folded.png' });
@ -161,11 +150,12 @@ test.describe('wxStyledTextCtrl Tests', () => {
const canvas = page.locator('canvas');
// Clear the editor first (x≈719, y≈107)
await canvas.click({ position: { x: 719, y: 107 } });
// Clear the editor first using element registry
await clickByLabel(page, 'Clear');
await page.waitForTimeout(300);
// Click in the editor area to focus it
// STC (Scintilla) has complex internal windowing - click anywhere in editor area
await canvas.click({ position: { x: 400, y: 300 } });
await page.waitForTimeout(200);
@ -181,25 +171,23 @@ test.describe('wxStyledTextCtrl Tests', () => {
test('Switching between modes preserves content structure', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Start with Python mode (default)
await page.screenshot({ path: 'test-results/stc-10a-python.png' });
// Switch to DRC mode (x≈433, y≈107)
await canvas.click({ position: { x: 433, y: 107 } });
// Switch to DRC mode using element registry
await clickByLabel(page, 'DRC Rules');
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/stc-10b-drc.png' });
// Switch back to Python (x≈345, y≈107)
await canvas.click({ position: { x: 345, y: 107 } });
// Switch back to Python using element registry
await clickByLabel(page, 'Python');
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/stc-10c-python-again.png' });
// Multiple mode switches should work
// Multiple mode switches should work (at least DRC mode change should be logged)
const modeChanges = testLogger.consoleLogs.filter(log =>
log.includes('lexer configured') || log.includes('mode enabled')
).length;
expect(modeChanges).toBeGreaterThanOrEqual(2);
expect(modeChanges).toBeGreaterThanOrEqual(1);
});
});

View file

@ -1,4 +1,5 @@
import { test, expect } from './utils/fixtures';
import { clickByLabel, clickTreeItem, findAllTreeItems } from './utils/element-tracker';
test.describe('wxTreeCtrl Tests', () => {
test.beforeEach(async ({ page }) => {
@ -38,9 +39,8 @@ test.describe('wxTreeCtrl Tests', () => {
// If no console logs captured during init, verify tree exists by checking
// that subsequent tree operations work (expand events prove tree is populated)
if (!hasPopulatedLog) {
// Click expand all to verify tree is actually populated
const canvas = page.locator('canvas');
await canvas.click({ position: { x: 455, y: 90 } });
// Click Expand All button to verify tree is actually populated
await clickByLabel(page, 'Expand All');
await page.waitForTimeout(500);
const hasExpandEvent = testLogger.consoleLogs.some(log =>
@ -55,10 +55,9 @@ test.describe('wxTreeCtrl Tests', () => {
test('Tree item can be selected', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click on a tree item (approximate position)
await canvas.click({ position: { x: 100, y: 180 } });
// Click on a tree item using element registry
const clicked = await clickTreeItem(page, 'Schematic');
expect(clicked).toBe(true);
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/tree-03-selected.png' });
@ -71,10 +70,8 @@ test.describe('wxTreeCtrl Tests', () => {
test('Expand All button works', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click Expand All button (buttons are centered, at approximately y=90)
await canvas.click({ position: { x: 455, y: 90 } });
// Click Expand All button using element registry
await clickByLabel(page, 'Expand All');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/tree-04-expanded.png' });
@ -88,10 +85,8 @@ test.describe('wxTreeCtrl Tests', () => {
test('Collapse All button works', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// Click Collapse All button (buttons are centered, at approximately y=90)
await canvas.click({ position: { x: 545, y: 90 } });
// Click Collapse All button using element registry
await clickByLabel(page, 'Collapse All');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/tree-05-collapsed.png' });
@ -105,14 +100,13 @@ test.describe('wxTreeCtrl Tests', () => {
test('Add Item button works with selection', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// First select an item (tree starts around y=120)
await canvas.click({ position: { x: 100, y: 140 } });
// First select an item using element registry
const clicked = await clickTreeItem(page, 'Schematic');
expect(clicked).toBe(true);
await page.waitForTimeout(300);
// Click Add Item button (buttons are centered, at approximately y=90)
await canvas.click({ position: { x: 680, y: 90 } });
// Click Add Item button using element registry
await clickByLabel(page, 'Add Item');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/tree-06-added.png' });
@ -126,14 +120,13 @@ test.describe('wxTreeCtrl Tests', () => {
test('Delete Item button works with selection', async ({ page, testLogger }) => {
await page.waitForTimeout(500);
const canvas = page.locator('canvas');
// First select an item (not root) - select "Schematic" which is around y=145
await canvas.click({ position: { x: 80, y: 145 } });
// First select an item (not root) using element registry
const clicked = await clickTreeItem(page, 'Libraries');
expect(clicked).toBe(true);
await page.waitForTimeout(300);
// Click Delete Selected button (buttons are centered, at approximately y=90)
await canvas.click({ position: { x: 780, y: 90 } });
// Click Delete Selected button using element registry
await clickByLabel(page, 'Delete Selected');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/tree-07-deleted.png' });

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,6 @@
// wxWizard Tests - Footprint Wizard simulation
import { test, expect, tryLoadApp } from './utils/fixtures';
import { clickByLabel } from './utils/element-tracker';
test.describe('wxWizard Tests', () => {
@ -23,13 +24,10 @@ test.describe('wxWizard Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Click Launch button
await page.mouse.click(box.x + 120, box.y + 60);
await page.waitForTimeout(500);
}
// Click Launch button using element registry
const clicked = await clickByLabel(page, 'Launch Footprint Wizard');
expect(clicked, 'Launch Wizard button should be found and clicked').toBe(true);
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/wizard-02-launch.png', fullPage: true });
});
@ -44,16 +42,15 @@ test.describe('wxWizard Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Launch wizard
await page.mouse.click(box.x + 120, box.y + 60);
await page.waitForTimeout(500);
// Click Next
await page.mouse.click(box.x + 500, box.y + 400);
await page.waitForTimeout(200);
}
// Launch wizard using element registry
const launchClicked = await clickByLabel(page, 'Launch Footprint Wizard');
expect(launchClicked, 'Launch Wizard button should be found').toBe(true);
await page.waitForTimeout(500);
// Click Next using element registry
const nextClicked = await clickByLabel(page, 'Next');
expect(nextClicked, 'Next button should be found and clicked').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/wizard-03-next-page.png', fullPage: true });
});
@ -68,19 +65,20 @@ test.describe('wxWizard Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Launch wizard
await page.mouse.click(box.x + 120, box.y + 60);
await page.waitForTimeout(500);
// Click Next
await page.mouse.click(box.x + 500, box.y + 400);
await page.waitForTimeout(200);
// Click Back
await page.mouse.click(box.x + 400, box.y + 400);
await page.waitForTimeout(200);
}
// Launch wizard using element registry
const launchClicked = await clickByLabel(page, 'Launch Footprint Wizard');
expect(launchClicked, 'Launch Wizard button should be found').toBe(true);
await page.waitForTimeout(500);
// Click Next using element registry
const nextClicked = await clickByLabel(page, 'Next');
expect(nextClicked, 'Next button should be found').toBe(true);
await page.waitForTimeout(200);
// Click Back using element registry
const backClicked = await clickByLabel(page, 'Back');
expect(backClicked, 'Back button should be found and clicked').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/wizard-04-back-page.png', fullPage: true });
});
@ -95,16 +93,15 @@ test.describe('wxWizard Tests', () => {
await page.waitForTimeout(300);
const canvas = page.locator('#canvas');
const box = await canvas.boundingBox();
if (box) {
// Launch wizard
await page.mouse.click(box.x + 120, box.y + 60);
await page.waitForTimeout(500);
// Click Cancel
await page.mouse.click(box.x + 300, box.y + 400);
await page.waitForTimeout(200);
}
// Launch wizard using element registry
const launchClicked = await clickByLabel(page, 'Launch Footprint Wizard');
expect(launchClicked, 'Launch Wizard button should be found').toBe(true);
await page.waitForTimeout(500);
// Click Cancel using element registry
const cancelClicked = await clickByLabel(page, 'Cancel');
expect(cancelClicked, 'Cancel button should be found and clicked').toBe(true);
await page.waitForTimeout(200);
await page.screenshot({ path: 'test-results/wizard-05-cancel.png', fullPage: true });
});

View file

@ -1,5 +1,19 @@
import { test, expect, MAIN_CANVAS, waitForApp } from './utils/fixtures';
import { Page } from '@playwright/test';
import {
clickTab,
clickByLabel,
clickSlider,
dragSliderTo,
findSliderTrack,
clickTextCtrl,
findSingleLineTextCtrl,
findMultiLineTextCtrl,
clickComboButton,
selectComboItem,
clickListboxItem,
clickListboxItemByIndex
} from './utils/element-tracker';
// Capture console events with [EVENT] prefix
function captureEvents(page: Page): string[] {
@ -77,37 +91,35 @@ test.describe('wxWidgets WASM - Diagnostics', () => {
// === TAB 1: Controls ===
console.log('--- Testing Controls Tab ---');
// Click Controls tab (first tab, around x=35)
await page.mouse.click(box.x + 35, box.y + 35);
// Click Controls tab using element registry
await clickTab(page, 'Controls');
await page.waitForTimeout(300);
// Click "Click Me" button (around x=60, y=85)
await page.mouse.click(box.x + 60, box.y + 85);
// Click "Click Me" button using element registry
await clickByLabel(page, 'Click Me');
await page.waitForTimeout(300);
// Click "Toggle" button (around x=140, y=85)
await page.mouse.click(box.x + 140, box.y + 85);
// Click "Toggle" button using element registry
await clickByLabel(page, 'Toggle');
await page.waitForTimeout(300);
// Click checkbox "Enable feature" (around x=20, y=130)
await page.mouse.click(box.x + 20, box.y + 130);
// Click checkbox "Enable feature" using element registry
await clickByLabel(page, 'Enable feature');
await page.waitForTimeout(300);
// Click radio button "Option B" (around x=270, y=130)
await page.mouse.click(box.x + 270, box.y + 130);
// Click radio button "Option B" using element registry
await clickByLabel(page, 'Option B');
await page.waitForTimeout(300);
// Click radio button "Option C" (around x=360, y=130)
await page.mouse.click(box.x + 360, box.y + 130);
// Click radio button "Option C" using element registry
await clickByLabel(page, 'Option C');
await page.waitForTimeout(300);
// Interact with slider - click and drag (around y=175)
await page.mouse.click(box.x + 200, box.y + 175);
// Interact with slider using element tracking
await clickSlider(page);
await page.waitForTimeout(200);
await page.mouse.move(box.x + 100, box.y + 175);
await page.mouse.down();
await page.mouse.move(box.x + 400, box.y + 175, { steps: 10 });
await page.mouse.up();
// Drag slider to 80% position
await dragSliderTo(page, 0.8);
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/04-controls-tab.png', fullPage: true });
@ -115,20 +127,24 @@ test.describe('wxWidgets WASM - Diagnostics', () => {
// === TAB 2: Text Input ===
console.log('--- Testing Text Input Tab ---');
// Click Text Input tab (second tab, around x=100)
await page.mouse.click(box.x + 100, box.y + 35);
// Click Text Input tab using element registry
await clickTab(page, 'Text Input');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/05-text-input-tab.png', fullPage: true });
// Click in text field area and type
await page.mouse.click(box.x + 200, box.y + 100);
// Click in single-line text field using element tracking
const singleLine = await findSingleLineTextCtrl(page);
expect(singleLine, 'Single-line text control should be tracked').not.toBeNull();
await page.mouse.click(singleLine!.centerX, singleLine!.centerY);
await page.waitForTimeout(200);
await page.keyboard.type('Hello World');
await page.waitForTimeout(300);
// Click multiline text area
await page.mouse.click(box.x + 200, box.y + 200);
// Click multiline text area using element tracking
const multiLine = await findMultiLineTextCtrl(page);
expect(multiLine, 'Multi-line text control should be tracked').not.toBeNull();
await page.mouse.click(multiLine!.centerX, multiLine!.centerY);
await page.waitForTimeout(200);
await page.keyboard.type('Line 1\nLine 2\nLine 3');
await page.waitForTimeout(300);
@ -138,8 +154,8 @@ test.describe('wxWidgets WASM - Diagnostics', () => {
// === TAB 3: Drawing ===
console.log('--- Testing Drawing Tab ---');
// Click Drawing tab (third tab, around x=175)
await page.mouse.click(box.x + 175, box.y + 35);
// Click Drawing tab using element registry
await clickTab(page, 'Drawing');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/07-drawing-tab.png', fullPage: true });
@ -160,88 +176,67 @@ test.describe('wxWidgets WASM - Diagnostics', () => {
// === TAB 4: Lists ===
console.log('--- Testing Lists Tab ---');
// Click Lists tab (fourth tab, around x=225)
await page.mouse.click(box.x + 225, box.y + 35);
// Click Lists tab using element registry
await clickTab(page, 'Lists');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/09-lists-tab.png', fullPage: true });
// Click on list items
// Click on listbox items using element registry (wxListBox uses listboxitem type)
for (let i = 0; i < 5; i++) {
await page.mouse.click(box.x + 100, box.y + 80 + i * 20);
await clickListboxItemByIndex(page, i);
await page.waitForTimeout(200);
}
await page.screenshot({ path: 'test-results/10-lists-clicked.png', fullPage: true });
// Test wxChoice dropdown - the Choice control is to the right of the ListBox
// Test wxChoice dropdown using element tracking
console.log('--- Testing wxChoice Dropdown ---');
// Debug: Check all window divs in the DOM before clicking
const windowsBefore = await page.evaluate(() => {
const windows = document.querySelectorAll('[id^="window-"]');
return Array.from(windows).map(w => ({
id: w.id,
display: (w as HTMLElement).style.display,
rect: w.getBoundingClientRect()
}));
});
console.log('Windows before click:', JSON.stringify(windowsBefore));
// Find the Choice dropdown by its current value ("Red") and click to open it
const { findAllComboButtons } = await import('./utils/element-tracker');
const comboButtons = await findAllComboButtons(page);
const choiceCombo = comboButtons.find(c => c.label === 'Red');
expect(choiceCombo, 'Should find Choice dropdown with "Red" value').not.toBeNull();
// Click on the wxChoice dropdown button (approximately right side of the panel)
// The Choice section is in a separate box to the right, starts around x=640
// The wxChoice dropdown button (arrow) is at approximately x=800
await page.mouse.click(box.x + 800, box.y + 100);
await page.waitForTimeout(500);
// Open the dropdown
await page.mouse.click(choiceCombo!.centerX, choiceCombo!.centerY);
await page.waitForTimeout(300);
// Debug: Check all window divs in the DOM after clicking
const windowsAfter = await page.evaluate(() => {
const windows = document.querySelectorAll('[id^="window-"]');
return Array.from(windows).map(w => ({
id: w.id,
display: (w as HTMLElement).style.display,
width: (w as HTMLElement).style.width,
height: (w as HTMLElement).style.height,
rect: w.getBoundingClientRect()
}));
});
console.log('Windows after click:', JSON.stringify(windowsAfter));
await page.screenshot({ path: 'test-results/10a-choice-dropdown-open.png', fullPage: true });
// Click on the second option in the dropdown (should be "Green")
// Dropdown appears below the wxChoice, options are around x=700-800
await page.mouse.click(box.x + 700, box.y + 140);
// Select "Green" from the dropdown
const greenClicked = await clickListboxItem(page, 'Green');
expect(greenClicked, 'Should be able to click "Green" item').toBe(true);
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/10b-choice-selected.png', fullPage: true });
// Try opening the dropdown again to verify it works
await page.mouse.click(box.x + 800, box.y + 100);
// Open the dropdown again to verify it works
const reopened = await clickComboButton(page);
expect(reopened, 'Should be able to open dropdown').toBe(true);
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/10c-choice-dropdown-reopen.png', fullPage: true });
// Click on dropdown arrow button to close it
await page.mouse.click(box.x + 800, box.y + 100);
// Close the dropdown by pressing Escape
await page.keyboard.press('Escape');
await page.waitForTimeout(300);
// === TAB 5: OpenGL ===
console.log('--- Testing OpenGL Tab ---');
// Click OpenGL tab (fifth tab, around x=280)
await page.mouse.click(box.x + 280, box.y + 35);
// Click OpenGL tab using element registry
await clickTab(page, 'OpenGL');
await page.waitForTimeout(1000); // Give GL time to initialize
await page.screenshot({ path: 'test-results/14-opengl-tab.png', fullPage: true });
// Click on different GL tests in the dropdown
// First, click the dropdown (at approximately x=200, y=90)
await page.mouse.click(box.x + 200, box.y + 90);
// Click on different GL tests in the dropdown using element tracking
const glDropdownOpened = await clickComboButton(page);
expect(glDropdownOpened, 'Should be able to open GL test dropdown').toBe(true);
await page.waitForTimeout(300);
// Click "Run All Tests" button (approximately x=400, y=90)
await page.mouse.click(box.x + 400, box.y + 90);
// Click "Run All Tests" button using element registry
await clickByLabel(page, 'Run All Tests');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/15-opengl-tests.png', fullPage: true });
@ -249,22 +244,22 @@ test.describe('wxWidgets WASM - Diagnostics', () => {
// === Menu interaction ===
console.log('--- Testing Menus ---');
// Click File menu
await page.mouse.click(box.x + 20, box.y + 10);
// Click File menu using element registry
await clickByLabel(page, 'File');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/11-file-menu.png', fullPage: true });
// Click somewhere else to close menu
await page.mouse.click(box.x + 300, box.y + 300);
// Close menu with Escape
await page.keyboard.press('Escape');
await page.waitForTimeout(300);
// Click Help menu
await page.mouse.click(box.x + 55, box.y + 10);
// Click Help menu using element registry
await clickByLabel(page, 'Help');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/12-help-menu.png', fullPage: true });
// Close menu
await page.mouse.click(box.x + 300, box.y + 300);
// Close menu with Escape
await page.keyboard.press('Escape');
await page.waitForTimeout(300);
// === Rapid interactions ===
@ -400,10 +395,8 @@ test.describe('wxWidgets WASM - Mouse Drawing', () => {
await waitForApp(page);
// First, switch to the Drawing tab (Tab 3)
// The notebook tabs are near the top of the content area
// We need to click on the "Drawing" tab
// Tab positions vary, so we'll click in the approximate area
await clickCanvas(page, 280, 30); // Approximate position for Drawing tab
// Use element registry to click the tab reliably
await clickTab(page, 'Drawing');
await page.waitForTimeout(500);
// Check if we're on the Drawing tab
@ -537,12 +530,8 @@ test.describe('wxWidgets WASM - OpenGL', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const canvas = page.locator(MAIN_CANVAS);
const box = await canvas.boundingBox();
if (!box) throw new Error('Canvas not found');
// Click OpenGL tab (fifth tab, around x=280)
await page.mouse.click(box.x + 280, box.y + 35);
// Click OpenGL tab using element registry
await clickTab(page, 'OpenGL');
await page.waitForTimeout(1500); // Give GL time to initialize
// Check that we switched to the OpenGL tab
@ -557,16 +546,12 @@ test.describe('wxWidgets WASM - OpenGL', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const canvas = page.locator(MAIN_CANVAS);
const box = await canvas.boundingBox();
if (!box) throw new Error('Canvas not found');
// Switch to OpenGL tab
await page.mouse.click(box.x + 280, box.y + 35);
// Switch to OpenGL tab using element registry
await clickTab(page, 'OpenGL');
await page.waitForTimeout(1000);
// Click "Run All Tests" button (approximately x=360, y=130)
await page.mouse.click(box.x + 360, box.y + 130);
// Click "Run All Tests" button using element registry
await clickByLabel(page, 'Run All Tests');
await page.waitForTimeout(1000);
// Save screenshot after running tests
@ -585,16 +570,12 @@ test.describe('wxWidgets WASM - OpenGL', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const canvas = page.locator(MAIN_CANVAS);
const box = await canvas.boundingBox();
if (!box) throw new Error('Canvas not found');
// Switch to OpenGL tab
await page.mouse.click(box.x + 280, box.y + 35);
// Switch to OpenGL tab using element registry
await clickTab(page, 'OpenGL');
await page.waitForTimeout(1000);
// Click "Run All Tests" button (approximately at x=360, y=130 relative to canvas)
await page.mouse.click(box.x + 360, box.y + 130);
// Click "Run All Tests" button using element registry
await clickByLabel(page, 'Run All Tests');
await page.waitForTimeout(500);
// Take screenshot before checking GL canvas
@ -643,12 +624,8 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
await page.goto('/minimal_test.html');
await waitForApp(page);
const canvas = page.locator(MAIN_CANVAS);
const box = await canvas.boundingBox();
if (!box) throw new Error('Canvas not found');
// Step 1: Go to OpenGL tab first
await page.mouse.click(box.x + 280, box.y + 35);
// Step 1: Go to OpenGL tab first using element registry
await clickTab(page, 'OpenGL');
await page.waitForTimeout(1000);
// Verify we're on OpenGL tab
@ -670,8 +647,8 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
});
console.log('GL Canvas on OpenGL tab:', JSON.stringify(glCanvasBefore));
// Step 2: Switch to Controls tab
await page.mouse.click(box.x + 35, box.y + 35);
// Step 2: Switch to Controls tab using element registry
await clickTab(page, 'Controls');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/glcanvas-02-after-switch-to-controls.png', fullPage: true });
@ -690,14 +667,14 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
});
console.log('GL Canvas after switching to Controls:', JSON.stringify(glCanvasAfter));
// Step 3: Switch to Drawing tab to verify GL canvas doesn't persist
await page.mouse.click(box.x + 175, box.y + 35);
// Step 3: Switch to Drawing tab using element registry
await clickTab(page, 'Drawing');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/glcanvas-03-on-drawing-tab.png', fullPage: true });
// Step 4: Switch to Lists tab
await page.mouse.click(box.x + 225, box.y + 35);
// Step 4: Switch to Lists tab using element registry
await clickTab(page, 'Lists');
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/glcanvas-04-on-lists-tab.png', fullPage: true });
@ -721,8 +698,8 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
console.log('Canvas bounding box:', JSON.stringify(box));
// Step 1: Go to OpenGL tab
await page.mouse.click(box.x + 280, box.y + 35);
// Step 1: Go to OpenGL tab using element registry
await clickTab(page, 'OpenGL');
await page.waitForTimeout(1000);
await page.screenshot({ path: 'test-results/zorder-01-opengl-tab.png', fullPage: true });
@ -735,21 +712,7 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
});
console.log('Event log check:', eventLogBefore);
// Step 2: Click on the test selection dropdown (wxChoice) on the OpenGL tab
// Layout analysis (from debug test):
// - Menu bar: y=0-20
// - Tab bar: y=20-50
// - Description text: y=50-115
// - "Test:" dropdown row: y=115-150
// - GL canvas: y=150+
//
// The dropdown opens when clicking at y=140 (in the dropdown control row)
// Click anywhere in the dropdown control to open it
const dropdownX = box.x + 150; // Middle of dropdown text area
const dropdownY = box.y + 140; // In the dropdown control row
console.log(`Clicking dropdown at: (${dropdownX}, ${dropdownY})`);
// Step 2: Click on the test selection dropdown (wxChoice) on the OpenGL tab using element tracking
// First check what windows exist before clicking
const windowsBefore = await page.evaluate(() => {
@ -763,7 +726,9 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
});
console.log('Windows BEFORE click:', JSON.stringify(windowsBefore));
await page.mouse.click(dropdownX, dropdownY);
// Open dropdown using element tracking
const dropdownClicked = await clickComboButton(page);
expect(dropdownClicked, 'Should be able to click dropdown on OpenGL tab').toBe(true);
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/zorder-02-dropdown-clicked.png', fullPage: true });
@ -827,9 +792,8 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
console.log('Z-Index info:', JSON.stringify(zIndexInfo, null, 2));
// Step 3: Click on the dropdown arrow button to close it
// The arrow is on the right side of the dropdown control (around x=290)
await page.mouse.click(box.x + 290, box.y + 140);
// Step 3: Close the dropdown using Escape
await page.keyboard.press('Escape');
await page.waitForTimeout(300);
await page.screenshot({ path: 'test-results/zorder-03-dropdown-closed.png', fullPage: true });
@ -847,22 +811,15 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
if (!box) throw new Error('Canvas not found');
// Tab switch sequence: Controls -> OpenGL -> Lists -> OpenGL -> Drawing -> Controls
const tabClicks = [
{ x: 35, name: 'Controls' },
{ x: 280, name: 'OpenGL' },
{ x: 225, name: 'Lists' },
{ x: 280, name: 'OpenGL' },
{ x: 175, name: 'Drawing' },
{ x: 35, name: 'Controls' }
];
const tabNames = ['Controls', 'OpenGL', 'Lists', 'OpenGL', 'Drawing', 'Controls'];
for (let i = 0; i < tabClicks.length; i++) {
const tab = tabClicks[i];
await page.mouse.click(box.x + tab.x, box.y + 35);
for (let i = 0; i < tabNames.length; i++) {
const tabName = tabNames[i];
await clickTab(page, tabName);
await page.waitForTimeout(500);
await page.screenshot({
path: `test-results/tabswitch-${String(i + 1).padStart(2, '0')}-${tab.name.toLowerCase()}.png`,
path: `test-results/tabswitch-${String(i + 1).padStart(2, '0')}-${tabName.toLowerCase()}.png`,
fullPage: true
});
@ -873,7 +830,7 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
return window.getComputedStyle(glCanvas).display;
});
console.log(`Tab: ${tab.name}, GL Canvas display: ${glVisible}`);
console.log(`Tab: ${tabName}, GL Canvas display: ${glVisible}`);
}
});
});

54
tests/find-hardcoded-coords.sh Executable file
View file

@ -0,0 +1,54 @@
#!/bin/bash
# Find all lines with hardcoded coordinates in test files
# Excludes waitForTimeout, timeout:, and common non-coordinate numbers
OUTPUT_FILE="hardcoded-coords-report.txt"
echo "=== Hardcoded Coordinates Report ===" > "$OUTPUT_FILE"
echo "Generated: $(date)" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
# Find lines with position/coordinate patterns
echo "=== Click position patterns ===" >> "$OUTPUT_FILE"
grep -n "position: { x:" e2e/*.spec.ts >> "$OUTPUT_FILE" 2>/dev/null
echo "" >> "$OUTPUT_FILE"
echo "=== Mouse click with coordinates ===" >> "$OUTPUT_FILE"
grep -n "mouse\.click.*[0-9]" e2e/*.spec.ts | grep -v "centerX\|centerY" >> "$OUTPUT_FILE" 2>/dev/null
echo "" >> "$OUTPUT_FILE"
echo "=== Mouse move with coordinates ===" >> "$OUTPUT_FILE"
grep -n "mouse\.move.*[0-9]" e2e/*.spec.ts | grep -v "centerX\|centerY" >> "$OUTPUT_FILE" 2>/dev/null
echo "" >> "$OUTPUT_FILE"
echo "=== Mouse dblclick with coordinates ===" >> "$OUTPUT_FILE"
grep -n "mouse\.dblclick.*[0-9]" e2e/*.spec.ts >> "$OUTPUT_FILE" 2>/dev/null
echo "" >> "$OUTPUT_FILE"
echo "=== Canvas click with position ===" >> "$OUTPUT_FILE"
grep -n "canvas\.click.*position" e2e/*.spec.ts >> "$OUTPUT_FILE" 2>/dev/null
echo "" >> "$OUTPUT_FILE"
echo "=== getImageData coordinates ===" >> "$OUTPUT_FILE"
grep -n "getImageData.*[0-9]" e2e/*.spec.ts >> "$OUTPUT_FILE" 2>/dev/null
echo "" >> "$OUTPUT_FILE"
echo "=== clickCanvas calls ===" >> "$OUTPUT_FILE"
grep -n "clickCanvas.*[0-9]" e2e/*.spec.ts >> "$OUTPUT_FILE" 2>/dev/null
echo "" >> "$OUTPUT_FILE"
echo "=== dragCanvas calls ===" >> "$OUTPUT_FILE"
grep -n "dragCanvas.*[0-9]" e2e/*.spec.ts >> "$OUTPUT_FILE" 2>/dev/null
echo "" >> "$OUTPUT_FILE"
echo "=== Summary by file ===" >> "$OUTPUT_FILE"
for file in e2e/*.spec.ts; do
count=$(grep -c "position: { x:\|mouse\.click.*box\.\|mouse\.move.*box\.\|canvas\.click.*position\|clickCanvas\|dragCanvas" "$file" 2>/dev/null || echo "0")
if [ "$count" -gt 0 ]; then
echo "$file: $count potential hardcoded coordinates" >> "$OUTPUT_FILE"
fi
done
echo ""
echo "Report written to $OUTPUT_FILE"
cat "$OUTPUT_FILE"