MatchMaster/tools/coin-madness/check-preview.cjs

67 lines
5.2 KiB
JavaScript

const { chromium } = require(process.env.PLAYWRIGHT_MODULE || 'playwright');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const out = '.codex_tmp/coinmadness-preview';
fs.mkdirSync(out, { recursive: true });
(async () => {
const browser = await chromium.launch({ headless: true, channel: process.env.BROWSER_CHANNEL || 'msedge' });
try {
const page = await browser.newPage({ viewport: { width: 450, height: 800 } });
const errors = []; page.on('pageerror', error => errors.push(error.message));
await page.goto('http://127.0.0.1:' + (process.env.PORT || 8765));
await page.waitForFunction(() => window.demo?.ready);
const before = await page.evaluate(() => demo.snapshot());
assert.equal(before.bundle, false); assert.equal(before.panels, 0);
await page.evaluate(() => demo.open()); await page.waitForTimeout(150);
assert.equal((await page.evaluate(() => demo.snapshot())).panels, 1);
const labels = await page.evaluate(() => cc.director.getScene().getComponentsInChildren(cc.Label).map(l => ({ text: l.string, width: l.node.width })));
assert.ok(await page.evaluate(() => !!demo.panel().node.getChildByName('Card').getChildByName('title').getComponent(cc.Sprite).spriteFrame));
assert.ok(labels.every(l => !l.text || l.width > 0));
assert.ok(await page.evaluate(() => demo.panel().node.getChildByName('Card')
.getComponentsInChildren(cc.Label).every(label => !/[0-9]/.test(label.string))), 'All digits must use image glyphs');
assert.ok(await page.evaluate(() => ['timer_bg', 'close'].every(name =>
demo.panel().node.getChildByName('Card').getChildByName(name).getComponent(cc.Sprite).spriteFrame)));
await page.screenshot({ path: out + '/unpaid.png' });
await page.evaluate(() => demo.action('purchase',{periodId:demo.data.state.config.periodId}));
await page.waitForTimeout(300);
for(let i=0;i<2;i++){await page.evaluate(()=>demo.action('simulate_win'));await page.waitForTimeout(300);}
await page.waitForTimeout(100); await page.screenshot({ path: out + '/claimable.png' });
await page.evaluate(() => {
const row = demo.panel().content.children[0];
for (let i = 0; i < 2; i++) row.emit(cc.Node.EventType.TOUCH_END, { stopPropagation() {} });
});
await page.waitForFunction(() => demo.data.state.stage === 1 && !demo.data.pending);
assert.equal(await page.evaluate(() => cc.fx.GameConfig.GM_INFO.coin), 1000);
assert.equal(await page.evaluate(() => demo.data.mockBalance), 1150);
assert.equal(await page.evaluate(() => demo.data.state.progress), 2);
await page.screenshot({ path: out + '/next-stage.png' });
for (let i = 0; i < 3; i++) { await page.evaluate(() => demo.action('simulate_win')); await page.waitForTimeout(300); }
await page.screenshot({ path: out + '/art-ready.png' });
// Repeated refreshes must destroy old row/label nodes rather than only detaching them.
const count = () => cc.director.getScene().getComponentsInChildren(cc.Label).length;
const initialLabels = await page.evaluate(count);
for (let i = 0; i < 5; i++) { await page.evaluate(() => demo.action('read')); await page.waitForTimeout(300); }
assert.equal(await page.evaluate(count), initialLabels);
assert.ok(await page.evaluate(() => demo.panel().countdown.frames.length === 10));
for (let i = 0; i < 10; i++) { await page.evaluate(() => demo.close()); await page.evaluate(() => demo.open()); }
await page.evaluate(() => demo.close());
const after = await page.evaluate(() => demo.snapshot());
assert.deepEqual(after, before); assert.deepEqual(errors, []);
// Destroy the host while a prefab request is in flight, as when leaving HomeScene.
const late = await browser.newPage({ viewport: { width: 450, height: 800 } });
late.on('pageerror', error => errors.push(error.message));
await late.goto('http://127.0.0.1:' + (process.env.PORT || 8765));
await late.waitForFunction(() => window.demo?.ready);
await late.route('**/coin_madness/import/**', async route => { await new Promise(r => setTimeout(r, 150)); await route.continue(); });
const loadingTexture = late.waitForRequest('**/coin_madness/import/**');
await late.evaluate(() => { demo.open(); });
await loadingTexture;
await late.evaluate(() => cc.director.getScene().getComponentsInChildren(cc.Component).find(c => c.constructor.name === 'CoinMadnessHost' || cc.js.getClassName(c) === 'CoinMadnessHost').destroy());
await late.waitForFunction(() => !demo.snapshot().bundle && demo.snapshot().panels === 0, null, { timeout: 5000 });
assert.equal((await late.evaluate(() => demo.snapshot())).bundle, false);
assert.equal((await late.evaluate(() => demo.snapshot())).panels, 0);
assert.deepEqual(errors, []);
console.log(JSON.stringify({ passed: true, before, after, cycles: 10, lateLoadReleased: true, doubleClickClaimCoins: 150, screenshots: out }, null, 2));
} finally { await browser.close(); }
})().catch(error => { console.error(error); process.exitCode = 1; });