25 lines
3 KiB
JavaScript
25 lines
3 KiB
JavaScript
'use strict';
|
||
const fs=require('fs');
|
||
const path=require('path');
|
||
const root=path.join(__dirname,'..');
|
||
const app=fs.readFileSync(path.join(root,'app.js'),'utf8');
|
||
const html=fs.readFileSync(path.join(root,'index.html'),'utf8');
|
||
const css=fs.readFileSync(path.join(root,'style.css'),'utf8');
|
||
function assert(value,message){if(!value)throw new Error(message)}
|
||
assert(html.includes('href="https://host.nishi.boats/~333/"')&&html.includes('333の部屋に戻る'),'The return link is missing');
|
||
assert(!html.includes('id="selectedInfo"')&&!app.includes("querySelector('#selectedInfo')"),'The current board level remains in the top UI');
|
||
assert(!app.includes('絵文字エフェクト')&&!html.includes('絵文字エフェクト'),'The reaction category still uses the retired label');
|
||
assert(app.includes('TIME_ATTACK_COOLDOWN_MINUTES=Object.freeze({3:10,5:15,10:20})'),'Time-attack cooldown durations are incorrect');
|
||
assert(app.includes('for(const minutes of TIME_ATTACK_MINUTES)data.timeAttackCooldowns[minutes]=cooldownEndsAt'),'Time-attack cooldown is not shared by every course');
|
||
assert(app.includes("for(const value of['3','2','1'])")&&app.includes("showTimeAttackCountdownOverlay('Start','start')"),'The start countdown is incomplete');
|
||
assert(app.includes("timeAttackBtn.classList.toggle('final-countdown',remaining<=30000&&remaining>0)")&&css.includes('.pill.time-attack.active.final-countdown'),'The right-side timer is not emphasized during the final 30 seconds');
|
||
assert(html.includes('獲得ジェムの倍率UP')&&html.includes('獲得ジェムに応じて次の通り倍率が上昇します。')&&html.includes('<small>基礎累計</small>'),'The multiplier explanation is missing');
|
||
assert(app.includes('return timeAttackMultiplier(run.baseCollected||0)')&&app.includes('reward.preTimeAward')&&app.includes('run.baseCollected'),'The multiplier implementation no longer matches the displayed explanation');
|
||
assert(!html.includes('id="timeAttackResultCollected"')&&!html.includes('id="timeAttackResultMultiplier"')&&!html.includes('id="timeAttackResultBonus"'),'Removed result fields remain');
|
||
assert(app.includes('cloudAppBaseUrl'),'The time-attack result does not use the current deployment URL');
|
||
assert(css.includes('rgba(194,108,255,.42)')&&css.includes('#timeAttackCountdownOverlay'),'The purple multiplier panel or countdown styling is missing');
|
||
console.log('v47.88 time-attack and navigation smoke test passed');
|
||
|
||
assert(html.includes('<title>LinkField/リンクフィールド</title>')&&app.includes('LinkField/リンクフィールド|タイムアタック'),'The LinkField title is missing');
|
||
assert(!app.includes('キャンディローズ')&&!app.includes('ルビービーム')&&!app.includes('line-color-rose')&&!app.includes('line-color-ruby'),'Removed line colors remain in presentation code');
|
||
assert(app.includes('let initialMeta=await randomUnsolvedMeta()')&&!app.includes('if(!restoreSavedCamera())centerMeta(initialMeta'),'Startup camera is not randomized to an unsolved board');
|