customer-stream-connect.mjs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import assert from 'node:assert/strict';
  2. import { mkdir, readFile, writeFile } from 'node:fs/promises';
  3. import { chromium } from 'playwright';
  4. const accounts = JSON.parse(await readFile(new URL('../../.work/frontend-accounts.json', import.meta.url), 'utf8'));
  5. const base = process.env.FRONTEND_URL || 'http://127.0.0.1:18762';
  6. const browser = await chromium.launch({ headless: true, executablePath: process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE });
  7. const page = await browser.newPage();
  8. page.setDefaultTimeout(10000);
  9. const started = Date.now(), errors = [];
  10. let opening, requests = 0, token;
  11. page.on('pageerror', error => errors.push(error.message));
  12. page.on('request', request => {
  13. if (/\/(openapi|admin)\//.test(request.url())) requests++;
  14. if (request.url().endsWith('/events')) opening = Date.now();
  15. });
  16. const timeout = setTimeout(() => { void browser.close(); }, 30000);
  17. try {
  18. await page.goto(`${base}/#/customer/login`);
  19. await page.getByLabel('账户', { exact: true }).fill('customer01');
  20. await page.getByLabel('密码', { exact: true }).fill(accounts.password);
  21. await page.getByRole('checkbox').check();
  22. const login = page.waitForResponse(response => response.request().method() === 'POST' && response.url().endsWith('/auth/sessions'));
  23. const stream = page.waitForResponse(response => response.url().endsWith('/events'));
  24. await page.getByRole('button', { name: '登录并继续', exact: true }).click();
  25. token = (await (await login).json()).access_token;
  26. const connected = await stream;
  27. const connectMs = Date.now() - opening;
  28. assert.equal(connected.status(), 200);
  29. assert.ok(connectMs < 5000, '空闲会话应在5秒内收到响应,无需等待15秒周期心跳');
  30. await page.waitForFunction(() => [...document.querySelectorAll('.mobile button')].some(button => button.textContent === '发送' && !button.disabled));
  31. assert.deepEqual(errors, []);
  32. requests++;
  33. const logout = await page.request.delete(`${base}/openapi/v1/auth/sessions/current`, { headers: { Authorization: `Bearer ${token}` } });
  34. assert.equal(logout.status(), 204);
  35. token = null;
  36. await page.waitForURL('**/#/customer/login');
  37. await mkdir(new URL('../../.work/frontend-verification/', import.meta.url), { recursive: true });
  38. const report = { date: new Date().toISOString(), connectMs, seconds: (Date.now() - started) / 1000, requestCount: requests, browserErrors: errors, generatedModelCalls: 0, durationLimitSeconds: 30 };
  39. await writeFile(new URL('../../.work/frontend-verification/customer-stream-connect.json', import.meta.url), JSON.stringify(report, null, 2));
  40. console.log(JSON.stringify(report));
  41. } finally {
  42. clearTimeout(timeout);
  43. if (token) await page.request.delete(`${base}/openapi/v1/auth/sessions/current`, { headers: { Authorization: `Bearer ${token}` } });
  44. await browser.close();
  45. }