Files
deepgrain-foundry/test/t_stalls.py
T

72 lines
4.2 KiB
Python

"""t45: real transport warnings, hover, frozen animation and recovery in both looks."""
import pathlib
import sys
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1] / 'tools'))
from use_venv import ensure_playwright; ensure_playwright()
from browser import launch, consume_gpu_option
consume_gpu_option()
ROOT = pathlib.Path(__file__).resolve().parents[1]
with launch(viewport={'width': 1280, 'height': 760}, page_path=sys.argv[1] if len(sys.argv)>1 else None) as (_, page, url):
errors=[]
page.on('pageerror', lambda e: errors.append(str(e)))
page.goto(url)
page.evaluate("""() => {
const enter=enterGame;enterGame=()=>{enter();GAME.paused=true;};
SET.look='pixel';SET.workerCap=0;SET.autosave=0;startNewWorld(7,768,600);
}""")
page.wait_for_function('GAME.running', timeout=60000)
page.evaluate("""() => {
mat.fill(EMPTY);part.fill(0);blockP.fill(0);blockV.fill(0);isPow.fill(0);
flags.fill(0);temp.fill(20);AMB.fill(20);bgm.fill(0);fog.fill(255);
machines=[null];molds=[];ents=[];flyers=[];treeBases=[];saplings=[];
pcells.clear();beltL=[];beltR=[];screwLists=Array.from({length:IS_SCREW.length},()=>[]);
weather.next=1e15;weather.shower=null;surfY.fill(300);updateRoof();
bot.x=320;bot.y=210;money=500;ledger={};nextPowerBuild=0;
for(const [code,v,by] of [[BP_BELT,1,46],[BP_FILTER,128,52],[BP_SCREW,1,58]]) {
for(let bx=68;bx<86;bx++)placeBlock(code,v,bx,by,true,{m:[],inv:0});
// The return screw hangs just above the loaded belt.
if(code===BP_BELT)for(let bx=70;bx<86;bx++)placeBlock(BP_SCREW,3,bx,44,true);
for(let y=by*4-4;y<by*4+(code===BP_SCREW?4:0);y++)
for(let x=272;x<344;x++)setCell(y*W+x,SAND,20,0);
for(let y=by*4-8;y<by*4+8;y++)setCell(y*W+344,STONE,20,0);
}
for(let k=0;k<180;k++)simTick();
$('hud').hidden=true;
SET.fog=false;SET.zoom=9;SET.lighting='off';SET.glow='off';SET.minimap=false;
SET.cameraLead=false;GAME.infoOverlay=false;GAME.hidePreviews=true;
document.querySelectorAll('.card-pop,.toast').forEach(e=>e.remove());R.floaters=[];
resizeRender();snapCamera();renderDirty.fill(1);GPU.world=null;SM.surf=-1;
}""")
assert page.evaluate("hoverInfo(330,185).warn==='stalled'"), 'jam has no hover warning'
assert page.evaluate("hoverInfo(330,185).t2.some(t=>t.includes('Clear the outlet or the top of the heap'))")
assert page.evaluate("[46,52,58].every(by=>transportStalled(by*BW+82))")
for look in ['pixel','smooth']:
page.evaluate(f"SET.look='{look}'")
page.wait_for_function(f"R.smoothOn === {'true' if look=='smooth' else 'false'}")
page.wait_for_timeout(150)
assert page.evaluate("""() => {
const p=worldToScreenPx(330,185),ctx=R.ctx;
ctx.clearRect(0,0,R.canvas.width,R.canvas.height);drawTransportStalls();
const shown=ctx.getImageData(p.x,p.y,1,1).data[3];
SET.fog=true;fog.fill(0);ctx.clearRect(0,0,R.canvas.width,R.canvas.height);drawTransportStalls();
const hidden=ctx.getImageData(p.x,p.y,1,1).data[3];SET.fog=false;fog.fill(255);
return shown>0 && hidden===0;
}""")
# Compare actual built pixels while simulation time advances under the jam.
page.wait_for_timeout(60)
clips=page.evaluate("""() => [184,208,233].map(y=>{const p=worldToScreenPx(329,y);return {x:p.x,y:p.y,width:18,height:9};})""")
before=[page.screenshot(clip=c) for c in clips]
page.evaluate('for(let k=0;k<10;k++)simTick()')
page.wait_for_timeout(60)
assert [page.screenshot(clip=c) for c in clips]==before, f'{look}: stalled transport still animates'
path=ROOT / ('shots/t45-stalled.png' if look=='pixel' else 'shots/t45-stalled-smooth.png')
page.screenshot(path=str(path))
print(f'PASS {look}: marker with overlay off, fog, hover, frozen rendered belt and screenshot')
page.evaluate("""() => {
for(const by of [46,52,58])for(let y=by*4-8;y<by*4+8;y++)for(let x=344;x<360;x++)setCell(y*W+x,EMPTY,20,0);
for(let k=0;k<60;k++)simTick();
}""")
assert page.evaluate('!transportStalled(46*BW+82)'), 'belt did not recover'
assert not errors, errors
print('PASS cleared blockage resumes transport; no page errors')