from playwright.sync_api import sync_playwright
errs=[]
with sync_playwright() as p:
    b=p.chromium.launch(); pg=b.new_page(viewport={'width':1200,'height':800})
    pg.on('pageerror',lambda e:errs.append('PAGEERR '+str(e)))
    pg.on('console',lambda m: errs.append('CONSOLE '+m.text) if m.type=='error' else None)
    pg.goto('http://localhost:3456/'); pg.wait_for_selector('form[data-form=login]')
    print('login screen ok; title:',pg.title())
    def login(m):
        pg.fill('input[name=mobile]',m); pg.fill('input[name=password]','adminpass' if m=='9000000000' else 'secret1'); pg.click('form[data-form=login] button')
        pg.wait_for_selector('.side')
    # --- retailer flow
    login('9333333333'); pg.wait_for_selector('.kpi'); print('retailer nav:',[a.inner_text() for a in pg.query_selector_all('.side a')])
    pg.click('#nav-recharge'); pg.wait_for_selector('#rf')
    pg.select_option('select[name=operator]','JIO'); pg.fill('input[name=number]','9876543210'); pg.fill('input[name=amount]','100')
    print('calc:',pg.inner_text('#rcalc'))
    pg.click('#rf button'); pg.wait_for_selector('.toast.ok'); print('toast:',pg.inner_text('.toast.ok'))
    pg.wait_for_timeout(700); print('recent row:',pg.inner_text('#recent tr:nth-child(2)'))
    pg.click('#nav-history'); pg.wait_for_selector('table td'); print('history first row:',pg.inner_text('.card:nth-of-type(2) tr:nth-child(2)')[:80])
    pg.click('#nav-account'); pg.click('form[data-form=apikey] button'); pg.wait_for_selector('pre'); 
    print('api docs has curl:', 'curl' in pg.inner_text('pre'))
    pg.click('[data-act=logout]'); pg.wait_for_selector('form[data-form=login]')
    # --- admin flow
    login('9000000000'); pg.wait_for_selector('.kpi'); print('admin nav:',[a.inner_text() for a in pg.query_selector_all('.side a')])
    print('admin dashboard fleet shows SIM:', 'JIO-01' in pg.inner_text('#view'))
    for t in ['users','sims','operators','review','settings','audit','complaints','funds','wallet']:
        pg.click(f'#nav-{t}'); pg.wait_for_timeout(250)
        assert 'class="card err"' not in pg.inner_html('#view'), t
        print('  view ok:',t)
    pg.click('#nav-users'); pg.wait_for_selector('table tr:nth-child(2)')
    pg.click('[data-act=urates]'); pg.wait_for_selector('dialog[open] table'); pg.fill('dialog input[name=pct]','3.5'); pg.click('dialog [data-act=ratesave]'); pg.wait_for_selector('.toast.ok'); print('rate saved ok'); pg.click('dialog [data-act=close]')
    pg.click('#nav-operators'); pg.wait_for_selector('[data-act=opsave]'); pg.click('[data-act=opsave]'); pg.wait_for_selector('.toast.ok'); print('operator row save ok')
    pg.set_viewport_size({'width':390,'height':800}); pg.click('#nav-dashboard'); pg.wait_for_timeout(300)
    print('mobile: horizontal overflow?', pg.evaluate('document.documentElement.scrollWidth>window.innerWidth+2'))
    pg.screenshot(path='/tmp/admin_mobile.png'); pg.set_viewport_size({'width':1200,'height':800}); pg.click('#nav-dashboard'); pg.wait_for_timeout(300); pg.screenshot(path='/tmp/admin_dash.png')
    # --- XSS check: user name with markup must be escaped
    b.close()
print('JS errors:',errs or 'none')
