Files
workinf_Blender_Wasm/web/tests/e2e/native-active-gesture-guard.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

25 lines
2.8 KiB
TypeScript

import { expect, test } from '@playwright/test';
import path from 'node:path';
import fs from 'node:fs';
import { observeNative, exposeWebTools, captureNativeWorkflowState, performNativeAction } from '../fixtures/native-ui-workflow';
import { nativeRequest, queryNativeJSON, readModelingMain, readNativeHistory, focusNativeViewport, waitNativeModal } from '../fixtures/native-modeling-workflow';
import { openFromUI } from '../fixtures/wasm-console-workflow';
const fixture = path.resolve(import.meta.dirname, '../../..', process.env.WBV2_CASE_FIXTURE ?? 'blender-5.2.0/tests/files/io_tests/blend_geometry/all_quads.blend');
test.afterEach(async ({ page }, info) => { fs.writeFileSync(info.outputPath('active-gesture-state.json'), JSON.stringify(await captureNativeWorkflowState(page), null, 2)); });
test('Native active transform refuses unsafe Main mutation', async ({ page }) => {
test.setTimeout(180000); await observeNative(page); await page.goto('/');
await expect.poll(() => page.evaluate(() => Array.isArray((window as any).__nativeWorkflowMain?.nodes)), { timeout: 60000 }).toBe(true);
await exposeWebTools(page); await openFromUI(page, () => page.getByTestId('blend-file-input').setInputFiles(fixture));
await performNativeAction(page, { command: 'createPrimitive' }, () => page.getByRole('button', { name: '添加立方体', exact: true }).click());
const { value: name } = await queryNativeJSON(page, "import bpy,json\nprint(json.dumps(bpy.context.view_layer.objects.active.name))"); expect(typeof name).toBe('string');
const { canvas, point } = await focusNativeViewport(page); const before = await readModelingMain(page, name);
const history = await readNativeHistory(page), gpu = await page.evaluate(() => (window as any).__nativeWorkflowGPU);
await canvas.focus(); const invoked = await nativeRequest(page, { type: 'gpuUI', op: 'invoke', session: gpu.session, ownerGeneration: gpu.ownerGeneration, operator: 'transform.translate', properties: {}, areaType: 'VIEW_3D', mode: 'OBJECT' });
await waitNativeModal(page, true); await page.mouse.move(point.x + 60, point.y + 35); await waitNativeModal(page, true, invoked.requestId);
await expect(nativeRequest(page, { type: 'jsonCommand', cmd: 'pythonExec', params: { source: "import bpy; bpy.context.scene['wbv2_guard_should_not_run'] = True", filename: 'ActiveGestureGuard.py', console: false } })).rejects.toThrow(/NATIVE_GESTURE_ACTIVE/);
await page.keyboard.press('Escape'); await waitNativeModal(page, false);
expect((await readModelingMain(page, name)).value).toEqual(before.value);
const after = await readNativeHistory(page); expect(after.cursor).toBe(history.cursor); expect(after.entries).toEqual(history.entries);
expect((await queryNativeJSON(page, "import bpy,json\nprint(json.dumps('wbv2_guard_should_not_run' in bpy.context.scene))")).value).toBe(false);
});