carbon-a-release / check_sweep.py
lvwerra's picture
lvwerra HF Staff
Extend the sweep to four seconds and make the centre dial selectable
cba18a0 verified
Raw History Blame Contribute Delete
4.68 kB
from pathlib import Path
import sys,json,time
sys.path.insert(0,'/home/node/local/carbon-a-render/python')
from playwright.sync_api import sync_playwright
R=Path(__file__).parent
with sync_playwright() as p:
b=p.chromium.launch(executable_path='/opt/pw-browsers/chromium_headless_shell-1234/chrome-headless-shell-linux64/chrome-headless-shell',args=['--no-sandbox','--enable-webgl','--use-gl=angle','--use-angle=swiftshader','--enable-unsafe-swiftshader'])
page=b.new_page(viewport={'width':1500,'height':1050});errors=[];page.on('pageerror',lambda e:errors.append(str(e)))
page.goto((R/'index.html').as_uri());page.wait_for_function('window.POC && !document.querySelector("#loading")')
assert page.evaluate('POC.sweepTotals')=={'species':16374,'assemblies':33588,'loci':212905534,'known':17828}
# The hand is thinner than the highlighted path and touches its exact root.
hand=page.evaluate('''()=>{const a=leaves[1200];selectAssembly(a);let paths=[],path=[];const ob=fx.beginPath,om=fx.moveTo,ol=fx.lineTo,os=fx.stroke;fx.beginPath=function(){path=[];return ob.call(this)};fx.moveTo=function(x,y){path.push([x,y]);return om.call(this,x,y)};fx.lineTo=function(x,y){path.push([x,y]);return ol.call(this,x,y)};fx.stroke=function(){paths.push({width:this.lineWidth,path:path.slice()});return os.call(this)};drawInteraction();fx.beginPath=ob;fx.moveTo=om;fx.lineTo=ol;fx.stroke=os;const hand=paths[0],strand=paths[1];return {handWidth:hand.width,strandWidth:strand.width,gap:Math.hypot(hand.path[1][0]-strand.path[0][0],hand.path[1][1]-strand.path[0][1])}}''')
assert hand['handWidth']<hand['strandWidth'] and hand['gap']<.001,hand
# Count all crossings, including many strands between rendered frames.
page.evaluate('''()=>{window.sweepFrames=[];window.treeRedraws=0;const old=gl.drawArrays.bind(gl);gl.drawArrays=(...args)=>{treeRedraws++;old(...args)};const original=updateSweep;updateSweep=function(t){original(t);sweepFrames.push({t:performance.now(),p:sweep.progress,count:sweep.count,species:sweep.species,loci:sweep.loci,angle:sweep.angle,id:selected?.i??null})}}''')
page.locator('#animate-sweep').click();page.wait_for_function('sweep.progress>.25 && sweep.running')
# Hover does not steal the animated selection.
box=page.locator('#stage').bounding_box();page.mouse.move(box['x']+box['width']/2,box['y']+box['height']/2)
page.wait_for_function('sweep.status==="complete"',timeout=10000)
result=page.evaluate('''()=>({frames:sweepFrames,redraws:treeRedraws,totals:{species:sweep.species,count:sweep.count,loci:sweep.loci,known:sweep.known},angle:sweep.angle,selected,zoom})''')
f=result['frames'];assert all(a['count']<=z['count'] and a['species']<=z['species'] and a['loci']<=z['loci'] for a,z in zip(f,f[1:]))
assert result['totals']=={'species':16374,'count':33588,'loci':212905534,'known':17828}
assert abs(result['angle']-4.71238898038469)<1e-9 and result['zoom']==1
duration=f[-1]['t']-f[1]['t'];assert 3900<=duration<4500,duration
assert len(f)>35,len(f)
assert result['redraws']<6,result['redraws']
assert any(z['count']-a['count']>1 for a,z in zip(f,f[1:]))
for row in f:
if row['id'] is not None:assert row['id']==row['count']-1
assert page.locator('#seen-species').inner_text()=='16,374'
assert page.locator('#seen-assemblies').inner_text()=='33,588'
assert page.locator('#seen-loci').inner_text()=='212,905,534'
page.screenshot(path=str(R/'sweep-complete.png'))
# Replay resets counts; stopping holds exact partial totals and a selection.
page.locator('#animate-sweep').click();page.wait_for_function('sweep.count>100 && sweep.count<33588')
page.locator('#animate-sweep').click();assert page.evaluate('sweep.status')=='stopped';count=page.evaluate('sweep.count');assert count<33588
page.wait_for_timeout(200);assert page.evaluate('sweep.count')==count
assert page.locator('#selection').is_visible()
page.screenshot(path=str(R/'sweep-detail.png'))
# Starting from a detail view restores the whole tree; Escape can stop playback.
page.locator('#detail').click();assert page.evaluate('zoom')>1
page.locator('#animate-sweep').click();assert page.evaluate('zoom')==1
page.keyboard.press('Escape');assert not page.evaluate('sweep.running')
page.locator('#theme-toggle').click();page.locator('#animate-sweep').click();page.wait_for_function('sweep.progress>.1');page.locator('#scope').select_option('1');assert page.locator('#selection').is_hidden();page.locator('#reset').click();assert not page.evaluate('sweep.running')
assert not errors,errors
print(json.dumps({'hand':hand,'duration_ms':round(duration),'frames':len(f),'background_redraws':result['redraws'],'totals':result['totals'],'errors':errors}),flush=True)
b.close()