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>
68 lines
3.4 KiB
TypeScript
68 lines
3.4 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import path from 'node:path';
|
|
import { observeNative, performNativeAction, exposeWebTools } from '../fixtures/native-ui-workflow';
|
|
import { webMain } from '../fixtures/console-main-workflow';
|
|
import { openFromUI } from '../fixtures/wasm-console-workflow';
|
|
import { focusNativeViewport, readModelingMain } from '../fixtures/native-modeling-workflow';
|
|
|
|
const fixture = path.resolve(import.meta.dirname, '../../../tests/files/web/basic_scene.blend');
|
|
|
|
/* Which editor owns the key after createPrimitive? Record the native active
|
|
* area at each step, then verify Tab and g once the viewport is clicked. */
|
|
test('native keymap probe: active editor and Tab/g', async ({ page }) => {
|
|
const rec: Record<string, unknown> = {};
|
|
const editor = () => page.evaluate(() => {
|
|
const context = (window as any).__nativeWorkflowEditor?.context;
|
|
return context ? { area: context.activeAreaId, editor: context.activeEditor, mode: context.mode, object: context.activeObjectId } : null;
|
|
});
|
|
const gpu = () => page.evaluate(() => { const g = (window as any).__nativeWorkflowGPU; return g ? { active: g.modalActive, owner: g.ownerGeneration, req: g.requestId } : null; });
|
|
await observeNative(page);
|
|
await page.goto('/');
|
|
await expect.poll(() => page.evaluate(() => Array.isArray((window as any).__nativeWorkflowMain?.nodes)), { timeout: 60_000 }).toBe(true);
|
|
await exposeWebTools(page);
|
|
await openFromUI(page, () => page.getByTestId('blend-file-input').setInputFiles(fixture));
|
|
rec.editorAfterOpen = await editor();
|
|
const opened = await webMain(page);
|
|
await performNativeAction(page, { command: 'createPrimitive' }, () => page.getByRole('button', { name: '添加立方体', exact: true }).click());
|
|
const added = (await webMain(page)).nodes.filter((node: any) => !opened.nodes.some((previous: any) => previous.id === node.id));
|
|
const name = added[0]?.name;
|
|
rec.name = name;
|
|
rec.editorAfterAdd = await editor();
|
|
rec.gpuAfterAdd = await gpu();
|
|
const { canvas, point } = await focusNativeViewport(page);
|
|
rec.editorAfterFocus = await editor();
|
|
rec.gpuAfterFocus = await gpu();
|
|
const read = async (label: string) => {
|
|
const value = await readModelingMain(page, name).catch((error: unknown) => ({ error: String(error).slice(0, 200) }));
|
|
rec[label] = (value as any)?.value ? { mode: (value as any).value.mode, location: (value as any).value.location } : value;
|
|
};
|
|
rec.editorAfterRead = await editor();
|
|
await canvas.focus();
|
|
await page.keyboard.press('Tab');
|
|
await page.waitForTimeout(2500);
|
|
await read('afterTabNoClick');
|
|
rec.editorAfterTabNoClick = await editor();
|
|
await page.mouse.click(point.x, point.y);
|
|
await page.waitForTimeout(1500);
|
|
rec.editorAfterViewportClick = await editor();
|
|
await canvas.focus();
|
|
await page.keyboard.press('Tab');
|
|
await page.waitForTimeout(2500);
|
|
await read('afterTabWithClick');
|
|
rec.editorAfterTabWithClick = await editor();
|
|
await page.keyboard.press('Tab');
|
|
await page.waitForTimeout(2500);
|
|
await page.mouse.click(point.x, point.y);
|
|
await page.waitForTimeout(800);
|
|
await canvas.focus();
|
|
await page.keyboard.press('g');
|
|
await page.waitForTimeout(900);
|
|
rec.gpuDuringG = await gpu();
|
|
rec.editorDuringG = await editor();
|
|
await page.keyboard.press('Escape');
|
|
await page.waitForTimeout(1500);
|
|
rec.gpuAfterEscape = await gpu();
|
|
await read('afterGxEscape');
|
|
console.log(JSON.stringify(rec, null, 1));
|
|
});
|