from pathlib import Path import sys,json 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',headless=True,args=['--no-sandbox','--enable-webgl','--use-gl=angle','--use-angle=swiftshader','--enable-unsafe-swiftshader']) page=b.new_page(viewport={'width':1500,'height':1050},device_scale_factor=1);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")') box=page.locator('#stage').bounding_box();cx=box['x']+box['width']/2;cy=box['y']+box['height']/2 page.mouse.move(cx,cy);page.wait_for_timeout(100);assert page.locator('#tree').evaluate('e=>getComputedStyle(e).cursor')=='default' page.locator('#detail').click();page.locator('#sel-close').click();page.mouse.move(cx,cy);page.wait_for_timeout(150);assert page.locator('#tree').evaluate('e=>getComputedStyle(e).cursor')=='pointer' assert page.locator('#selection').is_visible();assert page.locator('#sel-id').inner_text()=='GCA_000001405.29';assert page.locator('#sel-state').text_content().startswith('Hover preview') page.mouse.down();assert page.locator('#tree').evaluate('e=>getComputedStyle(e).cursor')!='grabbing';page.mouse.up();assert page.locator('#sel-id').inner_text()=='GCA_000001405.29' assert '4 / 1,412' in page.locator('#sel-data').inner_text();page.locator('#scope').select_option('1');assert '2 / 1,412' in page.locator('#sel-data').inner_text() # Inspect the path actually sent to Canvas, compared with the GPU's sampled line. result=page.evaluate('''()=>{let path=[],observed=null;const oldBegin=fx.beginPath,oldMove=fx.moveTo,oldLine=fx.lineTo,oldStroke=fx.stroke;fx.beginPath=function(){path=[];return oldBegin.call(this)};fx.moveTo=function(x,y){path.push([x,y]);return oldMove.call(this,x,y)};fx.lineTo=function(x,y){path.push([x,y]);return oldLine.call(this,x,y)};fx.stroke=function(){if(this.strokeStyle===palette.highlight&&this.lineWidth>1.7)observed=path.slice();return oldStroke.call(this)};draw();fx.beginPath=oldBegin;fx.moveTo=oldMove;fx.lineTo=oldLine;fx.stroke=oldStroke;let a=selected,expected=[screen([hitData[a.geometryStart],hitData[a.geometryStart+1]])];for(let k=a.geometryStart+4;kMath.hypot(v[0]-expected[i][0],v[1]-expected[i][1])))}}''') assert result['count']==result['expected'] and result['error']<.001,result print('highlight agreement',result,flush=True) page.screenshot(path=str(R/'selection-aligned.png')) page.mouse.move(cx-100,cy+100);page.mouse.down();page.mouse.move(cx-98,cy+100);assert page.locator('#tree').evaluate('e=>getComputedStyle(e).cursor')!='grabbing';page.mouse.move(cx-60,cy+120);assert page.locator('#tree').evaluate('e=>getComputedStyle(e).cursor')=='grabbing';page.mouse.up();assert page.locator('#tree').evaluate('e=>getComputedStyle(e).cursor')!='grabbing' assert page.locator('#sel-id').inner_text()=='GCA_000001405.29' timing=page.evaluate('''()=>{let t=performance.now();for(let i=0;i<5;i++)nearest(W/2+i,H/2,3);return (performance.now()-t)/5}''');print('mean hit-test ms',round(timing,1),'errors',errors,flush=True);assert not errors;b.close()