Files
workinf_Blender_Wasm/web/tests/e2e/modal-replica-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

61 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, readNativeBlend, readNativeHistory } from '../fixtures/native-modeling-workflow';
const fixture = path.resolve(import.meta.dirname, '../../../tests/files/web/basic_scene.blend');
/* Isolation: press `g` right after focusing the viewport, then again after the
* modeling / history / blend reads, so the step that swallows input is visible. */
test('isolate which prerequisite loses the g key', async ({ page }) => {
const rec: Record<string, unknown> = {};
const gpu = () => page.evaluate(() => {
const g = (window as any).__nativeWorkflowGPU;
return g ? { active: g.modalActive, ready: g.displayAcknowledged, owner: g.ownerGeneration, req: g.requestId } : null;
});
const pressG = async (label: string) => {
const canvas = page.locator('canvas[aria-label="Blender desktop"]').first();
await canvas.focus();
const series: unknown[] = [];
await page.keyboard.press('g');
for (let i = 0; i < 15; i++) { await page.waitForTimeout(100); series.push({ t: (i + 1) * 100, ...(await gpu()) }); }
const sawModal = series.some((s: any) => s.active === true);
rec[label] = { sawModal, maxActive: series.filter((s: any) => s.active).length, series };
if (sawModal) { await page.keyboard.press('Escape'); await page.waitForTimeout(1200); }
rec[`${label}_afterEscape`] = await gpu();
return sawModal;
};
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));
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.addedNames = added.map((node: any) => node.name);
const { canvas } = await focusNativeViewport(page);
rec.gpuAfterFocus = await gpu();
rec.step1_rightAfterFocus = await pressG('step1');
rec.gpuAfterStep1 = await gpu();
await readModelingMain(page, name);
rec.gpuAfterModelingRead = await gpu();
rec.step2_afterModelingRead = await pressG('step2');
rec.gpuAfterStep2 = await gpu();
await readNativeHistory(page);
rec.gpuAfterHistory = await gpu();
rec.step3_afterHistory = await pressG('step3');
rec.gpuAfterStep3 = await gpu();
await readNativeBlend(page);
rec.gpuAfterBlendRead = await gpu();
rec.step4_afterBlendRead = await pressG('step4');
rec.gpuFinal = await gpu();
console.log(JSON.stringify({ summary: {
step1: rec.step1_rightAfterFocus, step2: rec.step2_afterModelingRead, step3: rec.step3_afterHistory, step4: rec.step4_afterBlendRead,
owners: [rec.gpuAfterFocus, rec.gpuAfterStep1, rec.gpuAfterModelingRead, rec.gpuAfterStep2, rec.gpuAfterHistory, rec.gpuAfterStep3, rec.gpuAfterBlendRead, rec.gpuFinal],
} }, null, 1));
});