from pathlib import Path
import json
from playwright.sync_api import sync_playwright
ROOT=Path(__file__).resolve().parents[1];A=ROOT/'analysis';checks=[];errors=[]
with sync_playwright() as p:
    browser=p.chromium.launch(headless=True,args=['--disable-gpu','--disable-dev-shm-usage']);page=browser.new_page(viewport=dict(width=1550,height=1000));page.on('pageerror',lambda e:errors.append(str(e)));page.set_default_timeout(30000)
    page.goto((ROOT/'visuals/index.html').as_uri(),wait_until='load');page.wait_for_function('!!FLOW.cache[document.getElementById("run").value]')
    for rid in [r['run'] for r in json.loads((A/'runs.json').read_text())]:
        page.select_option('#run',rid);page.wait_for_function('(rid)=>document.getElementById("status").textContent.startsWith(FLOW.cache[rid]?.summary.run_id)',arg=rid)
        page.select_option('#algorithm','Shadow');page.select_option('#snapmode','auto');page.fill('#step','1');page.locator('#step').dispatch_event('change');assert page.locator('#region option').count()==0
        page.fill('#step','501');page.locator('#step').dispatch_event('change');assert page.locator('#region option').count()>0
        assert '截止 #500' in page.inner_text('#lineage')
        old=int(page.input_value('#seek'));page.click('#next');assert int(page.input_value('#seek'))==old+1
        page.select_option('#snapmode','frozen');page.select_option('#snapshot',index=0);assert '截止 #250' in page.inner_text('#lineage')
        page.select_option('#entry',index=1);assert 'ORACLE REPLAY' in page.inner_text('#entryfacts')
        page.locator('#lineagecanvas').click(position=dict(x=80,y=80));assert page.input_value('#snapmode')=='frozen'
        page.select_option('#algorithm','A-final');assert page.locator('#region option').count()>0
        page.select_option('#algorithm','Shadow');page.select_option('#snapmode','auto');page.click('#case')
        if page.locator('#photo img').count():page.wait_for_function('document.querySelector("#photo img").complete&&document.querySelector("#photo img").naturalWidth>0')
        else:assert 'MISSING' in page.inner_text('#photo')
        if rid in ['odkcollect-Rep1','odkcollect-Rep2','activitydiary-Rep1','scarletnotes-Rep2','wikipedia-Rep2']:
            page.screenshot(path=str(A/('viewer-'+rid+'.png')),full_page=True)
        checks.append(dict(run=rid,auto_no_future_before_first_snapshot=True,causal_500_step_snapshot=True,step=True,frozen_snapshot=True,oracle_entry=True,lineage_click=True,baseline=True,available_image_loaded=True))
    page.select_option('#speed','70');old=int(page.input_value('#seek'));page.click('#play');page.wait_for_timeout(350);page.click('#play');assert int(page.input_value('#seek'))>old
    page.locator('#timeline').click(position=dict(x=550,y=30));page.set_viewport_size(dict(width=390,height=844));page.wait_for_timeout(100);assert not page.evaluate('document.documentElement.scrollWidth>innerWidth');page.screenshot(path=str(A/'viewer-mobile.png'),full_page=True)
    browser.close()
assert not errors,errors
(A/'browser-validation.json').write_text(json.dumps(dict(status='PASS',mode='file:// offline',checks=checks,playback=True,timeline_click=True,mobile_no_overflow=True,errors=errors),ensure_ascii=False,indent=2));print('BROWSER_PASS',len(checks))
