Dev console: money, items, upgrades, free build, speed (t66)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
"""Dev console confirmation, keyboard isolation, HUD, time controls and saved badge."""
|
||||
import pathlib, sys
|
||||
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent.parent / 'tools'))
|
||||
from use_venv import ensure_playwright; ensure_playwright()
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
ROOT = pathlib.Path(__file__).resolve().parent.parent
|
||||
SHOTS = ROOT / 'shots'
|
||||
SHOTS.mkdir(exist_ok=True)
|
||||
fails = []
|
||||
def check(name, ok):
|
||||
print(('PASS ' if ok else 'FAIL ') + name)
|
||||
if not ok: fails.append(name)
|
||||
|
||||
with sync_playwright() as p:
|
||||
browser = p.chromium.launch()
|
||||
page = browser.new_page(viewport={'width': 1280, 'height': 760})
|
||||
errors = []
|
||||
page.on('pageerror', lambda e: errors.append(str(e)))
|
||||
page.add_init_script("localStorage.setItem('deepgrain.settings', JSON.stringify({look:'pixel', sv:2}));")
|
||||
page.goto((ROOT / 'dist/index.html').as_uri())
|
||||
page.wait_for_function("!$('title').hidden")
|
||||
page.evaluate("startNewWorld(424242, 512, 384, 'Console test')")
|
||||
page.wait_for_function('GAME.running && !GAME.loading')
|
||||
page.evaluate("document.querySelectorAll('.card, .toast').forEach(e => e.remove())")
|
||||
page.keyboard.press('`')
|
||||
check('backtick opens the first-use warning', page.is_visible('#m-dialog') and not page.is_visible('#dev-console'))
|
||||
page.screenshot(path=str(SHOTS / 't66-warning.png'))
|
||||
check('warning explains permanent marking and future achievements', 'permanently' in page.inner_text('#dlg-body') and 'achievements' in page.inner_text('#dlg-body'))
|
||||
page.get_by_role('button', name='Cancel', exact=True).click()
|
||||
check('cancel leaves the world unmarked and console closed', page.evaluate("!devWorld && $('dev-console').hidden && !GAME.paused"))
|
||||
page.keyboard.press('`')
|
||||
page.get_by_role('button', name='Enable dev console', exact=True).click()
|
||||
page.wait_for_function("!$('dev-console').hidden && document.activeElement === $('dev-input')")
|
||||
check('accepting marks the world and resumes play', page.evaluate('devWorld && !GAME.paused'))
|
||||
check('build material chip stays stable across HUD refreshes', page.evaluate("""() => {
|
||||
selectTool(2); renderSelCard();
|
||||
const chip = $('selcard').querySelector('[data-wall-picker]');
|
||||
renderSelCard();
|
||||
const stable = chip === $('selcard').querySelector('[data-wall-picker]');
|
||||
selectTool(0); return stable;
|
||||
}"""))
|
||||
old_money = page.evaluate('money')
|
||||
page.fill('#dev-input', 'money 1000'); page.keyboard.press('Enter')
|
||||
page.wait_for_function(f"money === {old_money + 1000} && $('wallet').textContent.includes(fmtMoney(money))")
|
||||
check('money command changes the wallet HUD', True)
|
||||
tool = page.evaluate('GAME.tool')
|
||||
page.fill('#dev-input', ''); page.keyboard.type('1234wasd')
|
||||
check('typing game keys does not switch tools or hold movement', page.evaluate(f'GAME.tool === {tool} && keys.size === 0'))
|
||||
page.keyboard.press('Escape')
|
||||
check('Escape closes console without opening pause menu', page.evaluate("$('dev-console').hidden && $('m-pause').hidden && !GAME.paused"))
|
||||
page.keyboard.press('`')
|
||||
check('marked worlds reopen without the warning', page.evaluate("!$('dev-console').hidden && $('m-dialog').hidden"))
|
||||
page.keyboard.press('`')
|
||||
check('backtick closes even with input focused', not page.is_visible('#dev-console'))
|
||||
page.keyboard.press('`')
|
||||
def command(text):
|
||||
page.fill('#dev-input', text); page.keyboard.press('Enter')
|
||||
command('pause')
|
||||
tick = page.evaluate('tick')
|
||||
page.wait_for_timeout(150)
|
||||
check('dev pause freezes simulation ticks', page.evaluate('tick') == tick)
|
||||
command('step 5')
|
||||
page.wait_for_function(f'tick === {tick + 5} && devSteps === 0')
|
||||
page.wait_for_timeout(150)
|
||||
check('step advances exactly five ticks then stays paused', page.evaluate('tick') == tick + 5)
|
||||
# Drive the actual frame accumulator with controlled elapsed time and no scheduled frames.
|
||||
counts = page.evaluate('''() => {
|
||||
requestAnimationFrame = () => 0;
|
||||
GAME.paused = false; devPaused = false; SET.fpsCap = 0; SET.maxSteps = 3;
|
||||
const counts = [];
|
||||
for (const speed of [0.5, 1, 2, 8]) {
|
||||
devSpeed = speed; acc = 0; const before = tick;
|
||||
const t = performance.now(); lastT = t - 34; lastRender = t - 34; frame(t);
|
||||
counts.push(tick - before);
|
||||
}
|
||||
return counts;
|
||||
}''')
|
||||
check('speed scales fixed ticks and respects maxSteps', counts == [1, 2, 3, 3])
|
||||
page.evaluate('devCommand("debt clear"); runDevCommand("money 1"); openNotebook("Claims")')
|
||||
page.wait_for_function("$('nb-body').textContent.includes('paid off')")
|
||||
check('cleared debt is reflected in Claims', True)
|
||||
page.evaluate('closeAllModals(); runDevCommand("debt 123"); openNotebook("Market")')
|
||||
check('new debt is reflected in the Market', '$123' in page.inner_text('#nb-body'))
|
||||
page.evaluate('closeAllModals()')
|
||||
page.evaluate("async () => { await saveWorld('main', true); await renderWorlds(); }")
|
||||
page.evaluate("openModal('m-worlds')")
|
||||
check('world list entry stores and draws the dev badge', page.locator('#worlds-list .dev-badge').is_visible() and page.inner_text('#worlds-list .dev-badge') == 'Dev console')
|
||||
page.screenshot(path=str(SHOTS / 't66-worlds.png'))
|
||||
page.evaluate('closeAllModals()')
|
||||
check('saving and loading preserves mark and log, resets runtime controls', page.evaluate('''async () => {
|
||||
const sv = await worldNewest(GAME.worldId);
|
||||
const count = devLog.length;
|
||||
await startFromSave(sv);
|
||||
return devWorld && devLog.length === count && devSpeed === 1 && !devPaused && !devFree && $('dev-console').hidden;
|
||||
}'''))
|
||||
check('no browser errors', not errors)
|
||||
browser.close()
|
||||
|
||||
sys.exit(1 if fails else 0)
|
||||
Reference in New Issue
Block a user