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>
68 lines
3.8 KiB
TypeScript
68 lines
3.8 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
|
|
const fixture = path.resolve(import.meta.dirname, '../../../tests/files/web/basic_scene.blend');
|
|
|
|
async function boot(page: import('@playwright/test').Page) {
|
|
await page.goto('/');
|
|
await page.getByTestId('blend-file-input').setInputFiles(fixture);
|
|
await expect(page.getByTestId('engine-status')).toContainText(/SceneIR/, { timeout: 60_000 });
|
|
await page.getByTestId('native-web-tools-toggle').click({ force: true });
|
|
await page.waitForTimeout(1500);
|
|
}
|
|
|
|
test('console assignment then Ctrl+Z in Layout', async ({ page }, info) => {
|
|
const record: Record<string, unknown> = {};
|
|
await boot(page);
|
|
await page.evaluate(() => {
|
|
const b = Array.from(document.querySelectorAll('nav[aria-label="工作区"] button'))
|
|
.find(x => (x.textContent ?? '').trim() === 'Scripting') as HTMLButtonElement | undefined;
|
|
b?.click();
|
|
});
|
|
await expect(page.getByLabel('Python 输入', { exact: true }).last()).toBeVisible({ timeout: 30_000 });
|
|
const input = page.getByLabel('Python 输入', { exact: true }).last();
|
|
const before = await page.evaluate(() => document.querySelector('[data-testid="engine-status"]')?.textContent ?? '');
|
|
record.statusBeforeAssign = before;
|
|
await input.fill("bpy.data.objects['BasicCube'].location.x = 3");
|
|
await input.press('Enter');
|
|
await page.waitForTimeout(4000);
|
|
record.consoleText = await page.getByRole('region', { name: 'Python Console', exact: true }).locator('pre').first().textContent().catch(() => null);
|
|
await page.evaluate(() => {
|
|
const b = Array.from(document.querySelectorAll('nav[aria-label="工作区"] button'))
|
|
.find(x => (x.textContent ?? '').trim() === 'Layout') as HTMLButtonElement | undefined;
|
|
b?.click();
|
|
});
|
|
await page.waitForTimeout(2500);
|
|
record.workspaceAfterSwitch = await page.locator('main').getAttribute('data-workspace');
|
|
record.statusAfterAssign = await page.getByTestId('engine-status').textContent().catch(() => null);
|
|
await page.keyboard.press('Control+z');
|
|
await page.waitForTimeout(3000);
|
|
record.statusAfterUndo = await page.getByTestId('engine-status').textContent().catch(() => null);
|
|
record.historyText = await page.evaluate(() => document.body.innerText.slice(-500));
|
|
fs.writeFileSync(info.outputPath('console-undo.json'), JSON.stringify(record, null, 1));
|
|
console.log(JSON.stringify(record, null, 1));
|
|
});
|
|
|
|
test('native modal cancel leaves mesh unchanged', async ({ page }, info) => {
|
|
const record: Record<string, unknown> = {};
|
|
await page.goto('/');
|
|
await page.getByTestId('blend-file-input').setInputFiles(fixture);
|
|
await expect(page.getByTestId('engine-status')).toContainText(/SceneIR/, { timeout: 60_000 });
|
|
record.desktopVisible = await page.locator('section[aria-label="Blender 桌面"]').isVisible().catch(() => null);
|
|
const canvas = page.locator('section[aria-label="Blender 桌面"] canvas').first();
|
|
record.canvasCount = await page.locator('section[aria-label="Blender 桌面"] canvas').count();
|
|
if (record.canvasCount) { await canvas.click({ position: { x: 400, y: 300 }, force: true }).catch(() => {}); }
|
|
await page.keyboard.press('g');
|
|
await page.waitForTimeout(600);
|
|
record.statusDuringModal = await page.getByTestId('engine-status').textContent().catch(() => null);
|
|
record.bodyDuringModal = await page.evaluate(() => document.body.innerText.slice(-400));
|
|
await page.keyboard.press('Escape');
|
|
await page.waitForTimeout(2000);
|
|
record.statusAfterEscape = await page.getByTestId('engine-status').textContent().catch(() => null);
|
|
record.bodyAfterEscape = await page.evaluate(() => document.body.innerText.slice(-400));
|
|
record.alerts = await page.locator('[role="alert"]').allTextContents();
|
|
fs.writeFileSync(info.outputPath('modal-cancel.json'), JSON.stringify(record, null, 1));
|
|
console.log(JSON.stringify(record, null, 1));
|
|
});
|