"""CPU-only browser QA; real file://, network disabled, real controls and pictures."""
import json
from pathlib import Path
from playwright.sync_api import sync_playwright

ROOT=Path(__file__).resolve().parents[1]
def main():
    result=dict(status='RUNNING',tests=[],errors=[],external_requests=[])
    def check(name,detail=True):result['tests'].append(dict(check=name,status='PASS',detail=detail))
    with sync_playwright() as p:
        browser=p.chromium.launch(headless=True,args=['--disable-gpu','--disable-dev-shm-usage'])
        ctx=browser.new_context(viewport={'width':1480,'height':1050},offline=True)
        page=ctx.new_page();page.on('pageerror',lambda e:result['errors'].append(str(e)))
        page.on('request',lambda r:result['external_requests'].append(r.url) if r.url.startswith(('http:','https:')) else None)
        page.goto((ROOT/'visuals/index.html').as_uri(),wait_until='load',timeout=120000)
        page.wait_for_function('!!window.RESEARCH',timeout=120000)
        assert page.evaluate('RESEARCH.DATA.runs.length')==10
        assert page.evaluate('RESEARCH.DATA.runs.reduce((n,r)=>n+r.occurrences.length,0)')==1967
        check('offline_file_initialization',dict(runs=10,occurrences=1967))
        for cid in page.evaluate('RESEARCH.DATA.runs.flatMap(r=>r.cases).map(c=>c.id)'):
            page.evaluate('(c)=>RESEARCH.caseChoose(c)',cid)
            page.wait_for_function("[...document.querySelectorAll('#photos img')].every(i=>i.complete&&i.naturalWidth>0)")
            assert 'NA' in page.locator('#inventory').inner_text()
            assert page.locator('#case-note').inner_text()
            check('case_'+cid,page.evaluate('RESEARCH.getState()'))
        for rid in page.evaluate('RESEARCH.DATA.runs.map(r=>r.id)'):
            page.select_option('#run',rid)
            for group in page.locator('#group option').evaluate_all('(a)=>a.map(x=>x.value)'):
                page.select_option('#group',group)
                for method in ['B','A2','A5','A10','A20']:
                    page.select_option('#method',method)
                    assert page.locator('#trace button').count()>0
                    page.click('#next');page.click('#prev')
                for c in page.locator('#checkpoint option').evaluate_all('(a)=>a.map(x=>x.value).filter(Boolean)'):
                    page.select_option('#checkpoint',c)
                    assert '只用过去' in page.locator('#cp-content').inner_text()
                    assert not page.locator('#future').is_visible()
                    page.check('#show-future');assert page.locator('#future').is_visible()
                    page.uncheck('#show-future')
                page.select_option('#share-level','L1');page.select_option('#share-level','L2')
                check(rid+'_'+group+'_methods_checkpoints_sharing')
        page.evaluate("RESEARCH.caseChoose('odk-r1-late-checkbox')")
        page.screenshot(path=str(ROOT/'evidence/viewer-desktop.png'),full_page=True)
        page.select_option('#method','A20');old=page.evaluate('RESEARCH.getState().step');page.click('#play')
        page.wait_for_function('(x)=>RESEARCH.getState().step>x',arg=old,timeout=5000);page.click('#play')
        check('real_trace_playback_advances')
        assert page.evaluate('RESEARCH.DATA.runs.every(r=>r.occurrences.every(o=>Object.values(o.segments).every(s=>s.ids.every(t=>!!r.events[t]))))')
        check('all_occurrence_step_references_resolve')
        ctx.close()
        mob=browser.new_context(viewport={'width':390,'height':844},is_mobile=True,offline=True);mp=mob.new_page()
        mp.on('pageerror',lambda e:result['errors'].append(str(e)))
        mp.goto((ROOT/'visuals/index.html').as_uri()+'#odk-r2-checkbox-delete',wait_until='load',timeout=120000)
        mp.wait_for_function('!!window.RESEARCH',timeout=120000)
        mp.wait_for_function("[...document.querySelectorAll('#photos img')].every(i=>i.complete&&i.naturalWidth>0)")
        assert mp.evaluate('innerWidth===390 && document.documentElement.scrollWidth<=391'),mp.evaluate('[document.documentElement.scrollWidth,innerWidth]')
        mp.screenshot(path=str(ROOT/'evidence/viewer-mobile.png'),full_page=True)
        check('mobile_390px_no_overflow')
        mob.close();browser.close()
    assert not result['errors'],result['errors'];assert not result['external_requests'],result['external_requests']
    result['status']='PASS';(ROOT/'evidence/browser-verification.json').write_text(json.dumps(result,ensure_ascii=False,indent=2)+'\n')
    print('PASS',len(result['tests']),'checks; file:// offline, CPU-only browser; no external requests')

if __name__=='__main__':main()
