Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer, web workflow engine and protocol, tooling, docs and task records. Large generated evidence, user-testing archives, build snapshots and imported test assets remain untracked. Co-Authored-By: Claude Code <noreply@anthropic.com>
60 lines
3.2 KiB
TypeScript
60 lines
3.2 KiB
TypeScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { test, expect } from "@playwright/test";
|
|
import { NativeUIWorkflow, observeNative } from "../fixtures/native-ui-workflow";
|
|
|
|
const root = path.resolve(import.meta.dirname, "../../..");
|
|
const fixture = path.join(root, "tests/files/web/basic_scene.blend");
|
|
|
|
test("probe menu access in both views then invoke pack", async ({ page }, testInfo) => {
|
|
test.setTimeout(180_000);
|
|
await observeNative(page);
|
|
await page.goto("/");
|
|
const flow = new NativeUIWorkflow(page, testInfo.outputPath("cases"));
|
|
await flow.command(() => page.getByTestId("blend-file-input").setInputFiles(fixture));
|
|
await expect(page.getByTestId("engine-status")).toContainText("SceneIR", { timeout: 60000 });
|
|
const log: any = {};
|
|
const probeHit = () => page.evaluate(() => {
|
|
const btn = Array.from(document.querySelectorAll('nav.menu-bar button')).find(b => b.getAttribute('aria-label') === '文件') as HTMLElement | undefined;
|
|
if (!btn) return { error: 'menu button missing' };
|
|
const r = btn.getBoundingClientRect();
|
|
const stack = document.elementsFromPoint(r.left + r.width / 2, r.top + r.height / 2).slice(0, 5).map(el => `${el.tagName}.${(el as HTMLElement).className}`.slice(0, 60));
|
|
return { rect: { x: r.left, y: r.top, w: r.width, h: r.height }, stack };
|
|
});
|
|
const openFileMenu = async () => {
|
|
await page.getByRole('button', { name: '文件', exact: true }).click({ timeout: 8000 });
|
|
await page.waitForTimeout(300);
|
|
return page.locator('[role="menu"]').evaluateAll(items => items.map(i => i.getAttribute('aria-label')));
|
|
};
|
|
try {
|
|
log.hitDesktopView = await probeHit();
|
|
log.menusDesktopView = await openFileMenu().catch((e: any) => `ERR:${e.message.split('\n')[0]}`);
|
|
const toolsToggle = page.getByTestId('native-web-tools-toggle');
|
|
log.hasToggle = await toolsToggle.count();
|
|
if (log.hasToggle) {
|
|
await toolsToggle.click({ force: true });
|
|
await page.waitForTimeout(500);
|
|
}
|
|
log.hitToolsView = await probeHit();
|
|
log.menusToolsView = await openFileMenu().catch((e: any) => `ERR:${e.message.split('\n')[0]}`);
|
|
await page.evaluate(() => {
|
|
const w = (window as any); w.__probeSent = [];
|
|
const worker = w.__nativeWorkflowEngine as Worker; const orig = worker.postMessage.bind(worker);
|
|
worker.postMessage = ((...a: any[]) => { w.__probeSent.push(a[0]?.cmd ?? a[0]?.command?.type ?? '?'); return orig(...(a as [any])); }) as any;
|
|
});
|
|
const external = page.getByRole('menuitem', { name: '外部数据', exact: true });
|
|
log.externalCount = await external.count();
|
|
if (log.externalCount) {
|
|
await external.click({ force: true });
|
|
await page.waitForTimeout(300);
|
|
const pack = page.getByRole('menuitem', { name: '打包资源', exact: true });
|
|
log.packDisabled = await pack.isDisabled();
|
|
await pack.click({ force: true });
|
|
await page.waitForTimeout(4000);
|
|
log.sent = await page.evaluate(() => (window as any).__probeSent);
|
|
log.status = await page.getByTestId('engine-status').innerText();
|
|
}
|
|
} catch (error: any) { log.error = String(error?.message ?? error).slice(0, 400); }
|
|
fs.writeFileSync("/tmp/pack-menu-probe.json", JSON.stringify(log, null, 2));
|
|
});
|