_r189_189_admin.cjs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. // R162: 189 admin-live UI E2E kick/read(String.raw 保反斜杠路径,修复 Location not found)
  2. const BASE = process.env.BASE_189 || 'http://192.168.16.189:4090';
  3. const AUTH = 'Basic ' + Buffer.from('opencode:' + (process.env.OPENCODE_SERVER_PASSWORD || 'IwinTrue@123')).toString('base64');
  4. const H = { Authorization: AUTH, 'Content-Type': 'application/json' };
  5. const CWD = String.raw`C:\code\cfc`;
  6. const LOC = '?location%5Bdirectory%5D=' + encodeURIComponent(CWD);
  7. const LOG = String.raw`C:\code\cfc\_r189_admin-live_test.log`;
  8. const SLEEP = ms => new Promise(r => setTimeout(r, ms));
  9. function buildKickCmd() {
  10. return [
  11. 'cd ' + CWD,
  12. 'if (Test-Path ' + LOG + ') { Remove-Item ' + LOG + ' -Force }',
  13. `Start-Process -FilePath cmd.exe -ArgumentList '/c','cd /d ${CWD}\\tests && set PLAYWRIGHT_HTML_REPORT=false && npx playwright test -c playwright.config.live.js --project=admin-desktop --reporter=line > ${LOG} 2>&1' -WindowStyle Hidden -PassThru | Select-Object Id`,
  14. 'start-sleep -Seconds 3',
  15. 'echo KICKED'
  16. ].join('; ');
  17. }
  18. function buildReadCmd() {
  19. return [
  20. 'echo READ_BEGIN',
  21. 'if (Test-Path ' + LOG + ') { Get-Content ' + LOG + ' -Tail 200 }',
  22. 'if (Test-Path ' + LOG + '.err) { echo ERR_BEGIN; Get-Content ' + LOG + '.err -Tail 30 }',
  23. 'echo READ_END'
  24. ].join('; ');
  25. }
  26. async function j(url, opt) {
  27. try {
  28. const r = await fetch(url, Object.assign({ headers: H }, opt));
  29. const t = await r.text();
  30. try { return { status: r.status, json: JSON.parse(t) }; } catch { return { status: r.status, text: t }; }
  31. } catch (e) { return { status: 0, err: e.message }; }
  32. }
  33. async function openShell(cmd, capMs = 30000) {
  34. const cr = await j(BASE + '/api/shell' + LOC, { method: 'POST', body: JSON.stringify({ command: cmd, cwd: CWD }) });
  35. const cj = (cr.json) || {};
  36. const id = (cj.data && cj.data.id) || cj.id;
  37. if (!id) return { err: 'create failed ' + cr.status + ' ' + JSON.stringify(cj).slice(0, 200), id: null };
  38. const t0 = Date.now();
  39. while (Date.now() - t0 < capMs) {
  40. await SLEEP(2000);
  41. const s = await j(BASE + '/api/shell/' + id + LOC);
  42. const d = (s.json && s.json.data) || null;
  43. if (d && d.status && d.status !== 'running') return { id, status: d.status };
  44. if (!d) continue;
  45. }
  46. return { id, status: 'timeout' };
  47. }
  48. (async () => {
  49. const mode = process.argv[2] || 'kick';
  50. if (mode === 'kick') {
  51. const k = await openShell(buildKickCmd(), 30000);
  52. console.log('KICK', k.err || ('id=' + k.id + ' status=' + k.status));
  53. return;
  54. }
  55. const r = await openShell(buildReadCmd(), 30000);
  56. if (r.err) { console.log('READ_ERR', r.err); process.exit(1); }
  57. const o = await j(BASE + '/api/shell/' + r.id + '/output' + LOC + '&limit=200000');
  58. console.log('OUT_BEGIN');
  59. console.log((o.json && o.json.data && o.json.data.output) || '(empty)');
  60. console.log('OUT_END');
  61. })().catch(e => { console.error('ERR', e.message); process.exit(1); });