Add earlysize test for GetClientSize() before Show()

Test infrastructure to verify window sizing works correctly
when GetClientSize() is called before the window is shown.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Viktor Vaczi 2025-12-14 16:10:08 +01:00
commit 838d8cb846
3 changed files with 242 additions and 2 deletions

View file

@ -0,0 +1,77 @@
// Early Size Test - Verifies GetClientSize() returns reasonable values before Show()
// This reproduces KiCad's pattern where GetClientSize() is called in the constructor.
import { test, expect, tryLoadApp } from './utils/fixtures';
test.describe('Early GetClientSize() Tests', () => {
test('Early size test app loads successfully', async ({ page, testLogger }) => {
await page.goto('/standalone/earlysize/earlysize_test.html');
const loaded = await tryLoadApp(page);
await page.screenshot({ path: 'test-results/earlysize-01-loaded.png', fullPage: true });
const hasStartup = testLogger.consoleLogs.some(l => l.includes('[EARLYSIZE_TEST] Early size test app started'));
expect(loaded, 'Early size app should load').toBe(true);
expect(hasStartup, 'Startup log should be present').toBe(true);
expect(testLogger.errors.filter(e => !e.includes('favicon'))).toHaveLength(0);
});
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;
}
// Wait for the app to finish initialization
await page.waitForTimeout(500);
await page.screenshot({ path: 'test-results/earlysize-02-result.png', fullPage: true });
// Check for early client size log
const clientSizeLogs = testLogger.consoleLogs.filter(l => l.includes('[EARLYSIZE_TEST] Early client size:'));
expect(clientSizeLogs.length).toBeGreaterThan(0);
// Parse the early client size
const clientSizeLog = clientSizeLogs[0];
const clientMatch = clientSizeLog.match(/Early client size: (\d+)x(\d+)/);
expect(clientMatch, 'Client size log should contain dimensions').not.toBeNull();
if (clientMatch) {
const clientWidth = parseInt(clientMatch[1]);
const clientHeight = parseInt(clientMatch[2]);
// The key assertion: early client size should NOT be 20x20 or similar tiny values
// This is the bug we're testing for - KiCad gets 20x20 here
expect(clientWidth, `Early client width should be > 100 (got ${clientWidth})`).toBeGreaterThan(100);
expect(clientHeight, `Early client height should be > 100 (got ${clientHeight})`).toBeGreaterThan(100);
}
// Check for early frame size log
const frameSizeLogs = testLogger.consoleLogs.filter(l => l.includes('[EARLYSIZE_TEST] Early frame size:'));
expect(frameSizeLogs.length).toBeGreaterThan(0);
// Parse the early frame size
const frameSizeLog = frameSizeLogs[0];
const frameMatch = frameSizeLog.match(/Early frame size: (\d+)x(\d+)/);
expect(frameMatch, 'Frame size log should contain dimensions').not.toBeNull();
if (frameMatch) {
const frameWidth = parseInt(frameMatch[1]);
const frameHeight = parseInt(frameMatch[2]);
// Frame size should also be reasonable
expect(frameWidth, `Early frame width should be > 100 (got ${frameWidth})`).toBeGreaterThan(100);
expect(frameHeight, `Early frame height should be > 100 (got ${frameHeight})`).toBeGreaterThan(100);
}
// Check for PASS/FAIL result
const passLog = testLogger.consoleLogs.some(l => l.includes('[EARLYSIZE_TEST] PASS'));
const failLog = testLogger.consoleLogs.some(l => l.includes('[EARLYSIZE_TEST] FAIL'));
expect(failLog, 'Should not have FAIL log').toBe(false);
expect(passLog, 'Should have PASS log').toBe(true);
});
});

View file

@ -131,7 +131,8 @@ all: minimal_test.html \
$(S)/textdecor/textdecor_test.html \
$(S)/bitmask/bitmask_test.html \
$(S)/regions/regions_test.html \
$(S)/maximize/maximize_test.html
$(S)/maximize/maximize_test.html \
$(S)/earlysize/earlysize_test.html
# Main test app (uses GL)
minimal_test.o: minimal_test.cpp
@ -413,6 +414,13 @@ $(S)/maximize/maximize_test.o: $(S)/maximize/maximize_test.cpp
$(S)/maximize/maximize_test.html: $(S)/maximize/maximize_test.o
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Early size test (no GL) - tests GetClientSize() before Show()
$(S)/earlysize/earlysize_test.o: $(S)/earlysize/earlysize_test.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
$(S)/earlysize/earlysize_test.html: $(S)/earlysize/earlysize_test.o
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
# Convenience targets
menu: $(S)/menu/menu_test.html
clipboard: $(S)/clipboard/clipboard_test.html
@ -453,9 +461,10 @@ textdecor: $(S)/textdecor/textdecor_test.html
bitmask: $(S)/bitmask/bitmask_test.html
regions: $(S)/regions/regions_test.html
maximize: $(S)/maximize/maximize_test.html
earlysize: $(S)/earlysize/earlysize_test.html
clean:
rm -f minimal_test.o minimal_test.html minimal_test.js minimal_test.wasm
rm -f $(S)/*/*.o $(S)/*/*.html $(S)/*/*.js $(S)/*/*.wasm
.PHONY: all clean menu clipboard filedialog layout aui toolbar grid dialog timer tree dataview htmlwin stc print dnd propgrid pickers collapsible listctrl infobar dataviewvirtual auinotebook wizard gridedit calendar gridrenderers printpreview bitmapbuttons specialized validators ownerdrawn popup xml wasmedge fontenum textdecor bitmask regions maximize
.PHONY: all clean menu clipboard filedialog layout aui toolbar grid dialog timer tree dataview htmlwin stc print dnd propgrid pickers collapsible listctrl infobar dataviewvirtual auinotebook wizard gridedit calendar gridrenderers printpreview bitmapbuttons specialized validators ownerdrawn popup xml wasmedge fontenum textdecor bitmask regions maximize earlysize

View file

@ -0,0 +1,154 @@
// Early Size Test - Reproduces KiCad's pattern of calling GetClientSize() before Show()
// This tests whether wxWidgets WASM port returns correct sizes during frame construction.
//
// KiCad's EDA_BASE_FRAME::commonInit() does:
// m_frameSize = defaultSize(); // 1280x720
// GetClientSize(&m_frameSize.x, &m_frameSize.y); // Overwrites with actual client size
//
// In WASM, GetClientSize() returns 20x20 if called before the frame is shown/sized.
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/display.h"
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif
class EarlySizeTestApp : public wxApp
{
public:
virtual bool OnInit() override;
};
class EarlySizeTestFrame : public wxFrame
{
public:
EarlySizeTestFrame();
private:
wxSize m_earlyClientSize; // Captured before Show()
wxSize m_earlyFrameSize;
wxStaticText* m_resultLabel;
void OnPaint(wxPaintEvent& evt);
wxDECLARE_EVENT_TABLE();
};
wxBEGIN_EVENT_TABLE(EarlySizeTestFrame, wxFrame)
EVT_PAINT(EarlySizeTestFrame::OnPaint)
wxEND_EVENT_TABLE()
wxIMPLEMENT_APP(EarlySizeTestApp);
bool EarlySizeTestApp::OnInit()
{
if (!wxApp::OnInit())
return false;
// Create frame with wxDefaultSize (like KiCad does)
EarlySizeTestFrame* frame = new EarlySizeTestFrame();
// Show the frame (this is where sizing should happen)
frame->Show(true);
return true;
}
EarlySizeTestFrame::EarlySizeTestFrame()
: wxFrame(nullptr, wxID_ANY, "Early Size Test",
wxDefaultPosition, wxDefaultSize) // No explicit size!
{
// === THIS IS THE KEY TEST ===
// KiCad calls GetClientSize() in commonInit(), BEFORE Show()
// In WASM, this should NOT return 20x20
GetClientSize(&m_earlyClientSize.x, &m_earlyClientSize.y);
m_earlyFrameSize = GetSize();
#ifdef __EMSCRIPTEN__
EM_ASM({
console.log('[EARLYSIZE_TEST] Constructor called - BEFORE Show()');
console.log('[EARLYSIZE_TEST] Early client size: ' + $0 + 'x' + $1);
console.log('[EARLYSIZE_TEST] Early frame size: ' + $2 + 'x' + $3);
}, m_earlyClientSize.x, m_earlyClientSize.y,
m_earlyFrameSize.x, m_earlyFrameSize.y);
#endif
// Create UI
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
wxStaticText* desc = new wxStaticText(this, wxID_ANY,
"Early Size Test\n\n"
"This test reproduces KiCad's pattern:\n"
"- Frame created with wxDefaultSize\n"
"- GetClientSize() called in constructor BEFORE Show()\n"
"- Size should NOT be 20x20!");
mainSizer->Add(desc, 0, wxALL, 10);
// Results
wxStaticBoxSizer* resultBox = new wxStaticBoxSizer(wxVERTICAL, this, "Results (from constructor)");
wxString resultText = wxString::Format(
"Early Client Size: %dx%d\nEarly Frame Size: %dx%d",
m_earlyClientSize.x, m_earlyClientSize.y,
m_earlyFrameSize.x, m_earlyFrameSize.y);
m_resultLabel = new wxStaticText(this, wxID_ANY, resultText);
resultBox->Add(m_resultLabel, 0, wxALL, 5);
mainSizer->Add(resultBox, 0, wxEXPAND | wxALL, 10);
SetSizer(mainSizer);
// Maximize like KiCad does
Maximize(true);
#ifdef __EMSCRIPTEN__
EM_ASM({
console.log('[EARLYSIZE_TEST] Early size test app started');
});
#endif
}
void EarlySizeTestFrame::OnPaint(wxPaintEvent& evt)
{
evt.Skip();
// Log final result after first paint
static bool logged = false;
if (!logged) {
logged = true;
wxSize currentClient;
GetClientSize(&currentClient.x, &currentClient.y);
wxSize currentFrame = GetSize();
#ifdef __EMSCRIPTEN__
// The key assertion: early client size should be > 100
// If it's 20x20, that's the bug!
bool earlyClientOk = (m_earlyClientSize.x > 100 && m_earlyClientSize.y > 100);
bool earlyFrameOk = (m_earlyFrameSize.x > 100 && m_earlyFrameSize.y > 100);
EM_ASM({
console.log('[EARLYSIZE_TEST] After Show() - current client: ' + $0 + 'x' + $1);
console.log('[EARLYSIZE_TEST] After Show() - current frame: ' + $2 + 'x' + $3);
if ($4 && $5) {
console.log('[EARLYSIZE_TEST] PASS: Early sizes were reasonable');
} else {
console.error('[EARLYSIZE_TEST] FAIL: Early sizes were tiny!');
console.error('[EARLYSIZE_TEST] Early client was: ' + $6 + 'x' + $7);
console.error('[EARLYSIZE_TEST] Early frame was: ' + $8 + 'x' + $9);
}
}, currentClient.x, currentClient.y,
currentFrame.x, currentFrame.y,
earlyClientOk ? 1 : 0, earlyFrameOk ? 1 : 0,
m_earlyClientSize.x, m_earlyClientSize.y,
m_earlyFrameSize.x, m_earlyFrameSize.y);
#endif
}
}