import {chromium} from 'file:///C:/Users/JSHY/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright/index.mjs'; import fs from 'node:fs/promises'; import assert from 'node:assert/strict'; const base='http://127.0.0.1:4183'; const out='docs/development-board-20261108'; const browser=await chromium.launch({executablePath:'C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe',headless:true}); const report={ok:false,checkedAt:new Date().toISOString(),responseOverrides:0,productionWrites:0,paidCalls:0,checks:[]}; try{ const context=await browser.newContext({viewport:{width:390,height:844},isMobile:true,hasTouch:true}); const p=await context.newPage(); await p.goto(base+'/industry?tab=development');await p.locator('[data-development-copy]').waitFor(); const cdp=await context.newCDPSession(p),info=await cdp.send('Target.getTargetInfo'); await cdp.send('Browser.setPermission',{permission:{name:'clipboard-write'},setting:'denied',origin:base,browserContextId:info.targetInfo.browserContextId}); assert.equal(await p.evaluate(()=>navigator.permissions.query({name:'clipboard-write'}).then(r=>r.state)),'denied'); await p.locator('[data-development-copy]').click(); await p.locator('.dr-copy[open]').waitFor(); const copy=await p.locator('.dr-copy textarea').inputValue(); assert.ok(copy.includes('KfMaterial/')&©.includes('KfSource/')&©.includes('待验证设想')); await p.locator('.dr-copy>button').click(); const range=await p.locator('.dr-copy textarea').evaluate(e=>({start:e.selectionStart,end:e.selectionEnd,length:e.value.length})); assert.equal(range.start,0);assert.equal(range.end,range.length); report.checks.push('real clipboard permission denial opens complete selectable brief'); await p.screenshot({path:out+'/copy-fallback-390.png'}); await p.keyboard.press('Escape');assert.equal(await p.locator('.dr-copy[open]').count(),0); report.checks.push('native Escape closes text dialog'); await p.locator('.dr-reference').first().click();await p.locator('.dr-detail[open]').waitFor(); await p.keyboard.press('Escape');assert.equal(await p.locator('.dr-detail[open]').count(),0); report.checks.push('native Escape closes source dialog'); for(const [tab,selector]of [['insights','.workshop-analysis'],['policies','.policy-applications'],['rankings','.ranking-research']]){ await p.goto(base+'/industry?tab='+tab); await p.waitForFunction(async tab=>{const el=document.querySelector('kf-app')?.renderRoot.querySelector('view-industry');if(!el)return false;await el.updateComplete;return el._tab===tab&&!el._loading&&!!el._data?.generation&&!el._error;},tab); await p.locator('view-industry').evaluate(async e=>{await e.updateComplete;return true;}); await p.waitForFunction(()=>{const el=document.querySelector('kf-app')?.renderRoot.querySelector('view-industry');return !el?false:!el._loading&&!!el._data;}); const state=await p.locator('view-industry').evaluate(e=>({tab:e._tab,ok:!!e._data&&!e._error,generation:e._data?.generation||null,loading:e._loading,error:e._error})); assert.equal(state.tab,tab);assert.ok(state.ok,JSON.stringify(state));report.checks.push('existing '+tab+' loads actual data'); } await p.goto(base+'/industry?tab=insights');await p.locator('.sf-filters').waitFor(); await p.setViewportSize({width:1440,height:900}); await p.locator('view-industry .p-actions a').filter({hasText:'研发参考'}).click(); await p.waitForURL(/tab=development/);await p.locator('industry-development .dr-intro').waitFor(); report.checks.push('existing innovation page links to development references'); report.ok=true; }catch(e){report.error=e.stack;process.exitCode=1;console.error(e);} finally{await browser.close();await fs.writeFile(out+'/supplement-acceptance.json',JSON.stringify(report,null,2)+'\n');console.log(JSON.stringify(report));}