feat: release v1.0.1 CADWorld 网站与 LeKiwi 智能抓放
web-platform-ci / Standalone decision service (no cloud credentials) (push) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled
lekiwi-compatibility / cpu-compatibility (push) Has been cancelled
web-platform-ci / Standalone decision service (no cloud credentials) (pull_request) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (pull_request) Has been cancelled
web-platform-ci / Playwright E2E (pull_request) Has been cancelled
lekiwi-compatibility / cpu-compatibility (pull_request) Has been cancelled
web-platform-ci / Standalone decision service (no cloud credentials) (push) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled
lekiwi-compatibility / cpu-compatibility (push) Has been cancelled
web-platform-ci / Standalone decision service (no cloud credentials) (pull_request) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (pull_request) Has been cancelled
web-platform-ci / Playwright E2E (pull_request) Has been cancelled
lekiwi-compatibility / cpu-compatibility (pull_request) Has been cancelled
集成同源 BYOK 会话隔离、精简模型设置、官方订阅入口和 HTTPS 发布运维;保留本地训练/调参与控制能力。同步 npm 版本及 CHANGELOG,记录公网真实 API 验收仍待用户凭据。
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { resolve } from 'node:path';
|
||||
import { writeFile } from 'node:fs/promises';
|
||||
|
||||
test('完整 CAD 主视口:60 秒渲染/物理性能记录(不承诺固定 FPS)', async ({ page }, info) => {
|
||||
const errors: string[] = [];
|
||||
page.on('pageerror', (error) => errors.push(error.message));
|
||||
await page.goto('/');
|
||||
const started = performance.now();
|
||||
await page
|
||||
.getByLabel('打开文件', { exact: true })
|
||||
.setInputFiles(resolve('build/lekiwi/lekiwi-v1.zip'));
|
||||
const dialog = page.getByRole('dialog', { name: '配置 URDF 仿真组件' });
|
||||
await expect(dialog).toBeVisible({ timeout: 30000 });
|
||||
await dialog.getByLabel('URDF 机器人 profile').selectOption('lekiwi-v1');
|
||||
await dialog.getByRole('button', { name: '转换并加载' }).click();
|
||||
await expect(page.getByRole('button', { name: '▶ 播放' })).toBeEnabled({ timeout: 60000 });
|
||||
const loadMs = performance.now() - started;
|
||||
await page.getByRole('button', { name: '▶ 播放' }).click();
|
||||
const result = await page.evaluate(async () => {
|
||||
const path = '/src/stores/useAppStore.ts';
|
||||
const { useAppStore } = (await import(
|
||||
/* @vite-ignore */ path
|
||||
)) as typeof import('../src/stores/useAppStore');
|
||||
const canvas = document.querySelector('main canvas') as HTMLCanvasElement;
|
||||
const gl = canvas.getContext('webgl2')!,
|
||||
ext = gl.getExtension('WEBGL_debug_renderer_info');
|
||||
const graphics = {
|
||||
size: [canvas.width, canvas.height],
|
||||
renderer: ext ? String(gl.getParameter(ext.UNMASKED_RENDERER_WEBGL)) : 'unknown',
|
||||
};
|
||||
const start = performance.now(),
|
||||
frames: number[] = [],
|
||||
steps: number[] = [];
|
||||
const longTasks: number[] = [];
|
||||
const observer = new PerformanceObserver((list) => {
|
||||
longTasks.push(...list.getEntries().map((e) => e.duration));
|
||||
});
|
||||
observer.observe({ type: 'longtask' });
|
||||
let previous = start;
|
||||
await new Promise<void>((resolve) => {
|
||||
const tick = (now: number) => {
|
||||
frames.push(now - previous);
|
||||
previous = now;
|
||||
steps.push(useAppStore.getState().stepMs);
|
||||
if (now - start >= 60000) resolve();
|
||||
else requestAnimationFrame(tick);
|
||||
};
|
||||
requestAnimationFrame(tick);
|
||||
});
|
||||
observer.disconnect();
|
||||
const p95 = (values: number[]) =>
|
||||
[...values].sort((a, b) => a - b)[Math.floor(values.length * 0.95)] ?? 0;
|
||||
const state = useAppStore.getState();
|
||||
return {
|
||||
graphics,
|
||||
frames: frames.length,
|
||||
fps: (1000 * frames.length) / (previous - start),
|
||||
frameP95Ms: p95(frames),
|
||||
stepP95Ms: p95(steps),
|
||||
longTasks,
|
||||
heap: state.snapshot?.wasmHeapBytes,
|
||||
simTime: state.snapshot?.time,
|
||||
diagnostic: state.diagnostic?.summary,
|
||||
};
|
||||
});
|
||||
await writeFile(
|
||||
info.outputPath('full-cad-performance.json'),
|
||||
JSON.stringify({ loadMs, ...result }, null, 2),
|
||||
);
|
||||
console.log('full CAD performance', { loadMs, ...result });
|
||||
await page.screenshot({ path: info.outputPath('full-cad.png') });
|
||||
expect(errors).toEqual([]);
|
||||
expect(result.diagnostic).toBeUndefined();
|
||||
expect(result.simTime).toBeGreaterThan(0);
|
||||
});
|
||||
Reference in New Issue
Block a user