Files
workinf_Blender_Wasm/web/tests/e2e/b3-pack-menu-probe.spec.ts
mes123456 f3e21c6b98
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
chore: checkpoint web Blender migration source, tools and docs
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>
2026-11-10 11:18:01 +08:00

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));
});