test: 💍 select height wxWidget
This commit is contained in:
parent
de03d6f0f6
commit
28615aba02
5 changed files with 170 additions and 1 deletions
|
|
@ -167,6 +167,7 @@ all: minimal_test.html \
|
|||
$(S)/regions/regions_test.html \
|
||||
$(S)/maximize/maximize_test.html \
|
||||
$(S)/earlysize/earlysize_test.html \
|
||||
$(S)/selectheight/selectheight_test.html \
|
||||
$(S)/threadpool/threadpool_test.html \
|
||||
$(S)/logerror/logerror_test.html \
|
||||
$(S)/retinascale/retinascale_test.html \
|
||||
|
|
@ -508,6 +509,12 @@ $(S)/earlysize/earlysize_test.o: $(S)/earlysize/earlysize_test.cpp
|
|||
$(S)/earlysize/earlysize_test.html: $(S)/earlysize/earlysize_test.o $(WX_CORE_LIB) $(JS_FILES)
|
||||
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
|
||||
|
||||
$(S)/selectheight/selectheight_test.o: $(S)/selectheight/selectheight_test.cpp
|
||||
$(CXX) -c $(CXXFLAGS) $< -o $@
|
||||
|
||||
$(S)/selectheight/selectheight_test.html: $(S)/selectheight/selectheight_test.o $(WX_CORE_LIB) $(JS_FILES)
|
||||
$(CXX) $< $(LDFLAGS_NOGL) --pre-js $(JS) --shell-file $(HTML) -o $@
|
||||
|
||||
# Thread Pool test (pthread) - reproduces KiCad deadlock when hardware_concurrency() > PTHREAD_POOL_SIZE
|
||||
$(S)/threadpool/threadpool_test.o: $(S)/threadpool/threadpool_test.cpp
|
||||
$(CXX) -c $(CXXFLAGS) -pthread $< -o $@
|
||||
|
|
@ -604,6 +611,7 @@ bitmask: $(S)/bitmask/bitmask_test.html
|
|||
regions: $(S)/regions/regions_test.html
|
||||
maximize: $(S)/maximize/maximize_test.html
|
||||
earlysize: $(S)/earlysize/earlysize_test.html
|
||||
selectheight: $(S)/selectheight/selectheight_test.html
|
||||
threadpool: $(S)/threadpool/threadpool_test.html
|
||||
logerror: $(S)/logerror/logerror_test.html
|
||||
|
||||
|
|
@ -627,7 +635,7 @@ clean:
|
|||
rm -f $(S)/*/*_test*.html $(S)/*/*_test*.js $(S)/*/*_test*.wasm
|
||||
rm -f $(S)/*/*_repro*.html $(S)/*/*_repro*.js $(S)/*/*_repro*.wasm
|
||||
|
||||
.PHONY: all clean menu contextmenu scrollbar 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 threadpool logerror retinascale coroutine coroutine-nested asyncify-races
|
||||
.PHONY: all clean menu contextmenu scrollbar 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 selectheight threadpool logerror retinascale coroutine coroutine-nested asyncify-races
|
||||
|
||||
# === Coroutine pthread variant — reproduces the KiCad Asyncify-fiber x pthreads crash ===
|
||||
# Same modal-free harness as `coroutine`, but compiled/linked with pthreads to match
|
||||
|
|
|
|||
105
tests/apps/standalone/selectheight/selectheight_test.cpp
Normal file
105
tests/apps/standalone/selectheight/selectheight_test.cpp
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
// Select Height Test - Regression guard for the wxChoice (<select>) height fix.
|
||||
//
|
||||
// Bug (fixed in commit "fix: 🐛 select height"): an HTML <select>'s height only
|
||||
// resolves once the browser lays it out, but DoGetBestSize() is frequently
|
||||
// queried BEFORE layout (wxAuiToolBar freezes a control's min size at AddControl
|
||||
// time, panel sizers measure during construction). The DOM reported ~0 height,
|
||||
// so the layout system pinned the control to an unusable sliver.
|
||||
//
|
||||
// The fix is wxChoice::DoGetBestSize() (src/wasm/choice.cpp), which floors the
|
||||
// height to GetCharHeight() + 8 when the DOM-measured height is too small.
|
||||
//
|
||||
// This test creates ONE wxChoice and queries GetBestSize() in the constructor,
|
||||
// BEFORE the frame is shown / laid out. On pre-fix code best.y is ~0 (FAIL);
|
||||
// with the fix it is GetCharHeight() + 8 (PASS).
|
||||
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
class SelectHeightTestApp : public wxApp
|
||||
{
|
||||
public:
|
||||
virtual bool OnInit() override;
|
||||
};
|
||||
|
||||
class SelectHeightTestFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
SelectHeightTestFrame();
|
||||
|
||||
private:
|
||||
wxSize m_earlyBestSize; // wxChoice best size captured before Show()/layout
|
||||
};
|
||||
|
||||
wxIMPLEMENT_APP(SelectHeightTestApp);
|
||||
|
||||
bool SelectHeightTestApp::OnInit()
|
||||
{
|
||||
if (!wxApp::OnInit())
|
||||
return false;
|
||||
|
||||
SelectHeightTestFrame* frame = new SelectHeightTestFrame();
|
||||
frame->Show(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
SelectHeightTestFrame::SelectHeightTestFrame()
|
||||
: wxFrame(nullptr, wxID_ANY, "Select Height Test",
|
||||
wxDefaultPosition, wxSize(400, 200))
|
||||
{
|
||||
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
mainSizer->Add(new wxStaticText(this, wxID_ANY,
|
||||
"Select Height Test\n\n"
|
||||
"One wxChoice; its GetBestSize() is queried in the constructor,\n"
|
||||
"before layout. Height must NOT collapse to ~0px."),
|
||||
0, wxALL, 10);
|
||||
|
||||
// The single control under test. wxDefaultSize so the caller does not force
|
||||
// a height -- the height must come from DoGetBestSize().
|
||||
wxString items[] = { "Red", "Green", "Blue" };
|
||||
wxChoice* choice = new wxChoice(this, wxID_ANY, wxDefaultPosition,
|
||||
wxDefaultSize, 3, items);
|
||||
choice->SetSelection(0);
|
||||
|
||||
// === THE KEY MEASUREMENT ===
|
||||
// Query best size BEFORE Show()/layout, where the bug manifested. Nothing is
|
||||
// cached yet, so this recomputes via wxChoice::DoGetBestSize().
|
||||
m_earlyBestSize = choice->GetBestSize();
|
||||
|
||||
// The bug was height-specific; width comes from intrinsic content sizing and
|
||||
// was never broken. A real control is at least a line of text tall.
|
||||
const int minHeight = GetCharHeight() + 8;
|
||||
const bool heightOk = (m_earlyBestSize.y >= minHeight);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EM_ASM({
|
||||
console.log('[SELECTHEIGHT_TEST] Choice best size: ' + $0 + 'x' + $1);
|
||||
console.log('[SELECTHEIGHT_TEST] Expected min height: ' + $2);
|
||||
if ($3) {
|
||||
console.log('[SELECTHEIGHT_TEST] PASS: select has a real height');
|
||||
} else {
|
||||
console.error('[SELECTHEIGHT_TEST] FAIL: select height collapsed to '
|
||||
+ $1 + 'px (expected >= ' + $2 + ')');
|
||||
}
|
||||
}, m_earlyBestSize.x, m_earlyBestSize.y, minHeight, heightOk ? 1 : 0);
|
||||
#endif
|
||||
|
||||
choice->SetSelection(0);
|
||||
mainSizer->Add(choice, 0, wxALL, 10);
|
||||
|
||||
SetSizer(mainSizer);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EM_ASM({
|
||||
console.log('[SELECTHEIGHT_TEST] Select height test app started');
|
||||
});
|
||||
#endif
|
||||
}
|
||||
BIN
tests/baseline-screenshots/selectheight-01-loaded.png
Normal file
BIN
tests/baseline-screenshots/selectheight-01-loaded.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
BIN
tests/baseline-screenshots/selectheight-02-result.png
Normal file
BIN
tests/baseline-screenshots/selectheight-02-result.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
56
tests/e2e/selectheight.spec.ts
Normal file
56
tests/e2e/selectheight.spec.ts
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
// Select Height Test - Regression guard for the wxChoice (<select>) height fix.
|
||||
// A <select>'s height only resolves after layout, but DoGetBestSize() is queried
|
||||
// before layout; the DOM used to report ~0 height, collapsing the control. The
|
||||
// fix floors the height in wxChoice::DoGetBestSize(). The C++ app queries one
|
||||
// wxChoice's GetBestSize() in its constructor (before Show()) and logs it.
|
||||
import { test, expect, tryLoadApp } from './utils/fixtures';
|
||||
|
||||
test.describe('Select Height Tests', () => {
|
||||
|
||||
test('Select height test app loads successfully', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/selectheight/selectheight_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
|
||||
await page.screenshot({ path: 'test-results/selectheight-01-loaded.png', fullPage: true });
|
||||
|
||||
const hasStartup = testLogger.consoleLogs.some(l => l.includes('[SELECTHEIGHT_TEST] Select height test app started'));
|
||||
|
||||
expect(loaded, 'Select height 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('wxChoice best size has a real height before layout', async ({ page, testLogger }) => {
|
||||
await page.goto('/standalone/selectheight/selectheight_test.html');
|
||||
const loaded = await tryLoadApp(page);
|
||||
expect(loaded, 'App should load').toBe(true);
|
||||
|
||||
// Wait for the app to finish initialization
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await page.screenshot({ path: 'test-results/selectheight-02-result.png', fullPage: true });
|
||||
|
||||
// Parse the best size logged from the constructor (before Show()/layout)
|
||||
const bestSizeLogs = testLogger.consoleLogs.filter(l => l.includes('[SELECTHEIGHT_TEST] Choice best size:'));
|
||||
expect(bestSizeLogs.length).toBeGreaterThan(0);
|
||||
|
||||
const bestMatch = bestSizeLogs[0].match(/Choice best size: (\d+)x(\d+)/);
|
||||
expect(bestMatch, 'Best size log should contain dimensions').not.toBeNull();
|
||||
|
||||
if (bestMatch) {
|
||||
const height = parseInt(bestMatch[2]);
|
||||
|
||||
// The key assertion: the <select> height must NOT collapse to ~0px.
|
||||
// Pre-fix this was ~0; the DoGetBestSize() floor makes it a line of text tall.
|
||||
expect(height, `Select best-size height should be > 0 (got ${height})`).toBeGreaterThan(0);
|
||||
expect(height, `Select best-size height should be a real control height (got ${height})`).toBeGreaterThan(10);
|
||||
}
|
||||
|
||||
// The C++ app cross-checks against GetCharHeight()+8 and emits PASS/FAIL.
|
||||
const passLog = testLogger.consoleLogs.some(l => l.includes('[SELECTHEIGHT_TEST] PASS'));
|
||||
const failLog = testLogger.consoleLogs.some(l => l.includes('[SELECTHEIGHT_TEST] FAIL'));
|
||||
|
||||
expect(failLog, 'Should not have FAIL log').toBe(false);
|
||||
expect(passLog, 'Should have PASS log').toBe(true);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue