// Exercises the actual WebGL bridge with WeChat logical coordinates and API fallbacks. const fs = require('fs'); const path = require('path'); const vm = require('vm'); const assert = require('assert'); const root = path.resolve(__dirname, '..'); const source = fs.readFileSync(path.join(root, 'AIClient/Assets/Plugins/WebGL/UiSafeArea.jslib'), 'utf8'); const results = []; function check(name, api, expected, status = 1, useGameGlobal = false) { const context = { LibraryManager: { library: {} }, mergeInto: Object.assign, HEAPF32: new Float32Array(16) }; if (api) { if (useGameGlobal) context.GameGlobal = { wx: api }; else context.wx = api; } vm.createContext(context); vm.runInContext(source, context); assert.strictEqual(context.LibraryManager.library.AIGame_GetUiSafeInsets(0), status, name); const actual = Array.from(context.HEAPF32.slice(0, 4)); actual.forEach((v, i) => assert(Math.abs(v - expected[i]) < 0.000001, name + ': ' + actual)); results.push({ name, status, actual }); } const phone = { windowWidth: 390, windowHeight: 844, pixelRatio: 3, safeArea: { left: 0, right: 390, top: 47, bottom: 810, width: 390, height: 763 } }; const capsule = { left: 290, right: 377, top: 51, bottom: 83, width: 87, height: 32 }; check('iphone notch, capsule and home indicator', { getWindowInfo: () => phone, getMenuButtonBoundingClientRect: () => capsule }, [0, 34 / 844, 0, 91 / 844]); check('DPR does not change normalized layout', { getWindowInfo: () => ({ ...phone, pixelRatio: 1 }), getMenuButtonBoundingClientRect: () => capsule }, [0, 34 / 844, 0, 91 / 844]); check('GameGlobal API access', { getWindowInfo: () => phone, getMenuButtonBoundingClientRect: () => capsule }, [0, 34 / 844, 0, 91 / 844], 1, true); check('older client window API fallback', { getWindowInfo: () => { throw Error('unsupported'); }, getSystemInfoSync: () => phone, getMenuButtonBoundingClientRect: () => capsule }, [0, 34 / 844, 0, 91 / 844]); check('menu API fallback', { getWindowInfo: () => phone }, [0, 34 / 844, 0, 87 / 844]); check('android capsule without notch', { getWindowInfo: () => ({ windowWidth: 360, windowHeight: 800 }), getMenuButtonBoundingClientRect: () => ({ top: 24, bottom: 56, width: 87, height: 32 }) }, [0, 0, 0, 64 / 800]); check('invalid dimensions', { getWindowInfo: () => ({ windowWidth: 0, windowHeight: 0 }) }, [0, 0, 0, 0], 0); check('browser has no wx', null, [0, 0, 0, 0], 0); const output = path.join(root, 'Tools/output/home_mobile'); fs.mkdirSync(output, { recursive: true }); fs.writeFileSync(path.join(output, 'wechat_safe_area.json'), JSON.stringify({ passed: true, cases: results }, null, 2)); console.log('PASS: ' + results.length + ' WeChat safe-area bridge scenarios');