feat(wasm-dom): dual-mode build scaffold — native DOM port builds, links and boots alongside canvas
Build/test plumbing for the second wxWidgets mode: --dom on build-wxuniversal-wasm.sh (build-wasm/wxwidgets-dom, no universal, --disable-tooltips, libwx_wasmu_* stubs) and build-wasm-test.sh (mirrors sources into tests/apps-dom, PORT=dom). Build script now reconfigures when Makefile.in or autoconf_inc.m4 regenerate (bakefile chain). Harness: WX_PORT=dom serves apps-dom, namespaces screenshots into test-results/dom and logs into logs/wxwidgets/dom; compare/update screenshot scripts take --port dom with baseline-screenshots-dom. New port-agnostic boot.spec.ts (green on both ports). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
14ca16cbd3
commit
249010a582
10 changed files with 205 additions and 29 deletions
|
|
@ -5,10 +5,20 @@
|
|||
# make -f Makefile.wasm # Optimized release build
|
||||
# make -f Makefile.wasm DEBUG=1 # Debug build with DWARF symbols and source maps
|
||||
|
||||
WXCONFIG = ../../build-wasm/wxwidgets-universal/wx-config
|
||||
TOOLS_ROOT = ../../wxwidgets/build/wasm
|
||||
KICAD_ROOT = ../../kicad
|
||||
|
||||
# PORT=dom links against the DOM (non-universal) wxWidgets build and adds the
|
||||
# wx-dom.js shim. Invoked by scripts/build-wasm-test.sh --dom from a mirrored
|
||||
# source tree in tests/apps-dom (so canvas and DOM bundles coexist).
|
||||
ifeq ($(PORT),dom)
|
||||
WXCONFIG = ../../build-wasm/wxwidgets-dom/wx-config
|
||||
WXLIB_PREFIX = libwx_wasmu
|
||||
else
|
||||
WXCONFIG = ../../build-wasm/wxwidgets-universal/wx-config
|
||||
WXLIB_PREFIX = libwx_wasmunivu
|
||||
endif
|
||||
|
||||
CXX = em++
|
||||
WX_CXXFLAGS := $(shell $(WXCONFIG) --cxxflags)
|
||||
|
||||
|
|
@ -103,13 +113,23 @@ LDFLAGS_COROUTINE = $(DEBUG_LDFLAGS) $(COROUTINE_BASE_LDFLAGS) $(WX_LDFLAGS_NOGL
|
|||
# forbids the very multi-parked-sleep states the harness exists to exercise.
|
||||
LDFLAGS_RACES = $(DEBUG_LDFLAGS) $(COROUTINE_BASE_LDFLAGS) -sASSERTIONS=0 $(WX_LDFLAGS_NOGL)
|
||||
|
||||
JS = $(TOOLS_ROOT)/wx.js
|
||||
# In dom mode a second pre-js carries the DOM-control shim ("--pre-js A --pre-js B"
|
||||
# after expansion — emcc accepts repeated --pre-js).
|
||||
ifeq ($(PORT),dom)
|
||||
JS = $(TOOLS_ROOT)/wx.js --pre-js $(TOOLS_ROOT)/wx-dom.js
|
||||
else
|
||||
JS = $(TOOLS_ROOT)/wx.js
|
||||
endif
|
||||
HTML = $(TOOLS_ROOT)/template.html
|
||||
|
||||
# wxWidgets library directory - used as dependency to rebuild when libs change
|
||||
WX_LIB_DIR = ../../build-wasm/wxwidgets-universal/lib
|
||||
ifeq ($(PORT),dom)
|
||||
WX_LIB_DIR = ../../build-wasm/wxwidgets-dom/lib
|
||||
else
|
||||
WX_LIB_DIR = ../../build-wasm/wxwidgets-universal/lib
|
||||
endif
|
||||
# Key library that changes when wxWidgets is rebuilt
|
||||
WX_CORE_LIB = $(WX_LIB_DIR)/libwx_wasmunivu_core-3.2-emscripten.a
|
||||
WX_CORE_LIB = $(WX_LIB_DIR)/$(WXLIB_PREFIX)_core-3.2-emscripten.a
|
||||
|
||||
# Standalone directories
|
||||
S = standalone
|
||||
|
|
|
|||
31
tests/e2e/boot.spec.ts
Normal file
31
tests/e2e/boot.spec.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import { test, expect, waitForApp } from './utils/fixtures';
|
||||
|
||||
// Port-agnostic boot check: the app starts, the wx element registry fills,
|
||||
// and (in DOM mode) the wx-dom shim is present. Runs under both WX_PORT
|
||||
// values; intentionally takes no screenshots.
|
||||
test.describe('Application boot', () => {
|
||||
test('minimal app boots and registers elements', async ({ page, testLogger }) => {
|
||||
const fatal: string[] = [];
|
||||
page.on('pageerror', (err) => fatal.push(String(err)));
|
||||
|
||||
await page.goto('/minimal_test.html');
|
||||
await waitForApp(page);
|
||||
|
||||
// The registry fills as wx windows are created.
|
||||
await page.waitForFunction(
|
||||
() => (window as any).wxElementRegistry?.elements?.size > 0,
|
||||
undefined,
|
||||
{ timeout: 30000 }
|
||||
);
|
||||
|
||||
const elementCount = await page.evaluate(
|
||||
() => (window as any).wxElementRegistry.elements.size
|
||||
);
|
||||
expect(elementCount).toBeGreaterThan(0);
|
||||
|
||||
const isDomPort = await page.evaluate(() => (window as any).wxDomPort === true);
|
||||
expect(isDomPort).toBe(process.env.WX_PORT === 'dom');
|
||||
|
||||
expect(fatal, `page errors: ${fatal.join('\n')}`).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
|
@ -2,10 +2,31 @@ import { test as base } from '@playwright/test';
|
|||
import * as path from 'path';
|
||||
import { setupTestLogger, writeTestLogs, TestLogger, MAIN_CANVAS, waitForApp, tryLoadApp, getCanvasBox, WXWIDGETS_LOGS_DIR, getTestFileName } from './test-utils';
|
||||
|
||||
// WX_PORT=dom runs the same specs against the DOM-port bundles; screenshots
|
||||
// and logs are namespaced into a dom/ subdirectory so the canvas artifacts
|
||||
// stay untouched (baselines: tests/baseline-screenshots-dom/).
|
||||
const IS_DOM_PORT = process.env.WX_PORT === 'dom';
|
||||
|
||||
// Extend base test with automatic logging
|
||||
export const test = base.extend<{
|
||||
testLogger: TestLogger;
|
||||
}>({
|
||||
page: async ({ page }, use) => {
|
||||
if (IS_DOM_PORT) {
|
||||
const origScreenshot = page.screenshot.bind(page);
|
||||
page.screenshot = ((options?: Parameters<typeof origScreenshot>[0]) => {
|
||||
if (options?.path) {
|
||||
const dir = path.dirname(options.path);
|
||||
// Specs write to test-results/<name>.png; redirect to test-results/dom/.
|
||||
if (path.basename(dir) === 'test-results') {
|
||||
options = { ...options, path: path.join(dir, 'dom', path.basename(options.path)) };
|
||||
}
|
||||
}
|
||||
return origScreenshot(options);
|
||||
}) as typeof page.screenshot;
|
||||
}
|
||||
await use(page);
|
||||
},
|
||||
testLogger: async ({ page }, use, testInfo) => {
|
||||
// Build test name from describe block + test title
|
||||
const testName = testInfo.titlePath.join(' - ');
|
||||
|
|
@ -14,9 +35,11 @@ export const test = base.extend<{
|
|||
|
||||
await use(logger);
|
||||
|
||||
// Write logs to wxwidgets/<test-file>/ directory
|
||||
// Write logs to wxwidgets/<test-file>/ directory (wxwidgets/dom/<test-file>/ for the DOM port)
|
||||
const testFileName = getTestFileName(testInfo.file);
|
||||
const logsDir = path.join(WXWIDGETS_LOGS_DIR, testFileName);
|
||||
const logsDir = IS_DOM_PORT
|
||||
? path.join(WXWIDGETS_LOGS_DIR, 'dom', testFileName)
|
||||
: path.join(WXWIDGETS_LOGS_DIR, testFileName);
|
||||
writeTestLogs(testName, logger, logsDir);
|
||||
logger.cleanup();
|
||||
},
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@ function findFreePort(): number {
|
|||
|
||||
const port = resolvePort();
|
||||
|
||||
// WX_PORT=dom runs the suite against the DOM-port bundles (built by
|
||||
// scripts/build-wasm-test.sh --dom into tests/apps-dom with identical layout).
|
||||
const appsDir = process.env.WX_PORT === 'dom' ? 'apps-dom' : 'apps';
|
||||
|
||||
export default defineConfig({
|
||||
globalSetup: './global-setup.ts',
|
||||
testDir: './e2e',
|
||||
|
|
@ -98,7 +102,7 @@ export default defineConfig({
|
|||
],
|
||||
|
||||
webServer: {
|
||||
command: `npx serve apps -p ${port} -c ../serve.json`,
|
||||
command: `npx serve ${appsDir} -p ${port} -c ../serve.json`,
|
||||
port: port,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue