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