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>
32 lines
2.9 KiB
TypeScript
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);
|
|
});
|