#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""验收 Demo：合格流程可提交 / 缺项被拦 / 待办自动生成与确认生效 / 不落盘 / 0 报错。"""
import sys
from playwright.sync_api import sync_playwright

F = '/Users/liuxinyuan/Desktop/Hermes输出-工作类/产品说明/销售活动录入_Demo.html'
ok = True
def chk(label, cond, detail=''):
    global ok
    print('  %s %-44s %s' % ('✅' if cond else '❌', label, detail))
    if not cond:
        ok = False

with sync_playwright() as p:
    br = p.chromium.launch(channel='chrome', headless=True)
    pg = br.new_page(viewport={'width': 1200, 'height': 1100})
    errs, reqs = [], []
    pg.on('pageerror', lambda e: errs.append(str(e)))
    pg.on('request', lambda r: reqs.append(r.url) if r.url.startswith('http') else None)
    pg.goto('file://' + F, wait_until='load')
    pg.wait_for_timeout(900)

    print('① 初始状态')
    chk('品牌页眉/页脚', pg.evaluate("() => !!document.querySelector('.bior-header') && !!document.querySelector('.bior-footer')"))
    chk('订单演示数据 3 条', pg.evaluate("() => document.querySelectorAll('#ordlist .ord').length") == 3)
    chk('未填时待办区为空态', '会出现自动生成的待办' in pg.evaluate("() => document.getElementById('todos').innerText"))

    print('\n② 空表提交 → 应被拦并逐条提示')
    pg.evaluate("() => doSubmit()")
    pg.wait_for_timeout(400)
    res = pg.evaluate("() => document.getElementById('res').innerText.replace(/\\s+/g,' ')")
    chk('弹出校验失败', '提交未通过' in res, res[:64])
    for kw in ['客户', '活动形式', '采购跟进细分', '下一步计划']:
        chk('提示含「%s」' % kw, kw in res)
    chk('未显示活动 JSON', pg.evaluate("() => document.getElementById('out').style.display") == 'none')

    print('\n③ 一键填充示例 → 待办应自动生成')
    pg.evaluate("() => fillDemo()")
    pg.wait_for_timeout(500)
    chk('订单已勾选 1 张', pg.evaluate("() => document.querySelectorAll('#ordlist input:checked').length") == 1)
    n_todo = pg.evaluate("() => document.querySelectorAll('#todos .todo').length")
    chk('自动生成 2 条待办', n_todo == 2, '%d 条' % n_todo)
    chk('待办显示来源（问题现象/下一步计划）', '问题现象' in pg.evaluate("() => document.getElementById('todos').innerText"))
    chk('竞品价格框因勾选而显示', pg.evaluate("() => document.getElementById('priceBox').style.display") != 'none')

    print('\n④ 取消一条待办 → 只提交确认的')
    pg.evaluate("() => { const c=document.querySelectorAll('#todos input[type=checkbox]')[1]; c.checked=false; c.dispatchEvent(new Event('change',{bubbles:true})); }")
    pg.wait_for_timeout(400)
    pg.evaluate("() => doSubmit()")
    pg.wait_for_timeout(500)
    res = pg.evaluate("() => document.getElementById('res').innerText.replace(/\\s+/g,' ')")
    chk('提交成功', '提交成功' in res, res[:70])
    js = pg.evaluate("() => document.getElementById('out').textContent")
    chk('JSON 里 todos 只剩 1 条', '"todos"' in js and js.count('"src"') == 1, 'src 出现 %d 次' % js.count('"src"'))
    chk('JSON 含订单号（虚构）', 'ZHBR26xxxxx01' in js)
    chk('JSON channel=offline', '"channel": "offline"' in js)
    chk('JSON params 解析为 2 条', js.count('"desc"') == 2, 'desc 出现 %d 次' % js.count('"desc"'))
    chk('JSON prices 解析为 1 条', js.count('"brand"') == 1)

    print('\n⑤ 清空 → 恢复空态')
    pg.evaluate("() => clearAll()")
    pg.wait_for_timeout(400)
    chk('客户已清空', pg.evaluate("() => document.getElementById('customer').value") == '')
    chk('待办区回到空态', '会出现自动生成的待办' in pg.evaluate("() => document.getElementById('todos').innerText"))

    print('\n⑥ 不落盘 / 不联网 / 0 报错')
    chk('localStorage 为空', pg.evaluate("() => localStorage.length") == 0, pg.evaluate("() => String(localStorage.length)"))
    chk('无 http 请求发出', len(reqs) == 0, str(reqs[:2]))
    src = pg.content()
    for tok in ['localStorage', 'sessionStorage', 'fetch(', 'XMLHttpRequest', 'sendBeacon']:
        n = src.count(tok)
        chk('源码 %s 计数 0' % tok, n == 0, str(n))
    chk('0 JS 错误', len(errs) == 0, str(errs[:2]))
    pg.screenshot(path='/tmp/demo_full.png', full_page=True)
    br.close()

print('\n%s' % ('✅ 全部通过' if ok else '❌ 有失败项'))
sys.exit(0 if ok else 1)
