77 lines
4.7 KiB
JavaScript
77 lines
4.7 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const ts = require('typescript');
|
|
const { chromium } = require('playwright');
|
|
|
|
const output = ts.transpileModule(fs.readFileSync('assets/Script/coin_madness/GoldMinerService.ts', 'utf8'), {
|
|
compilerOptions: { target: ts.ScriptTarget.ES2017, module: ts.ModuleKind.CommonJS }
|
|
}).outputText;
|
|
const exported = {};
|
|
new Function('require', 'exports', output)(() => ({}), exported);
|
|
const service = Object.create(exported.default.prototype);
|
|
service.ledger = { notices: {} };
|
|
for (const status of ['purchasable', 'unlocked']) {
|
|
service.info = { status, progressWins: 4, tasks: [{ targetWins: 5, claimStatus: 'locked' }] };
|
|
assert.equal(service.hasBadge, false);
|
|
service.info.progressWins = 5;
|
|
assert.equal(service.hasBadge, true);
|
|
service.info.tasks[0].claimStatus = 'claimed';
|
|
assert.equal(service.hasBadge, false);
|
|
}
|
|
service.info.tasks[0].claimStatus = 'pending_unlock';
|
|
assert.equal(service.hasBadge, true);
|
|
service.info = null; service.ledger.notices = { old: 100 };
|
|
assert.equal(service.hasBadge, true);
|
|
|
|
(async () => {
|
|
const browser = await chromium.launch({ headless: true, channel: 'msedge' });
|
|
try {
|
|
const page = await browser.newPage({ viewport: { width: 450, height: 800 } });
|
|
page.on('pageerror', error => console.error('Preview:', error.message));
|
|
await page.goto('http://127.0.0.1:' + (process.env.PORT || 8879));
|
|
await page.waitForFunction(() => window.demo && demo.ready);
|
|
await page.evaluate(() => {
|
|
const data = { serverNow: Date.now(), status: 'purchasable', state: {
|
|
config: { periodId: 'layout-test', startsAt: Date.now() - 1000, endsAt: Date.now() + 3600000,
|
|
priceCents: 300, stages: Array.from({ length: 5 }, (_, i) => ({ wins: i + 1, coins: 1000 })) },
|
|
totalWins: 0, paidAt: 0, claimed: Array(5).fill(false), stage: 0 } };
|
|
window.testService = { info: { ...data.state.config, status: data.status },
|
|
settlementNotice: 0, serverNow: Date.now(), hasBadge: false,
|
|
readForDisplay: async () => data, refresh: async () => data, view: () => data, stopPolling() {} };
|
|
cc.director.getScene().children[0].getComponent('CoinMadnessHost').resumeSync();
|
|
});
|
|
await page.evaluate(() => { demo.open(); });
|
|
await page.waitForFunction(() => cc.director.getScene().children[0].getChildByName('CoinMadness')?.getComponent('CoinMadnessPanel')?.data);
|
|
for (const price of [3, 68, 128, 3]) {
|
|
const result = await page.evaluate(price => {
|
|
const panel = demo.panel(), data = JSON.parse(JSON.stringify(panel.data));
|
|
data.state.config.priceCents = price * 100;
|
|
data.state.config.stages.forEach((s, i) => { s.coins = i ? 9999 : 45000; });
|
|
data.state.paidAt = 0; data.status = 'purchasable';
|
|
panel.render(data);
|
|
function bounds(digits) {
|
|
const boxes = digits.node.children.filter(n => n.active).map(n => {
|
|
const image = n.getChildByName('Image');
|
|
return { left: n.x - image.width / 2, right: n.x + image.width / 2 };
|
|
});
|
|
return { left: boxes[0].left, right: boxes[boxes.length - 1].right,
|
|
separated: boxes.every((b, i) => !i || b.left >= boxes[i - 1].right) };
|
|
}
|
|
const p = bounds(panel.priceDigits), total = bounds(panel.totalDigits);
|
|
return { total, price: p, priceRight: panel.priceDigits.node.x + p.right,
|
|
currencyLeft: panel.currency.x - panel.currency.width / 2,
|
|
currencyRight: panel.currency.x + panel.currency.width / 2,
|
|
buttonRight: panel.purchaseButton.width / 2,
|
|
rewards: panel.content.children.filter(n => n.active).map(n => bounds(n.getChildByName('Reward').getComponent('CoinMadnessDigits'))) };
|
|
}, price);
|
|
assert(result.total.separated && result.total.right - result.total.left <= 164.01);
|
|
assert(result.price.separated && result.priceRight < result.currencyLeft);
|
|
assert(result.currencyRight < result.buttonRight);
|
|
assert(result.rewards.every(r => r.separated && r.right - r.left <= 170.01));
|
|
fs.mkdirSync('.codex_tmp/number-layout', { recursive: true });
|
|
await page.screenshot({ path: '.codex_tmp/number-layout/price-' + price + '.png' });
|
|
}
|
|
console.log('PASS: 4/5-digit rewards, 1/2/3-digit prices, repeated layout and unpaid completion badge');
|
|
} finally { await browser.close(); }
|
|
})().catch(error => { console.error(error); process.exitCode = 1; });
|