Clean up test infrastructure and fix test assertions
- Replace test.skip() with proper expect() assertions when app fails to load - Remove button-finder utility (no longer needed with element registry) - Remove kicad tests (tested separately) - Add findByName/clickByName helpers for bitmap buttons - Fix element lookups: use clickByName for bitmap buttons, clickTreeItem for treebook pages, selectComboItem for wxChoice items - Add SetName() to shape buttons in bitmapbuttons_test.cpp - Remove verbose logging from print and threadpool tests - Update README to reflect current test infrastructure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
2ecb79996d
commit
251056e506
42 changed files with 241 additions and 1138 deletions
|
|
@ -235,30 +235,6 @@ These tests use the element registry:
|
|||
- `filedialog.spec.ts` - Open, Save, Open Multiple buttons
|
||||
- `logerror.spec.ts` - Trigger Error, Flush Log buttons
|
||||
|
||||
## Button Finder Utility (Legacy)
|
||||
|
||||
For elements not trackable by the registry, the button-finder utility scans a test app to find clickable positions by pixel coordinates.
|
||||
|
||||
**Note:** This utility is excluded from regular test runs (`npm test`). Use the dedicated config to run it.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
cd tests
|
||||
|
||||
# Use the dedicated button-finder config (recommended)
|
||||
APP_URL=/standalone/clipboard/clipboard_test.html npx playwright test --config=playwright-button-finder.config.ts
|
||||
|
||||
# Scan with custom region (faster - focus on likely button area)
|
||||
APP_URL=/standalone/dialog/dialog_test.html START_Y=150 END_Y=300 STEP=8 npx playwright test --config=playwright-button-finder.config.ts
|
||||
|
||||
# Scan dataview test app for button positions
|
||||
APP_URL=/standalone/dataview/dataview_test.html STEP=8 START_Y=80 END_Y=180 npx playwright test --config=playwright-button-finder.config.ts
|
||||
|
||||
# Scan htmlwin test app
|
||||
APP_URL=/standalone/htmlwin/htmlwin_test.html STEP=8 START_Y=80 END_Y=160 npx playwright test --config=playwright-button-finder.config.ts
|
||||
```
|
||||
|
||||
### Available Test Apps
|
||||
|
||||
| App URL | Description |
|
||||
|
|
|
|||
|
|
@ -93,18 +93,23 @@ public:
|
|||
|
||||
m_btnSelect = new wxBitmapButton(mainPanel, wxID_ANY, CreateToolIcon(*wxBLACK, "S"));
|
||||
m_btnSelect->SetToolTip("Select Tool");
|
||||
m_btnSelect->SetName("SelectTool");
|
||||
|
||||
m_btnLine = new wxBitmapButton(mainPanel, wxID_ANY, CreateToolIcon(*wxBLUE, "L"));
|
||||
m_btnLine->SetToolTip("Line Tool");
|
||||
m_btnLine->SetName("LineTool");
|
||||
|
||||
m_btnRect = new wxBitmapButton(mainPanel, wxID_ANY, CreateToolIcon(wxColour(0, 128, 0), "R"));
|
||||
m_btnRect->SetToolTip("Rectangle Tool");
|
||||
m_btnRect->SetName("RectangleTool");
|
||||
|
||||
m_btnCircle = new wxBitmapButton(mainPanel, wxID_ANY, CreateToolIcon(*wxRED, "C"));
|
||||
m_btnCircle->SetToolTip("Circle Tool");
|
||||
m_btnCircle->SetName("CircleTool");
|
||||
|
||||
m_btnText = new wxBitmapButton(mainPanel, wxID_ANY, CreateToolIcon(wxColour(128, 0, 128), "T"));
|
||||
m_btnText->SetToolTip("Text Tool");
|
||||
m_btnText->SetName("TextTool");
|
||||
|
||||
m_btnSelect->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { Log("Select tool clicked"); });
|
||||
m_btnLine->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { Log("Line tool clicked"); });
|
||||
|
|
@ -182,9 +187,17 @@ public:
|
|||
wxStaticBoxSizer* shapesSizer = new wxStaticBoxSizer(wxHORIZONTAL, mainPanel, "Different Icon Shapes");
|
||||
|
||||
wxBitmapButton* btnRect = new wxBitmapButton(mainPanel, wxID_ANY, CreateIcon(*wxRED, 32, "rect"));
|
||||
btnRect->SetToolTip("Rectangle");
|
||||
btnRect->SetName("Rectangle");
|
||||
wxBitmapButton* btnCircle = new wxBitmapButton(mainPanel, wxID_ANY, CreateIcon(*wxBLUE, 32, "circle"));
|
||||
btnCircle->SetToolTip("Circle");
|
||||
btnCircle->SetName("Circle");
|
||||
wxBitmapButton* btnTriangle = new wxBitmapButton(mainPanel, wxID_ANY, CreateIcon(wxColour(0, 128, 0), 32, "triangle"));
|
||||
btnTriangle->SetToolTip("Triangle");
|
||||
btnTriangle->SetName("Triangle");
|
||||
wxBitmapButton* btnDiamond = new wxBitmapButton(mainPanel, wxID_ANY, CreateIcon(wxColour(128, 0, 128), 32, "diamond"));
|
||||
btnDiamond->SetToolTip("Diamond");
|
||||
btnDiamond->SetName("Diamond");
|
||||
|
||||
btnRect->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { Log("Rectangle shape clicked"); });
|
||||
btnCircle->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { Log("Circle shape clicked"); });
|
||||
|
|
@ -213,10 +226,15 @@ public:
|
|||
wxArtProvider::GetBitmap(wxART_REDO, wxART_TOOLBAR));
|
||||
|
||||
btnNew->SetToolTip("New");
|
||||
btnNew->SetName("New");
|
||||
btnOpen->SetToolTip("Open");
|
||||
btnOpen->SetName("Open");
|
||||
btnSave->SetToolTip("Save");
|
||||
btnSave->SetName("Save");
|
||||
btnUndo->SetToolTip("Undo");
|
||||
btnUndo->SetName("Undo");
|
||||
btnRedo->SetToolTip("Redo");
|
||||
btnRedo->SetName("Redo");
|
||||
|
||||
btnNew->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { Log("New clicked"); });
|
||||
btnOpen->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { Log("Open clicked"); });
|
||||
|
|
|
|||
|
|
@ -19,10 +19,7 @@ test.describe('wxAuiManager Tests', () => {
|
|||
test('AUI dockable panels are visible', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/aui/aui_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.screenshot({ path: 'test-results/aui-02-panels.png', fullPage: true });
|
||||
|
||||
|
|
@ -34,10 +31,7 @@ test.describe('wxAuiManager Tests', () => {
|
|||
test('Panel close button can be clicked', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/aui/aui_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Find all AUI parts to verify they're registered
|
||||
const auiParts = await findRenderedByType(page, 'auipart');
|
||||
|
|
@ -54,10 +48,7 @@ test.describe('wxAuiManager Tests', () => {
|
|||
test('Panel can be dragged', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/aui/aui_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
const box = await getCanvasBox(page);
|
||||
|
||||
|
|
@ -78,10 +69,7 @@ test.describe('wxAuiManager Tests', () => {
|
|||
test('Multiple panels can be interacted with', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/aui/aui_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Click in Properties panel using element tracking
|
||||
const propsClicked = await clickAuiPaneContent(page, 'Properties');
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@ test.describe('wxAuiNotebook Tests', () => {
|
|||
test('AuiNotebook tabs can be switched', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/auinotebook/auinotebook_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -35,10 +32,7 @@ test.describe('wxAuiNotebook Tests', () => {
|
|||
test('AuiNotebook tabs can be added', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/auinotebook/auinotebook_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -53,10 +47,7 @@ test.describe('wxAuiNotebook Tests', () => {
|
|||
test('AuiNotebook tabs can be removed', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/auinotebook/auinotebook_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -71,10 +62,7 @@ test.describe('wxAuiNotebook Tests', () => {
|
|||
test('AuiNotebook tab style can be changed', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/auinotebook/auinotebook_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// wxBitmapButton Tests - Bitmap buttons, toggle buttons, disabled states
|
||||
import { test, expect, tryLoadApp } from './utils/fixtures';
|
||||
import { clickByLabel } from './utils/element-tracker';
|
||||
import { clickByLabel, clickByName } from './utils/element-tracker';
|
||||
|
||||
test.describe('wxBitmapButton Tests', () => {
|
||||
|
||||
|
|
@ -17,18 +17,15 @@ test.describe('wxBitmapButton Tests', () => {
|
|||
test('Toolbar-style buttons can be clicked', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/bitmapbuttons/bitmapbuttons_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
// Click Select tool button using element registry
|
||||
await clickByLabel(page, 'Select Tool');
|
||||
// Click Select tool button using element registry (by name)
|
||||
await clickByName(page, 'SelectTool');
|
||||
await page.waitForTimeout(100);
|
||||
// Click Line tool button
|
||||
await clickByLabel(page, 'Line Tool');
|
||||
await clickByName(page, 'LineTool');
|
||||
await page.waitForTimeout(100);
|
||||
|
||||
await page.screenshot({ path: 'test-results/bitmapbuttons-02-toolbar-click.png', fullPage: true });
|
||||
|
|
@ -37,10 +34,7 @@ test.describe('wxBitmapButton Tests', () => {
|
|||
test('Toggle buttons can be toggled', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/bitmapbuttons/bitmapbuttons_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -54,10 +48,7 @@ test.describe('wxBitmapButton Tests', () => {
|
|||
test('Toggle button can toggle multiple layers', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/bitmapbuttons/bitmapbuttons_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -73,10 +64,7 @@ test.describe('wxBitmapButton Tests', () => {
|
|||
test('Disabled button can be re-enabled', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/bitmapbuttons/bitmapbuttons_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -90,19 +78,16 @@ test.describe('wxBitmapButton Tests', () => {
|
|||
test('Shape buttons display different icons', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/bitmapbuttons/bitmapbuttons_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
// Click different shape buttons using element registry (by tooltip)
|
||||
await clickByLabel(page, 'Rectangle');
|
||||
// Click different shape buttons using element registry (by name)
|
||||
await clickByName(page, 'Rectangle');
|
||||
await page.waitForTimeout(100);
|
||||
await clickByLabel(page, 'Circle');
|
||||
await clickByName(page, 'Circle');
|
||||
await page.waitForTimeout(100);
|
||||
await clickByLabel(page, 'Triangle');
|
||||
await clickByName(page, 'Triangle');
|
||||
await page.waitForTimeout(200);
|
||||
|
||||
await page.screenshot({ path: 'test-results/bitmapbuttons-06-shapes.png', fullPage: true });
|
||||
|
|
@ -111,17 +96,14 @@ test.describe('wxBitmapButton Tests', () => {
|
|||
test('Art Provider buttons display system icons', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/bitmapbuttons/bitmapbuttons_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
// Click New, Open buttons using element registry (by tooltip)
|
||||
await clickByLabel(page, 'New');
|
||||
// Click New, Open buttons using element registry (by name)
|
||||
await clickByName(page, 'New');
|
||||
await page.waitForTimeout(100);
|
||||
await clickByLabel(page, 'Open');
|
||||
await clickByName(page, 'Open');
|
||||
await page.waitForTimeout(200);
|
||||
|
||||
await page.screenshot({ path: 'test-results/bitmapbuttons-07-artprovider.png', fullPage: true });
|
||||
|
|
|
|||
|
|
@ -1,258 +0,0 @@
|
|||
/**
|
||||
* Button Finder Utility
|
||||
*
|
||||
* A utility for finding clickable button positions in wxWidgets WASM canvas apps.
|
||||
* This is NOT a regular test - it's excluded from normal test runs via testIgnore.
|
||||
*
|
||||
* wxWidgets WASM renders everything to a canvas, so UI tests need specific pixel
|
||||
* coordinates to click buttons. This utility scans the canvas and reports positions
|
||||
* that trigger console log responses (indicating a button was clicked).
|
||||
*
|
||||
* Usage:
|
||||
* cd tests
|
||||
*
|
||||
* # Scan clipboard test app
|
||||
* APP_URL=/standalone/clipboard/clipboard_test.html npx playwright test button-finder --reporter=list
|
||||
*
|
||||
* # Scan dialog test app
|
||||
* APP_URL=/standalone/dialog/dialog_test.html npx playwright test button-finder --reporter=list
|
||||
*
|
||||
* # Scan tree test app
|
||||
* APP_URL=/standalone/tree/tree_test.html npx playwright test button-finder --reporter=list
|
||||
*
|
||||
* # Scan menu test app
|
||||
* APP_URL=/standalone/menu/menu_test.html npx playwright test button-finder --reporter=list
|
||||
*
|
||||
* # Scan with custom region (faster - focus on likely button area)
|
||||
* APP_URL=/standalone/dialog/dialog_test.html START_Y=150 END_Y=300 STEP=8 npx playwright test button-finder --reporter=list
|
||||
*
|
||||
* Environment Variables:
|
||||
* APP_URL - URL path to scan (REQUIRED - no default to force explicit choice)
|
||||
* STEP - Pixel step size (default: 10, smaller = more accurate but slower)
|
||||
* START_X - X start coordinate (default: 0)
|
||||
* END_X - X end coordinate (default: canvas width)
|
||||
* START_Y - Y start coordinate (default: 0)
|
||||
* END_Y - Y end coordinate (default: canvas height)
|
||||
*
|
||||
* Available Test Apps:
|
||||
* /standalone/clipboard/clipboard_test.html - Copy, Paste, Check, Clear buttons
|
||||
* /standalone/dialog/dialog_test.html - Info, Yes/No, Error, Custom dialog buttons
|
||||
* /standalone/tree/tree_test.html - Expand All, Collapse All, etc.
|
||||
* /standalone/menu/menu_test.html - Menu bar testing
|
||||
* /standalone/grid/grid_test.html - Grid controls
|
||||
* /standalone/aui/aui_test.html - AUI panel controls
|
||||
* /standalone/toolbar/toolbar_test.html - Toolbar buttons
|
||||
* /standalone/timer/timer_test.html - Timer controls
|
||||
* /standalone/filedialog/filedialog_test.html - File dialog buttons
|
||||
* /standalone/layout/layout_test.html - Layout controls
|
||||
*
|
||||
* Output:
|
||||
* - Console output with button positions and labels
|
||||
* - Generated test code snippets
|
||||
* - JSON results at test-results/button-finder-results.json
|
||||
*/
|
||||
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { tryLoadApp } from './utils/fixtures';
|
||||
|
||||
// Configuration from environment - APP_URL is required
|
||||
const APP_URL = process.env.APP_URL;
|
||||
const STEP = parseInt(process.env.STEP || '10');
|
||||
const START_Y = process.env.START_Y ? parseInt(process.env.START_Y) : undefined;
|
||||
const END_Y = process.env.END_Y ? parseInt(process.env.END_Y) : undefined;
|
||||
const START_X = process.env.START_X ? parseInt(process.env.START_X) : undefined;
|
||||
const END_X = process.env.END_X ? parseInt(process.env.END_X) : undefined;
|
||||
|
||||
test.describe('Button Finder Utility', () => {
|
||||
// Long timeout for scanning
|
||||
test.setTimeout(300000);
|
||||
|
||||
test('Scan for buttons', async ({ page }) => {
|
||||
// Require APP_URL to be specified
|
||||
if (!APP_URL) {
|
||||
console.error('\n' + '='.repeat(70));
|
||||
console.error('ERROR: APP_URL environment variable is required');
|
||||
console.error('='.repeat(70));
|
||||
console.error('\nUsage examples:');
|
||||
console.error(' APP_URL=/standalone/clipboard/clipboard_test.html npx playwright test button-finder --reporter=list');
|
||||
console.error(' APP_URL=/standalone/dialog/dialog_test.html npx playwright test button-finder --reporter=list');
|
||||
console.error(' APP_URL=/standalone/tree/tree_test.html START_Y=100 END_Y=300 npx playwright test button-finder --reporter=list');
|
||||
console.error('\nAvailable apps:');
|
||||
console.error(' /standalone/clipboard/clipboard_test.html');
|
||||
console.error(' /standalone/dialog/dialog_test.html');
|
||||
console.error(' /standalone/tree/tree_test.html');
|
||||
console.error(' /standalone/menu/menu_test.html');
|
||||
console.error(' /standalone/grid/grid_test.html');
|
||||
console.error(' /standalone/aui/aui_test.html');
|
||||
console.error(' /standalone/toolbar/toolbar_test.html');
|
||||
console.error(' /standalone/timer/timer_test.html');
|
||||
console.error(' /standalone/filedialog/filedialog_test.html');
|
||||
console.error(' /standalone/layout/layout_test.html');
|
||||
console.error('');
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`\n${'='.repeat(70)}`);
|
||||
console.log(`Button Finder - Scanning: ${APP_URL}`);
|
||||
console.log(`Step size: ${STEP}px`);
|
||||
console.log(`${'='.repeat(70)}\n`);
|
||||
|
||||
// Navigate and wait for app
|
||||
await page.goto(APP_URL);
|
||||
const loaded = await tryLoadApp(page);
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Get canvas bounds
|
||||
const canvas = page.locator('canvas').first();
|
||||
const box = await canvas.boundingBox();
|
||||
if (!box) {
|
||||
console.log('ERROR: Canvas not found');
|
||||
return;
|
||||
}
|
||||
|
||||
const scanStartX = START_X ?? 0;
|
||||
const scanEndX = END_X ?? box.width;
|
||||
const scanStartY = START_Y ?? 0;
|
||||
const scanEndY = END_Y ?? box.height;
|
||||
|
||||
console.log(`Canvas: ${box.width}x${box.height} at (${box.x}, ${box.y})`);
|
||||
console.log(`Scan region: X[${scanStartX}-${scanEndX}] Y[${scanStartY}-${scanEndY}]`);
|
||||
console.log(`Estimated clicks: ${Math.ceil((scanEndX - scanStartX) / STEP) * Math.ceil((scanEndY - scanStartY) / STEP)}\n`);
|
||||
|
||||
// Take before screenshot
|
||||
await page.screenshot({ path: 'test-results/button-finder-before.png', fullPage: true });
|
||||
|
||||
// Collect console logs
|
||||
const logs: string[] = [];
|
||||
page.on('console', msg => logs.push(msg.text()));
|
||||
|
||||
// Track found buttons
|
||||
const buttons: Array<{x: number, y: number, label: string, log: string}> = [];
|
||||
const seenLogs = new Set<string>();
|
||||
|
||||
// Keywords that indicate a button click response
|
||||
const buttonKeywords = [
|
||||
'Attempting', 'SUCCESS', 'ERROR', 'WARNING',
|
||||
'clicked', 'Clicked', 'EVT_BUTTON', 'EVT_MENU',
|
||||
'OnButton', 'OnClick', 'pressed', 'Pressed',
|
||||
'Copy', 'Paste', 'Clear', 'Check', 'Open', 'Close',
|
||||
'selected', 'Selected', 'expand', 'collapse',
|
||||
'Expand', 'Collapse', 'Add', 'Remove', 'Delete',
|
||||
'Start', 'Stop', 'Reset', 'Save', 'Load'
|
||||
];
|
||||
|
||||
// Label keywords for identification
|
||||
const labelKeywords = [
|
||||
'Copy', 'Paste', 'Clear', 'Check', 'Open', 'Close',
|
||||
'OK', 'Cancel', 'Yes', 'No', 'Expand', 'Collapse',
|
||||
'Add', 'Remove', 'Delete', 'Start', 'Stop', 'Reset',
|
||||
'Save', 'Load', 'Info', 'Error', 'Warning', 'Custom'
|
||||
];
|
||||
|
||||
// Scan the canvas
|
||||
let lastProgressY = -100;
|
||||
for (let y = scanStartY; y < scanEndY; y += STEP) {
|
||||
// Progress indicator every 50px
|
||||
if (y - lastProgressY >= 50) {
|
||||
console.log(`Scanning row ${y}/${scanEndY}...`);
|
||||
lastProgressY = y;
|
||||
}
|
||||
|
||||
for (let x = scanStartX; x < scanEndX; x += STEP) {
|
||||
const logCountBefore = logs.length;
|
||||
|
||||
// Click at this position
|
||||
await page.mouse.click(box.x + x, box.y + y);
|
||||
// Small wait to allow response
|
||||
await page.waitForTimeout(20);
|
||||
|
||||
// Check for new logs
|
||||
if (logs.length > logCountBefore) {
|
||||
const newLogs = logs.slice(logCountBefore);
|
||||
|
||||
for (const log of newLogs) {
|
||||
// Skip noise
|
||||
if (log.includes('favicon') || log.includes('DevTools')) continue;
|
||||
|
||||
// Check if this looks like a button response
|
||||
const isButtonLog = buttonKeywords.some(kw => log.includes(kw));
|
||||
|
||||
if (isButtonLog && !seenLogs.has(log)) {
|
||||
seenLogs.add(log);
|
||||
|
||||
// Try to extract a label
|
||||
let label = 'Button';
|
||||
for (const kw of labelKeywords) {
|
||||
if (log.toLowerCase().includes(kw.toLowerCase())) {
|
||||
label = kw;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buttons.push({
|
||||
x,
|
||||
y,
|
||||
label,
|
||||
log: log.substring(0, 80)
|
||||
});
|
||||
|
||||
console.log(` FOUND: (${x}, ${y}) ${label} - "${log.substring(0, 60)}"`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Take after screenshot
|
||||
await page.screenshot({ path: 'test-results/button-finder-after.png', fullPage: true });
|
||||
|
||||
// Output results
|
||||
console.log(`\n${'='.repeat(70)}`);
|
||||
console.log(`RESULTS: Found ${buttons.length} buttons`);
|
||||
console.log(`${'='.repeat(70)}\n`);
|
||||
|
||||
if (buttons.length > 0) {
|
||||
console.log('Button positions (relative to canvas):');
|
||||
console.log('');
|
||||
for (const btn of buttons) {
|
||||
console.log(` ${btn.label.padEnd(12)} at (${String(btn.x).padStart(3)}, ${String(btn.y).padStart(3)})`);
|
||||
console.log(` Log: ${btn.log}`);
|
||||
console.log('');
|
||||
}
|
||||
|
||||
console.log('\nGenerated test code:');
|
||||
console.log('```typescript');
|
||||
console.log('const box = await getCanvasBox(page);');
|
||||
console.log('');
|
||||
for (const btn of buttons) {
|
||||
console.log(`// ${btn.label} button`);
|
||||
console.log(`await page.mouse.click(box.x + ${btn.x}, box.y + ${btn.y});`);
|
||||
console.log(`await page.waitForTimeout(500);`);
|
||||
console.log('');
|
||||
}
|
||||
console.log('```');
|
||||
} else {
|
||||
console.log('No buttons found.');
|
||||
console.log('\nPossible reasons:');
|
||||
console.log(' - Buttons are outside the scan region (try adjusting START_Y/END_Y)');
|
||||
console.log(' - Button clicks dont produce recognizable logs');
|
||||
console.log(' - Step size is too large (try STEP=5)');
|
||||
console.log('\nCaptured logs:');
|
||||
logs.slice(0, 30).forEach(log => console.log(` ${log.substring(0, 80)}`));
|
||||
}
|
||||
|
||||
// Write results to a JSON file for programmatic use
|
||||
const results = {
|
||||
app: APP_URL,
|
||||
canvas: { x: box.x, y: box.y, width: box.width, height: box.height },
|
||||
scanRegion: { startX: scanStartX, endX: scanEndX, startY: scanStartY, endY: scanEndY },
|
||||
step: STEP,
|
||||
buttons: buttons
|
||||
};
|
||||
|
||||
const fs = await import('fs');
|
||||
fs.writeFileSync('test-results/button-finder-results.json', JSON.stringify(results, null, 2));
|
||||
console.log('\nResults saved to: test-results/button-finder-results.json');
|
||||
});
|
||||
});
|
||||
|
|
@ -17,10 +17,7 @@ test.describe('wxCalendarCtrl Tests', () => {
|
|||
test('Calendar dates can be selected', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/calendar/calendar_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -35,10 +32,7 @@ test.describe('wxCalendarCtrl Tests', () => {
|
|||
test('Calendar can navigate to next month', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/calendar/calendar_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -53,10 +47,7 @@ test.describe('wxCalendarCtrl Tests', () => {
|
|||
test('Calendar can navigate to previous month', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/calendar/calendar_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -71,10 +62,7 @@ test.describe('wxCalendarCtrl Tests', () => {
|
|||
test('Calendar can navigate to today', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/calendar/calendar_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,10 +21,7 @@ test.describe('wxClipboard Tests', () => {
|
|||
test('Copy button copies text to clipboard', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/clipboard/clipboard_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
@ -49,10 +46,7 @@ test.describe('wxClipboard Tests', () => {
|
|||
test('Paste button retrieves text from clipboard', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/clipboard/clipboard_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
@ -84,10 +78,7 @@ test.describe('wxClipboard Tests', () => {
|
|||
test('Check clipboard button reports clipboard content', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/clipboard/clipboard_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
@ -112,10 +103,7 @@ test.describe('wxClipboard Tests', () => {
|
|||
test('Clear clipboard button clears clipboard', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/clipboard/clipboard_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
@ -143,10 +131,7 @@ test.describe('wxClipboard Tests', () => {
|
|||
test('Full clipboard flow: copy, check, paste, clear', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/clipboard/clipboard_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,7 @@ test.describe('wxCollapsiblePane Tests', () => {
|
|||
test('Collapsible panes are created', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/collapsible/collapsible_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/collapsible-02-panes.png', fullPage: true });
|
||||
|
|
@ -36,10 +33,7 @@ test.describe('wxCollapsiblePane Tests', () => {
|
|||
test('First pane is expanded by default', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/collapsible/collapsible_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/collapsible-03-expanded.png', fullPage: true });
|
||||
|
|
@ -51,10 +45,7 @@ test.describe('wxCollapsiblePane Tests', () => {
|
|||
test('Expand All button works', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/collapsible/collapsible_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Click Expand All button using element registry
|
||||
const clicked = await clickByLabel(page, 'Expand All');
|
||||
|
|
@ -72,10 +63,7 @@ test.describe('wxCollapsiblePane Tests', () => {
|
|||
test('Collapse All button works', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/collapsible/collapsible_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Click Collapse All button using element registry
|
||||
const clicked = await clickByLabel(page, 'Collapse All');
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@ test.describe('wxDataViewCtrl Virtual Mode Tests', () => {
|
|||
test('Virtual list handles large datasets', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dataviewvirtual/dataviewvirtual_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
|
|
@ -40,10 +37,7 @@ test.describe('wxDataViewCtrl Virtual Mode Tests', () => {
|
|||
test('Virtual list scrolling works', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dataviewvirtual/dataviewvirtual_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -58,10 +52,7 @@ test.describe('wxDataViewCtrl Virtual Mode Tests', () => {
|
|||
test('Virtual list selection works', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dataviewvirtual/dataviewvirtual_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -77,10 +68,7 @@ test.describe('wxDataViewCtrl Virtual Mode Tests', () => {
|
|||
test('Zone manager panel works', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dataviewvirtual/dataviewvirtual_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,10 +20,7 @@ test.describe('wxDialog/wxMessageBox Tests', () => {
|
|||
test('Info dialog button can be clicked', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dialog/dialog_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
@ -43,10 +40,7 @@ test.describe('wxDialog/wxMessageBox Tests', () => {
|
|||
test('Yes/No dialog button can be clicked', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dialog/dialog_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
@ -65,10 +59,7 @@ test.describe('wxDialog/wxMessageBox Tests', () => {
|
|||
test('Error dialog button can be clicked', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dialog/dialog_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
@ -87,10 +78,7 @@ test.describe('wxDialog/wxMessageBox Tests', () => {
|
|||
test('Custom dialog button can be clicked', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dialog/dialog_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,10 +21,7 @@ test.describe('wxDragDrop Tests', () => {
|
|||
test('DnD handlers are registered', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dnd/dnd_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.screenshot({ path: 'test-results/dnd-02-handlers.png', fullPage: true });
|
||||
|
||||
|
|
@ -37,17 +34,11 @@ test.describe('wxDragDrop Tests', () => {
|
|||
test('DragEnter event is detected', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dnd/dnd_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
const canvas = page.locator('#canvas');
|
||||
const box = await canvas.boundingBox();
|
||||
if (!box) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(box, 'Canvas should have bounding box').not.toBeNull();
|
||||
|
||||
// Simulate dragenter event
|
||||
await page.evaluate(({ x, y }) => {
|
||||
|
|
@ -74,17 +65,11 @@ test.describe('wxDragDrop Tests', () => {
|
|||
test('DragLeave event is detected', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dnd/dnd_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
const canvas = page.locator('#canvas');
|
||||
const box = await canvas.boundingBox();
|
||||
if (!box) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(box, 'Canvas should have bounding box').not.toBeNull();
|
||||
|
||||
// Simulate dragenter then dragleave
|
||||
await page.evaluate(({ x, y }) => {
|
||||
|
|
@ -118,17 +103,11 @@ test.describe('wxDragDrop Tests', () => {
|
|||
test('Drop event triggers file processing', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dnd/dnd_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
const canvas = page.locator('#canvas');
|
||||
const box = await canvas.boundingBox();
|
||||
if (!box) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(box, 'Canvas should have bounding box').not.toBeNull();
|
||||
|
||||
// Create a test file and simulate drop
|
||||
const testContent = 'Test file content for DnD';
|
||||
|
|
@ -163,17 +142,11 @@ test.describe('wxDragDrop Tests', () => {
|
|||
test('Dropped file is written to WASM filesystem', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dnd/dnd_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
const canvas = page.locator('#canvas');
|
||||
const box = await canvas.boundingBox();
|
||||
if (!box) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(box, 'Canvas should have bounding box').not.toBeNull();
|
||||
|
||||
const testFileName = 'wasm-test-file.txt';
|
||||
const testContent = 'Content written via DnD';
|
||||
|
|
@ -208,17 +181,11 @@ test.describe('wxDragDrop Tests', () => {
|
|||
test('wxDropFilesEvent is fired after drop', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dnd/dnd_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
const canvas = page.locator('#canvas');
|
||||
const box = await canvas.boundingBox();
|
||||
if (!box) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(box, 'Canvas should have bounding box').not.toBeNull();
|
||||
|
||||
const testFileName = 'event-test.kicad_pcb';
|
||||
const testContent = '(kicad_pcb (version 20230121))';
|
||||
|
|
@ -255,17 +222,11 @@ test.describe('wxDragDrop Tests', () => {
|
|||
test('Multiple files can be dropped', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dnd/dnd_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
const canvas = page.locator('#canvas');
|
||||
const box = await canvas.boundingBox();
|
||||
if (!box) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(box, 'Canvas should have bounding box').not.toBeNull();
|
||||
|
||||
await page.evaluate(({ x, y }) => {
|
||||
const canvas = document.getElementById('canvas');
|
||||
|
|
@ -300,18 +261,12 @@ test.describe('wxDragDrop Tests', () => {
|
|||
test('Clear files button exists in UI', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/dnd/dnd_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// First drop a file to verify drop works
|
||||
const canvas = page.locator('#canvas');
|
||||
const box = await canvas.boundingBox();
|
||||
if (!box) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(box, 'Canvas should have bounding box').not.toBeNull();
|
||||
|
||||
await page.evaluate(({ x, y }) => {
|
||||
const canvas = document.getElementById('canvas');
|
||||
|
|
|
|||
|
|
@ -20,10 +20,7 @@ test.describe('Early GetClientSize() Tests', () => {
|
|||
test('GetClientSize() returns reasonable values before Show()', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/earlysize/earlysize_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Wait for the app to finish initialization
|
||||
await page.waitForTimeout(500);
|
||||
|
|
|
|||
|
|
@ -19,10 +19,7 @@ test.describe('wxFileDialog Tests', () => {
|
|||
test('Open file button can be clicked', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/filedialog/filedialog_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
@ -38,10 +35,7 @@ test.describe('wxFileDialog Tests', () => {
|
|||
test('Save file button can be clicked', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/filedialog/filedialog_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
@ -57,10 +51,7 @@ test.describe('wxFileDialog Tests', () => {
|
|||
test('Open multiple button can be clicked', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/filedialog/filedialog_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
@ -76,10 +67,7 @@ test.describe('wxFileDialog Tests', () => {
|
|||
test('All file dialog buttons accessible', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/filedialog/filedialog_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,11 +6,7 @@ test.describe('wxFontEnumerator Tests', () => {
|
|||
test('Font enumeration renders correctly', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/fontenum/fontenum_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Wait for auto font enumeration to complete (uses Asyncify)
|
||||
await page.waitForTimeout(3000);
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@ test.describe('wxGrid Cell Editing Tests', () => {
|
|||
test('Grid cells can be selected', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/gridedit/gridedit_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -35,10 +32,7 @@ test.describe('wxGrid Cell Editing Tests', () => {
|
|||
test('Grid cells can be edited', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/gridedit/gridedit_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -56,10 +50,7 @@ test.describe('wxGrid Cell Editing Tests', () => {
|
|||
test('Grid rows can be added', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/gridedit/gridedit_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -74,10 +65,7 @@ test.describe('wxGrid Cell Editing Tests', () => {
|
|||
test('Grid rows can be deleted', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/gridedit/gridedit_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@ test.describe('wxGrid Custom Cell Renderers Tests', () => {
|
|||
test('Color cells tab displays color swatches', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/gridrenderers/gridrenderers_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -31,10 +28,7 @@ test.describe('wxGrid Custom Cell Renderers Tests', () => {
|
|||
test('Icon+Text tab displays icons with text', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/gridrenderers/gridrenderers_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -49,10 +43,7 @@ test.describe('wxGrid Custom Cell Renderers Tests', () => {
|
|||
test('Striped rows tab displays alternating colors', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/gridrenderers/gridrenderers_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -67,10 +58,7 @@ test.describe('wxGrid Custom Cell Renderers Tests', () => {
|
|||
test('Checkbox cells can be toggled in striped grid', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/gridrenderers/gridrenderers_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,7 @@ test.describe('wxInfoBar Tests', () => {
|
|||
test('Show Info Message button works', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/infobar/infobar_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Click Show Info Message button using element registry
|
||||
const clicked = await clickByLabel(page, 'Show Info Message');
|
||||
|
|
@ -40,10 +37,7 @@ test.describe('wxInfoBar Tests', () => {
|
|||
test('Show Warning Message button works', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/infobar/infobar_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Click Show Warning Message button using element registry
|
||||
const clicked = await clickByLabel(page, 'Show Warning Message');
|
||||
|
|
@ -61,10 +55,7 @@ test.describe('wxInfoBar Tests', () => {
|
|||
test('Show Error Message button works', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/infobar/infobar_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Click Show Error Message button using element registry
|
||||
const clicked = await clickByLabel(page, 'Show Error Message');
|
||||
|
|
@ -82,10 +73,7 @@ test.describe('wxInfoBar Tests', () => {
|
|||
test('Dismiss button works', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/infobar/infobar_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// First show a message using element registry
|
||||
const infoClicked = await clickByLabel(page, 'Show Info Message');
|
||||
|
|
|
|||
|
|
@ -1,96 +0,0 @@
|
|||
import { test, expect } from '../utils/fixtures';
|
||||
|
||||
test.describe('KiCad PCBnew WASM', () => {
|
||||
|
||||
test('WASM runtime initializes', async ({ page, testLogger }) => {
|
||||
// Navigate to KiCad app
|
||||
await page.goto('/kicad/pcbnew.html');
|
||||
|
||||
// Wait for runtime initialization (longer timeout for KiCad - 15MB WASM)
|
||||
await page.waitForFunction(() => {
|
||||
return (document.querySelector('#canvas') as HTMLElement)?.style.display === 'block';
|
||||
}, { timeout: 120000 }); // 2 min timeout for large WASM
|
||||
|
||||
// Verify canvas is visible
|
||||
const canvas = page.locator('#canvas');
|
||||
await expect(canvas).toBeVisible();
|
||||
|
||||
// Check for successful initialization logs
|
||||
const initLog = testLogger.consoleLogs.find(l =>
|
||||
l.includes('[KICAD] Runtime initialized')
|
||||
);
|
||||
expect(initLog).toBeTruthy();
|
||||
|
||||
// Check that app started creating
|
||||
const appLog = testLogger.consoleLogs.find(l =>
|
||||
l.includes('[KICAD_OUT] Creating app')
|
||||
);
|
||||
expect(appLog).toBeTruthy();
|
||||
|
||||
// Take screenshot of initial state
|
||||
await page.screenshot({
|
||||
path: 'test-results/kicad-pcbnew-01-initial.png',
|
||||
fullPage: true
|
||||
});
|
||||
|
||||
// Log any errors for debugging (but don't fail on WASM exceptions yet)
|
||||
const errors = testLogger.errors.filter(e =>
|
||||
!e.includes('favicon') &&
|
||||
!e.includes('SharedArrayBuffer')
|
||||
);
|
||||
|
||||
if (errors.length > 0) {
|
||||
console.log('Errors during initialization:', errors);
|
||||
}
|
||||
|
||||
// For now, we expect initialization errors due to incomplete port
|
||||
// The test passes if runtime initializes - we track errors for debugging
|
||||
});
|
||||
|
||||
test('canvas is properly sized', async ({ page }) => {
|
||||
await page.goto('/kicad/pcbnew.html');
|
||||
|
||||
// Wait for load
|
||||
await page.waitForFunction(() => {
|
||||
return (document.querySelector('#canvas') as HTMLElement)?.style.display === 'block';
|
||||
}, { timeout: 120000 });
|
||||
|
||||
// Wait for initial render
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Get canvas and verify it's sized properly
|
||||
const canvas = page.locator('#canvas');
|
||||
const box = await canvas.boundingBox();
|
||||
expect(box).toBeTruthy();
|
||||
expect(box!.width).toBeGreaterThan(100);
|
||||
expect(box!.height).toBeGreaterThan(100);
|
||||
|
||||
// Screenshot for visual inspection
|
||||
await page.screenshot({
|
||||
path: 'test-results/kicad-pcbnew-02-rendered.png',
|
||||
fullPage: true
|
||||
});
|
||||
});
|
||||
|
||||
// This test documents the current state - expect to fail until port is complete
|
||||
test.skip('loads without errors', async ({ page, testLogger }) => {
|
||||
await page.goto('/kicad/pcbnew.html');
|
||||
|
||||
await page.waitForFunction(() => {
|
||||
return (document.querySelector('#canvas') as HTMLElement)?.style.display === 'block';
|
||||
}, { timeout: 120000 });
|
||||
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Check for errors
|
||||
const errors = testLogger.errors.filter(e =>
|
||||
!e.includes('favicon') &&
|
||||
!e.includes('SharedArrayBuffer')
|
||||
);
|
||||
|
||||
// This will fail until KiCad WASM port is complete
|
||||
// Current known issue: WASM exception during wxWidgets initialization
|
||||
expect(errors).toHaveLength(0);
|
||||
});
|
||||
|
||||
});
|
||||
|
|
@ -19,10 +19,7 @@ test.describe('wxSplitterWindow & wxScrolledWindow Tests', () => {
|
|||
test('Splitter is visible with two panes', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/layout/layout_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.screenshot({ path: 'test-results/layout-02-splitter.png', fullPage: true });
|
||||
|
||||
|
|
@ -34,10 +31,7 @@ test.describe('wxSplitterWindow & wxScrolledWindow Tests', () => {
|
|||
test('Splitter sash can be dragged', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/layout/layout_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Get splitter sash from element registry
|
||||
const sash = await getSplitterSash(page);
|
||||
|
|
@ -60,10 +54,7 @@ test.describe('wxSplitterWindow & wxScrolledWindow Tests', () => {
|
|||
test('Scrolled windows show content', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/layout/layout_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
const box = await getCanvasBox(page);
|
||||
|
||||
|
|
@ -87,10 +78,7 @@ test.describe('wxSplitterWindow & wxScrolledWindow Tests', () => {
|
|||
test('Layout controls work together', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/layout/layout_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Get splitter sash from element registry
|
||||
const sash = await getSplitterSash(page);
|
||||
|
|
|
|||
|
|
@ -19,10 +19,7 @@ test.describe('wxListCtrl Virtual Mode Tests', () => {
|
|||
test('Virtual list displays 10000 items', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/listctrl/listctrl_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/listctrl-02-virtual.png', fullPage: true });
|
||||
|
|
@ -36,10 +33,7 @@ test.describe('wxListCtrl Virtual Mode Tests', () => {
|
|||
test('List columns are visible', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/listctrl/listctrl_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/listctrl-03-columns.png', fullPage: true });
|
||||
|
|
@ -51,10 +45,7 @@ test.describe('wxListCtrl Virtual Mode Tests', () => {
|
|||
test('Item selection works', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/listctrl/listctrl_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -74,10 +65,7 @@ test.describe('wxListCtrl Virtual Mode Tests', () => {
|
|||
test('Scroll to bottom works with large list', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/listctrl/listctrl_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,10 +20,7 @@ test.describe('wxFrame::Maximize() Tests', () => {
|
|||
test('Maximized window has reasonable size (not tiny)', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/maximize/maximize_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Wait for maximize to complete
|
||||
await page.waitForTimeout(500);
|
||||
|
|
@ -62,10 +59,7 @@ test.describe('wxFrame::Maximize() Tests', () => {
|
|||
test.skip('Display geometry is reported correctly', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/maximize/maximize_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
|
|
@ -91,10 +85,7 @@ test.describe('wxFrame::Maximize() Tests', () => {
|
|||
test('Canvas is properly sized after maximize', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/maximize/maximize_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,10 +21,7 @@ test.describe('wxMenuBar Tests', () => {
|
|||
test('Menu bar is visible', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/menu/menu_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.screenshot({ path: 'test-results/menu-02-menubar.png', fullPage: true });
|
||||
|
||||
|
|
@ -39,10 +36,7 @@ test.describe('wxMenuBar Tests', () => {
|
|||
test('File menu can be clicked', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/menu/menu_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Click on File menu using element registry
|
||||
const clicked = await clickMenuBarItem(page, 'File');
|
||||
|
|
@ -55,10 +49,7 @@ test.describe('wxMenuBar Tests', () => {
|
|||
test('Edit menu can be clicked', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/menu/menu_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Click on Edit menu using element registry
|
||||
const clicked = await clickMenuBarItem(page, 'Edit');
|
||||
|
|
@ -71,10 +62,7 @@ test.describe('wxMenuBar Tests', () => {
|
|||
test('Multiple menus can be accessed', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/menu/menu_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Verify all menu bar items are registered
|
||||
const menuItems = await findRenderedByType(page, 'menuitem', { subType: 'menubar' });
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { test, expect, MAIN_CANVAS, waitForApp, getCanvasBox } from './utils/fixtures';
|
||||
import { clickTab, clickByLabel, findByLabel, clickListItem } from './utils/element-tracker';
|
||||
import { clickTab, clickByLabel, selectComboItem } from './utils/element-tracker';
|
||||
|
||||
async function switchToOpenGLTab(page: any) {
|
||||
// Click OpenGL tab using element registry
|
||||
|
|
@ -13,20 +13,8 @@ async function switchToOpenGLTab(page: any) {
|
|||
|
||||
// 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);
|
||||
|
||||
// Click the test item in the dropdown list
|
||||
const itemClicked = await clickListItem(page, testName);
|
||||
if (!itemClicked) {
|
||||
// Fallback: try by label
|
||||
await clickByLabel(page, testName);
|
||||
}
|
||||
// Use combo helper to select from wxChoice dropdown
|
||||
await selectComboItem(page, testName);
|
||||
await page.waitForTimeout(500);
|
||||
}
|
||||
|
||||
|
|
@ -64,10 +52,9 @@ test.describe('OpenGL Tests', () => {
|
|||
|
||||
const testNames = [
|
||||
'Immediate Mode',
|
||||
'Matrix Ops',
|
||||
'Matrix Operations',
|
||||
'Vertex Arrays',
|
||||
'State Mgmt',
|
||||
'Texture Coords'
|
||||
'State Management'
|
||||
];
|
||||
|
||||
for (let i = 0; i < testNames.length; i++) {
|
||||
|
|
|
|||
|
|
@ -16,10 +16,7 @@ test.describe('wxOwnerDrawnComboBox Tests', () => {
|
|||
test('Layer combobox is visible', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/ownerdrawn/ownerdrawn_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/ownerdrawn-02-layer.png', fullPage: true });
|
||||
|
|
@ -31,10 +28,7 @@ test.describe('wxOwnerDrawnComboBox Tests', () => {
|
|||
test('Font combobox is visible', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/ownerdrawn/ownerdrawn_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/ownerdrawn-03-font.png', fullPage: true });
|
||||
|
|
@ -45,10 +39,7 @@ test.describe('wxOwnerDrawnComboBox Tests', () => {
|
|||
test('Icon combobox is visible', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/ownerdrawn/ownerdrawn_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/ownerdrawn-04-icon.png', fullPage: true });
|
||||
|
|
@ -59,10 +50,7 @@ test.describe('wxOwnerDrawnComboBox Tests', () => {
|
|||
test('Selection log panel exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/ownerdrawn/ownerdrawn_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/ownerdrawn-05-log.png', fullPage: true });
|
||||
|
|
|
|||
|
|
@ -18,10 +18,7 @@ test.describe('wxPicker Controls Tests', () => {
|
|||
test('Color pickers are visible', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/pickers/pickers_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/pickers-02-colors.png', fullPage: true });
|
||||
|
|
@ -35,10 +32,7 @@ test.describe('wxPicker Controls Tests', () => {
|
|||
test('Font picker is visible', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/pickers/pickers_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/pickers-03-font.png', fullPage: true });
|
||||
|
|
@ -50,10 +44,7 @@ test.describe('wxPicker Controls Tests', () => {
|
|||
test('Color preview panel exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/pickers/pickers_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/pickers-04-preview.png', fullPage: true });
|
||||
|
|
|
|||
|
|
@ -16,10 +16,7 @@ test.describe('wxPopupWindow Tests', () => {
|
|||
test('Status popup button exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/popup/popup_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/popup-02-status.png', fullPage: true });
|
||||
|
|
@ -31,10 +28,7 @@ test.describe('wxPopupWindow Tests', () => {
|
|||
test('Tool palette button exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/popup/popup_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/popup-03-palette.png', fullPage: true });
|
||||
|
|
@ -45,10 +39,7 @@ test.describe('wxPopupWindow Tests', () => {
|
|||
test('Color picker button exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/popup/popup_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/popup-04-color.png', fullPage: true });
|
||||
|
|
@ -59,10 +50,7 @@ test.describe('wxPopupWindow Tests', () => {
|
|||
test('Positioning buttons exist', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/popup/popup_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/popup-05-positioning.png', fullPage: true });
|
||||
|
|
@ -73,10 +61,7 @@ test.describe('wxPopupWindow Tests', () => {
|
|||
test('Event log panel exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/popup/popup_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/popup-06-log.png', fullPage: true });
|
||||
|
|
|
|||
|
|
@ -150,9 +150,8 @@ test.describe('wxPrinting Tests', () => {
|
|||
log.includes('PRINTOUT_CALLBACK')
|
||||
);
|
||||
|
||||
// Log what callbacks we found (for debugging)
|
||||
console.log('Printout callbacks found:', callbacks.length);
|
||||
callbacks.forEach(cb => console.log(' -', cb));
|
||||
// Verify printout callbacks were triggered
|
||||
expect(callbacks.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test('No JavaScript errors during print operations', async ({ page, testLogger }) => {
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@ test.describe('wxPrintPreview Tests', () => {
|
|||
test('Preview area displays schematic-like content', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/printpreview/printpreview_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
|
|
@ -31,10 +28,7 @@ test.describe('wxPrintPreview Tests', () => {
|
|||
test('Print Preview button opens preview frame', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/printpreview/printpreview_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -49,10 +43,7 @@ test.describe('wxPrintPreview Tests', () => {
|
|||
test('Page Setup button opens dialog', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/printpreview/printpreview_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -67,10 +58,7 @@ test.describe('wxPrintPreview Tests', () => {
|
|||
test('Print settings display shows current configuration', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/printpreview/printpreview_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,7 @@ test.describe('wxPropertyGrid Tests', () => {
|
|||
test('PropertyGrid displays properties with categories', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/propgrid/propgrid_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/propgrid-02-categories.png', fullPage: true });
|
||||
|
|
@ -37,10 +34,7 @@ test.describe('wxPropertyGrid Tests', () => {
|
|||
test('PropertyGrid selection events fire', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/propgrid/propgrid_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Click on a property row using element registry
|
||||
const clicked = await clickPropertyRow(page, 'Reference');
|
||||
|
|
@ -59,10 +53,7 @@ test.describe('wxPropertyGrid Tests', () => {
|
|||
test('PropertyGridManager has multiple pages', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/propgrid/propgrid_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +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';
|
||||
import { clickByLabel, clickComboButton, selectComboItem, clickListboxItem, clickTreeItem } from './utils/element-tracker';
|
||||
|
||||
test.describe('Specialized wxWidgets Controls Tests', () => {
|
||||
|
||||
|
|
@ -17,10 +17,7 @@ test.describe('Specialized wxWidgets Controls Tests', () => {
|
|||
test('wxTreebook displays tree with pages', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/specialized/specialized_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
|
|
@ -28,18 +25,19 @@ test.describe('Specialized wxWidgets Controls Tests', () => {
|
|||
await page.screenshot({ path: 'test-results/specialized-02-treebook-initial.png', fullPage: true });
|
||||
});
|
||||
|
||||
test('wxTreebook can navigate to sub-pages', async ({ page, testLogger }) => {
|
||||
test('wxTreebook can navigate between pages', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/specialized/specialized_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
// Click on Colors sub-page in tree using element registry
|
||||
await clickByLabel(page, 'Colors');
|
||||
// Click on Display page using element registry
|
||||
await clickTreeItem(page, 'Display');
|
||||
await page.waitForTimeout(200);
|
||||
|
||||
// Click on Printing page using element registry
|
||||
await clickTreeItem(page, 'Printing');
|
||||
await page.waitForTimeout(200);
|
||||
|
||||
await page.screenshot({ path: 'test-results/specialized-03-treebook-subpage.png', fullPage: true });
|
||||
|
|
@ -48,15 +46,12 @@ test.describe('Specialized wxWidgets Controls Tests', () => {
|
|||
test('wxTreebook can expand tree nodes', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/specialized/specialized_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
// Click on Editing page using element registry
|
||||
await clickByLabel(page, 'Editing');
|
||||
await clickTreeItem(page, 'Editing');
|
||||
await page.waitForTimeout(200);
|
||||
|
||||
await page.screenshot({ path: 'test-results/specialized-04-treebook-expand.png', fullPage: true });
|
||||
|
|
@ -65,10 +60,7 @@ test.describe('Specialized wxWidgets Controls Tests', () => {
|
|||
test('wxBitmapComboBox displays layer swatches', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/specialized/specialized_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -83,10 +75,7 @@ test.describe('Specialized wxWidgets Controls Tests', () => {
|
|||
test('wxBitmapComboBox can select different layer', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/specialized/specialized_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -101,10 +90,7 @@ test.describe('Specialized wxWidgets Controls Tests', () => {
|
|||
test('wxRearrangeCtrl displays layer order', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/specialized/specialized_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
|
|
@ -115,10 +101,7 @@ test.describe('Specialized wxWidgets Controls Tests', () => {
|
|||
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) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,32 +19,13 @@ test.describe('Thread Pool Deadlock Tests', () => {
|
|||
|
||||
await page.screenshot({ path: 'test-results/threadpool-01-loaded.png', fullPage: true });
|
||||
|
||||
// Check console for hardware_concurrency value
|
||||
const hardwareConcurrencyLog = testLogger.consoleLogs.find(log =>
|
||||
log.includes('[THREADPOOL] hardware_concurrency:')
|
||||
);
|
||||
if (hardwareConcurrencyLog) {
|
||||
console.log('Detected:', hardwareConcurrencyLog);
|
||||
}
|
||||
|
||||
// Check for success marker - all threads created and joined
|
||||
const success = testLogger.consoleLogs.some(log =>
|
||||
log.includes('[THREADPOOL] SUCCESS')
|
||||
);
|
||||
|
||||
// Check for blocking warning (indicates potential deadlock situation)
|
||||
const blockingWarning = testLogger.consoleLogs.some(log =>
|
||||
log.includes('Blocking on the main thread is very dangerous')
|
||||
);
|
||||
|
||||
expect(loaded, 'App should load without deadlock').toBe(true);
|
||||
expect(success, 'All threads should complete successfully').toBe(true);
|
||||
|
||||
// Log blocking warning status (informational, doesn't fail test)
|
||||
if (blockingWarning) {
|
||||
console.log('Warning: Blocking on main thread detected (thread creation may have triggered worker spawn)');
|
||||
}
|
||||
|
||||
expect(testLogger.errors.filter(e => !e.includes('favicon'))).toHaveLength(0);
|
||||
});
|
||||
|
||||
|
|
@ -52,37 +33,24 @@ test.describe('Thread Pool Deadlock Tests', () => {
|
|||
await page.goto('/standalone/threadpool/threadpool_test.html');
|
||||
|
||||
const loaded = await tryLoadApp(page, 30000);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load without deadlock').toBe(true);
|
||||
|
||||
// Extract hardware_concurrency from logs
|
||||
const hwLog = testLogger.consoleLogs.find(log =>
|
||||
log.includes('[THREADPOOL] hardware_concurrency:')
|
||||
);
|
||||
expect(hwLog, 'Should find hardware_concurrency log').toBeDefined();
|
||||
|
||||
if (!hwLog) {
|
||||
console.log('Could not find hardware_concurrency log');
|
||||
return;
|
||||
}
|
||||
const match = hwLog!.match(/hardware_concurrency:\s*(\d+)/);
|
||||
expect(match, 'Should parse hardware_concurrency value').not.toBeNull();
|
||||
|
||||
const match = hwLog.match(/hardware_concurrency:\s*(\d+)/);
|
||||
if (!match) {
|
||||
console.log('Could not parse hardware_concurrency value');
|
||||
return;
|
||||
}
|
||||
|
||||
const expectedThreads = parseInt(match[1], 10);
|
||||
console.log(`Expected ${expectedThreads} threads based on hardware_concurrency`);
|
||||
const expectedThreads = parseInt(match![1], 10);
|
||||
|
||||
// Count "Thread X started" messages
|
||||
const threadStartedLogs = testLogger.consoleLogs.filter(log =>
|
||||
log.includes('[THREADPOOL] Thread') && log.includes('started')
|
||||
);
|
||||
|
||||
console.log(`Found ${threadStartedLogs.length} "Thread started" messages`);
|
||||
|
||||
// All threads should have started
|
||||
expect(threadStartedLogs.length).toBe(expectedThreads);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@ test.describe('wxTimer Tests', () => {
|
|||
test('Slow timer can be started and stopped', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/timer/timer_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
@ -61,10 +58,7 @@ test.describe('wxTimer Tests', () => {
|
|||
test('Fast timer can be started and updates gauge', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/timer/timer_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
@ -98,10 +92,7 @@ test.describe('wxTimer Tests', () => {
|
|||
test('Reset counters button works', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/timer/timer_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await waitForRegistry(page);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,7 @@ test.describe('wxToolBar & wxStatusBar Tests', () => {
|
|||
test('Toolbar buttons are visible', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/toolbar/toolbar_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.screenshot({ path: 'test-results/toolbar-02-buttons.png', fullPage: true });
|
||||
|
||||
|
|
@ -34,10 +31,7 @@ test.describe('wxToolBar & wxStatusBar Tests', () => {
|
|||
test('New tool button can be clicked', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/toolbar/toolbar_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Click New button using element registry
|
||||
const clicked = await clickToolbarTool(page, 'New');
|
||||
|
|
@ -50,10 +44,7 @@ test.describe('wxToolBar & wxStatusBar Tests', () => {
|
|||
test('Zoom tools can be clicked', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/toolbar/toolbar_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Click Zoom In using element registry
|
||||
const zoomInClicked = await clickToolbarTool(page, 'Zoom In');
|
||||
|
|
@ -71,10 +62,7 @@ test.describe('wxToolBar & wxStatusBar Tests', () => {
|
|||
test('Toggle tool changes state', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/toolbar/toolbar_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Click Toggle button using element registry
|
||||
const toggleClicked1 = await clickToolbarTool(page, 'Toggle');
|
||||
|
|
@ -94,10 +82,7 @@ test.describe('wxToolBar & wxStatusBar Tests', () => {
|
|||
test('Status bar shows messages', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/toolbar/toolbar_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.screenshot({ path: 'test-results/toolbar-07-statusbar.png', fullPage: true });
|
||||
|
||||
|
|
@ -109,10 +94,7 @@ test.describe('wxToolBar & wxStatusBar Tests', () => {
|
|||
test('All toolbar buttons accessible', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/toolbar/toolbar_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Verify all tools are registered
|
||||
const tools = await findRenderedByType(page, 'tool');
|
||||
|
|
|
|||
|
|
@ -363,6 +363,48 @@ export async function findRenderedByType(
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find rendered element by tooltip
|
||||
*/
|
||||
export async function findByTooltip(
|
||||
page: Page,
|
||||
tooltip: string,
|
||||
options: RenderedFindOptions = {}
|
||||
): Promise<WxRenderedElement | null> {
|
||||
const elements = await page.evaluate(
|
||||
([tooltip, opts]: [string, RenderedFindOptions]) => {
|
||||
const registry = window.wxElementRegistry;
|
||||
if (!registry || !registry.findAllRendered) return [];
|
||||
// Find all rendered elements and filter by tooltip
|
||||
const all = registry.findAllRendered(opts);
|
||||
return all.filter(e => e.tooltip && e.tooltip.includes(tooltip));
|
||||
},
|
||||
[tooltip, options] as [string, RenderedFindOptions]
|
||||
);
|
||||
return elements.length > 0 ? elements[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Click on a rendered element by tooltip
|
||||
*/
|
||||
export async function clickByTooltip(
|
||||
page: Page,
|
||||
tooltip: string,
|
||||
options: RenderedFindOptions = {}
|
||||
): Promise<boolean> {
|
||||
const element = await findByTooltip(page, tooltip, options);
|
||||
if (!element) {
|
||||
console.warn(`Element with tooltip "${tooltip}" not found`);
|
||||
return false;
|
||||
}
|
||||
if (!element.enabled) {
|
||||
console.warn(`Element with tooltip "${tooltip}" is disabled`);
|
||||
return false;
|
||||
}
|
||||
await page.mouse.click(element.centerX, element.centerY);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Click on a toolbar tool by label or tooltip
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -16,10 +16,7 @@ test.describe('wxValidator Tests', () => {
|
|||
test('Text validator input exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/validators/validators_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/validators-02-text.png', fullPage: true });
|
||||
|
|
@ -31,10 +28,7 @@ test.describe('wxValidator Tests', () => {
|
|||
test('Integer validator input exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/validators/validators_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/validators-03-integer.png', fullPage: true });
|
||||
|
|
@ -45,10 +39,7 @@ test.describe('wxValidator Tests', () => {
|
|||
test('Floating point validator input exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/validators/validators_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/validators-04-float.png', fullPage: true });
|
||||
|
|
@ -59,10 +50,7 @@ test.describe('wxValidator Tests', () => {
|
|||
test('Custom net name validator input exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/validators/validators_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/validators-05-netname.png', fullPage: true });
|
||||
|
|
@ -73,10 +61,7 @@ test.describe('wxValidator Tests', () => {
|
|||
test('Validate all button exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/validators/validators_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/validators-06-button.png', fullPage: true });
|
||||
|
|
|
|||
|
|
@ -16,10 +16,7 @@ test.describe('WASM Edge Cases Tests', () => {
|
|||
test('File system test button exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/wasmedge/wasmedge_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/wasmedge-02-filesystem.png', fullPage: true });
|
||||
|
|
@ -31,10 +28,7 @@ test.describe('WASM Edge Cases Tests', () => {
|
|||
test('Threading test button exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/wasmedge/wasmedge_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/wasmedge-03-threading.png', fullPage: true });
|
||||
|
|
@ -45,10 +39,7 @@ test.describe('WASM Edge Cases Tests', () => {
|
|||
test('Font enumeration test button exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/wasmedge/wasmedge_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/wasmedge-04-fonts.png', fullPage: true });
|
||||
|
|
@ -59,10 +50,7 @@ test.describe('WASM Edge Cases Tests', () => {
|
|||
test('Clipboard test button exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/wasmedge/wasmedge_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/wasmedge-05-clipboard.png', fullPage: true });
|
||||
|
|
@ -73,10 +61,7 @@ test.describe('WASM Edge Cases Tests', () => {
|
|||
test('Memory test button exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/wasmedge/wasmedge_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/wasmedge-06-memory.png', fullPage: true });
|
||||
|
|
@ -87,10 +72,7 @@ test.describe('WASM Edge Cases Tests', () => {
|
|||
test('Run all tests button exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/wasmedge/wasmedge_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/wasmedge-07-runall.png', fullPage: true });
|
||||
|
|
@ -101,10 +83,7 @@ test.describe('WASM Edge Cases Tests', () => {
|
|||
test('Test results log exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/wasmedge/wasmedge_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/wasmedge-08-log.png', fullPage: true });
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@ test.describe('wxWizard Tests', () => {
|
|||
test('Wizard dialog can be launched', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/wizard/wizard_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -35,10 +32,7 @@ test.describe('wxWizard Tests', () => {
|
|||
test('Wizard can navigate to next page', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/wizard/wizard_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -58,10 +52,7 @@ test.describe('wxWizard Tests', () => {
|
|||
test('Wizard can navigate back', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/wizard/wizard_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
@ -86,10 +77,7 @@ test.describe('wxWizard Tests', () => {
|
|||
test('Wizard can be cancelled', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/wizard/wizard_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { Page } from '@playwright/test';
|
|||
import {
|
||||
clickTab,
|
||||
clickByLabel,
|
||||
clickMenuBarItem,
|
||||
clickSlider,
|
||||
dragSliderTo,
|
||||
findSliderTrack,
|
||||
|
|
@ -89,8 +90,6 @@ test.describe('wxWidgets WASM - Diagnostics', () => {
|
|||
await page.screenshot({ path: 'test-results/03-after-load.png', fullPage: true });
|
||||
|
||||
// === TAB 1: Controls ===
|
||||
console.log('--- Testing Controls Tab ---');
|
||||
|
||||
// Click Controls tab using element registry
|
||||
await clickTab(page, 'Controls');
|
||||
await page.waitForTimeout(300);
|
||||
|
|
@ -125,8 +124,6 @@ test.describe('wxWidgets WASM - Diagnostics', () => {
|
|||
await page.screenshot({ path: 'test-results/04-controls-tab.png', fullPage: true });
|
||||
|
||||
// === TAB 2: Text Input ===
|
||||
console.log('--- Testing Text Input Tab ---');
|
||||
|
||||
// Click Text Input tab using element registry
|
||||
await clickTab(page, 'Text Input');
|
||||
await page.waitForTimeout(500);
|
||||
|
|
@ -152,8 +149,6 @@ test.describe('wxWidgets WASM - Diagnostics', () => {
|
|||
await page.screenshot({ path: 'test-results/06-text-input-typed.png', fullPage: true });
|
||||
|
||||
// === TAB 3: Drawing ===
|
||||
console.log('--- Testing Drawing Tab ---');
|
||||
|
||||
// Click Drawing tab using element registry
|
||||
await clickTab(page, 'Drawing');
|
||||
await page.waitForTimeout(500);
|
||||
|
|
@ -174,8 +169,6 @@ test.describe('wxWidgets WASM - Diagnostics', () => {
|
|||
await page.screenshot({ path: 'test-results/08-drawing-done.png', fullPage: true });
|
||||
|
||||
// === TAB 4: Lists ===
|
||||
console.log('--- Testing Lists Tab ---');
|
||||
|
||||
// Click Lists tab using element registry
|
||||
await clickTab(page, 'Lists');
|
||||
await page.waitForTimeout(500);
|
||||
|
|
@ -191,8 +184,6 @@ test.describe('wxWidgets WASM - Diagnostics', () => {
|
|||
await page.screenshot({ path: 'test-results/10-lists-clicked.png', fullPage: true });
|
||||
|
||||
// Test wxChoice dropdown using element tracking
|
||||
console.log('--- Testing wxChoice Dropdown ---');
|
||||
|
||||
// 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);
|
||||
|
|
@ -222,8 +213,6 @@ test.describe('wxWidgets WASM - Diagnostics', () => {
|
|||
await page.waitForTimeout(300);
|
||||
|
||||
// === TAB 5: OpenGL ===
|
||||
console.log('--- Testing OpenGL Tab ---');
|
||||
|
||||
// Click OpenGL tab using element registry
|
||||
await clickTab(page, 'OpenGL');
|
||||
await page.waitForTimeout(1000); // Give GL time to initialize
|
||||
|
|
@ -242,10 +231,8 @@ test.describe('wxWidgets WASM - Diagnostics', () => {
|
|||
await page.screenshot({ path: 'test-results/15-opengl-tests.png', fullPage: true });
|
||||
|
||||
// === Menu interaction ===
|
||||
console.log('--- Testing Menus ---');
|
||||
|
||||
// Click File menu using element registry
|
||||
await clickByLabel(page, 'File');
|
||||
await clickMenuBarItem(page, 'File');
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/11-file-menu.png', fullPage: true });
|
||||
|
||||
|
|
@ -254,7 +241,7 @@ test.describe('wxWidgets WASM - Diagnostics', () => {
|
|||
await page.waitForTimeout(300);
|
||||
|
||||
// Click Help menu using element registry
|
||||
await clickByLabel(page, 'Help');
|
||||
await clickMenuBarItem(page, 'Help');
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/12-help-menu.png', fullPage: true });
|
||||
|
||||
|
|
@ -263,8 +250,6 @@ test.describe('wxWidgets WASM - Diagnostics', () => {
|
|||
await page.waitForTimeout(300);
|
||||
|
||||
// === Rapid interactions ===
|
||||
console.log('--- Rapid interactions ---');
|
||||
|
||||
// Click rapidly on various areas
|
||||
for (let i = 0; i < 30; i++) {
|
||||
const x = 50 + (i * 37) % 400;
|
||||
|
|
@ -274,24 +259,6 @@ test.describe('wxWidgets WASM - Diagnostics', () => {
|
|||
}
|
||||
|
||||
await page.screenshot({ path: 'test-results/13-final.png', fullPage: true });
|
||||
|
||||
// Print all logs
|
||||
console.log('\n=== ALL CONSOLE LOGS ===');
|
||||
testLogger.consoleLogs.forEach(log => console.log(log));
|
||||
console.log('\n=== ALL ERRORS ===');
|
||||
testLogger.errors.forEach(err => console.log(err));
|
||||
console.log('========================\n');
|
||||
|
||||
// Fail test if there are critical errors
|
||||
const criticalErrors = testLogger.errors.filter(e =>
|
||||
!e.includes('SharedArrayBuffer') &&
|
||||
!e.includes('cross-origin')
|
||||
);
|
||||
|
||||
if (criticalErrors.length > 0) {
|
||||
console.log('\n!!! CRITICAL ERRORS FOUND !!!');
|
||||
criticalErrors.forEach(e => console.log(e));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -604,8 +571,6 @@ test.describe('wxWidgets WASM - OpenGL', () => {
|
|||
};
|
||||
});
|
||||
|
||||
console.log('GL Canvas Debug Info:', JSON.stringify(glCanvasInfo, null, 2));
|
||||
|
||||
// Take screenshot of GL canvas
|
||||
const screenshot = await page.screenshot();
|
||||
expect(screenshot.length).toBeGreaterThan(0);
|
||||
|
|
@ -645,7 +610,6 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
|
|||
zIndex: window.getComputedStyle(glCanvas).zIndex
|
||||
};
|
||||
});
|
||||
console.log('GL Canvas on OpenGL tab:', JSON.stringify(glCanvasBefore));
|
||||
|
||||
// Step 2: Switch to Controls tab using element registry
|
||||
await clickTab(page, 'Controls');
|
||||
|
|
@ -665,7 +629,6 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
|
|||
zIndex: window.getComputedStyle(glCanvas).zIndex
|
||||
};
|
||||
});
|
||||
console.log('GL Canvas after switching to Controls:', JSON.stringify(glCanvasAfter));
|
||||
|
||||
// Step 3: Switch to Drawing tab using element registry
|
||||
await clickTab(page, 'Drawing');
|
||||
|
|
@ -680,11 +643,8 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
|
|||
await page.screenshot({ path: 'test-results/glcanvas-04-on-lists-tab.png', fullPage: true });
|
||||
|
||||
// GL canvas should be hidden (display: none) when not on OpenGL tab
|
||||
// This assertion will fail before the fix and pass after
|
||||
if (glCanvasAfter.exists) {
|
||||
console.log(`GL Canvas display after tab switch: ${glCanvasAfter.display}`);
|
||||
// Uncomment after fix is applied:
|
||||
// expect(glCanvasAfter.display).toBe('none');
|
||||
expect(glCanvasAfter.display).toBe('none');
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -696,36 +656,13 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
|
|||
const box = await canvas.boundingBox();
|
||||
if (!box) throw new Error('Canvas not found');
|
||||
|
||||
console.log('Canvas bounding box:', JSON.stringify(box));
|
||||
|
||||
// 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 });
|
||||
|
||||
// Debug: Log the event log contents to understand what events are being received
|
||||
const eventLogBefore = await page.evaluate(() => {
|
||||
// Find all text in event log listbox area
|
||||
const canvas = document.getElementById('canvas');
|
||||
return canvas ? 'Canvas exists' : 'No canvas';
|
||||
});
|
||||
console.log('Event log check:', eventLogBefore);
|
||||
|
||||
// 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(() => {
|
||||
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
|
||||
}));
|
||||
});
|
||||
console.log('Windows BEFORE click:', JSON.stringify(windowsBefore));
|
||||
|
||||
// Open dropdown using element tracking
|
||||
const dropdownClicked = await clickComboButton(page);
|
||||
expect(dropdownClicked, 'Should be able to click dropdown on OpenGL tab').toBe(true);
|
||||
|
|
@ -733,27 +670,6 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
|
|||
|
||||
await page.screenshot({ path: 'test-results/zorder-02-dropdown-clicked.png', fullPage: true });
|
||||
|
||||
// Check what windows exist 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));
|
||||
|
||||
// Check for any logged events
|
||||
const clickEvents = testLogger.consoleLogs.filter(log =>
|
||||
log.includes('GL Test selected') ||
|
||||
log.includes('clicked') ||
|
||||
log.includes('Choice')
|
||||
);
|
||||
console.log('Click-related events in logs:', clickEvents);
|
||||
|
||||
// Check z-index values
|
||||
const zIndexInfo = await page.evaluate(() => {
|
||||
const glCanvas = document.querySelector('[id^="glcanvas-"]') as HTMLCanvasElement;
|
||||
|
|
@ -790,8 +706,6 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
|
|||
return result;
|
||||
});
|
||||
|
||||
console.log('Z-Index info:', JSON.stringify(zIndexInfo, null, 2));
|
||||
|
||||
// Step 3: Close the dropdown using Escape
|
||||
await page.keyboard.press('Escape');
|
||||
await page.waitForTimeout(300);
|
||||
|
|
@ -830,7 +744,12 @@ test.describe('wxWidgets WASM - Canvas Z-Ordering and Visibility', () => {
|
|||
return window.getComputedStyle(glCanvas).display;
|
||||
});
|
||||
|
||||
console.log(`Tab: ${tabName}, GL Canvas display: ${glVisible}`);
|
||||
// GL canvas should only be visible on OpenGL tab
|
||||
if (tabName === 'OpenGL') {
|
||||
expect(glVisible).toBe('block');
|
||||
} else {
|
||||
expect(glVisible).toBe('none');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,10 +16,7 @@ test.describe('wxXmlDocument Tests', () => {
|
|||
test('Sample XML input exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/xml/xml_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/xml-02-input.png', fullPage: true });
|
||||
|
|
@ -31,10 +28,7 @@ test.describe('wxXmlDocument Tests', () => {
|
|||
test('Parse button exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/xml/xml_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/xml-03-parse.png', fullPage: true });
|
||||
|
|
@ -45,10 +39,7 @@ test.describe('wxXmlDocument Tests', () => {
|
|||
test('Traverse button exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/xml/xml_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/xml-04-traverse.png', fullPage: true });
|
||||
|
|
@ -59,10 +50,7 @@ test.describe('wxXmlDocument Tests', () => {
|
|||
test('Create XML button exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/xml/xml_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/xml-05-create.png', fullPage: true });
|
||||
|
|
@ -73,10 +61,7 @@ test.describe('wxXmlDocument Tests', () => {
|
|||
test('Results output panel exists', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/xml/xml_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
if (!loaded) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
await page.waitForTimeout(500);
|
||||
await page.screenshot({ path: 'test-results/xml-06-results.png', fullPage: true });
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
import { defineConfig, devices } from '@playwright/test';
|
||||
|
||||
/**
|
||||
* Playwright config for button-finder utility ONLY.
|
||||
* This config does NOT exclude button-finder.spec.ts like the main config.
|
||||
*/
|
||||
export default defineConfig({
|
||||
testDir: './e2e',
|
||||
fullyParallel: false,
|
||||
retries: 0,
|
||||
workers: 1,
|
||||
reporter: 'list',
|
||||
timeout: 300000, // 5 minute timeout for scanning
|
||||
|
||||
// Only include the button-finder test
|
||||
testMatch: '**/button-finder.spec.ts',
|
||||
|
||||
use: {
|
||||
baseURL: 'http://localhost:8080',
|
||||
trace: 'off',
|
||||
},
|
||||
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
],
|
||||
|
||||
webServer: {
|
||||
command: 'npx serve apps -p 8080',
|
||||
port: 8080,
|
||||
reuseExistingServer: true,
|
||||
},
|
||||
});
|
||||
|
|
@ -55,9 +55,6 @@ export default defineConfig({
|
|||
reporter: 'html',
|
||||
timeout: 60000, // WASM can be slow to load
|
||||
|
||||
// Exclude button-finder from regular test runs - it's a utility, not a test
|
||||
testIgnore: ['**/button-finder.spec.ts'],
|
||||
|
||||
use: {
|
||||
baseURL: `http://localhost:${port}`,
|
||||
trace: 'on-first-retry',
|
||||
|
|
|
|||
Loading…
Reference in a new issue