Files
workinf_Blender_Wasm/web/tests/e2e/upstream-blendfile-versioning.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

32 lines
2.9 KiB
TypeScript

import { expect, test } from '@playwright/test';
import path from 'node:path';
import fs from 'node:fs';
import { observeNative, captureNativeWorkflowState, performNativeAction, exposeWebTools } from '../fixtures/native-ui-workflow';
import { queryNativeJSON, readNativeHistory } from '../fixtures/native-modeling-workflow';
const sceneSource = 'import bpy,json\nprint(json.dumps([{\"name\":s.name,\"viewLayers\":[v.name for v in s.view_layers]} for s in bpy.data.scenes]))';
const cases = [
['sequence_editing/sequence.blend', 'sequence', '1', '1 RenderLayer'],
['io_tests/blend_geometry/all_quads.blend', 'all_quads', 'Scene', 'RenderLayer'],
['sequence_editing/effects/blends.blend', 'blends', 'Scene', 'ViewLayer'],
['sequence_editing/vse_load_meta_stack.blend', 'vse_load_meta_stack', 'Scene', 'ViewLayer'],
] as const;
test.afterEach(async ({ page }, info) => { await info.attach('native-state', { body: JSON.stringify(await captureNativeWorkflowState(page)), contentType: 'application/json' }); });
for (const [file, project, scene, viewLayer] of cases) test(`original ${project} opens through the product file input`, async ({ page }) => {
const fixture = path.resolve(import.meta.dirname, '../../../blender-5.2.0/tests/files', file);
test.setTimeout(180000); await observeNative(page); await page.goto('/');
await expect(page.getByTestId('engine-status')).toHaveText('Engine: new General project', { timeout: 60000 });
await performNativeAction(page, { type: 'openBlend' }, () => page.getByTestId('blend-file-input').setInputFiles(fixture));
await expect(page.locator('main.blender-app')).toHaveAttribute('data-project-id', project, { timeout: 30000 });
await expect(page.getByTestId('engine-status')).toContainText('SceneIR');
const { value } = await queryNativeJSON(page, sceneSource);
expect(value).toEqual([{ name: scene, viewLayers: [viewLayer] }]);
await exposeWebTools(page); const download = page.waitForEvent('download'); await page.getByRole('button', { name: '保存项目', exact: true }).click();
const saved = await download; const bytes = fs.readFileSync((await saved.path())!);
await performNativeAction(page, { type: 'openBlend' }, () => page.getByTestId('blend-file-input').setInputFiles({ name: `${project}-saved.blend`, mimeType: 'application/octet-stream', buffer: bytes }));
await expect(page.locator('main.blender-app')).toHaveAttribute('data-project-id', `${project}-saved`);
expect((await queryNativeJSON(page, sceneSource)).value).toEqual(value);
const history = await readNativeHistory(page);
await performNativeAction(page, { type: 'openBlend' }, () => page.getByTestId('blend-file-input').setInputFiles({ name: 'truncated.blend', mimeType: 'application/octet-stream', buffer: fs.readFileSync(fixture).subarray(0, 8) }), false);
expect((await queryNativeJSON(page, sceneSource)).value).toEqual(value); expect(await readNativeHistory(page)).toEqual(history);
});