import { test, expect } from '@playwright/test'; import path from 'node:path'; const fixture = path.resolve(import.meta.dirname, '../../../tests/files/web/basic_scene.blend'); async function menuUndo(page: import('@playwright/test').Page) { await page.getByRole('button', { name: '编辑', exact: true }).first().click({ force: true }); await page.waitForTimeout(400); await page.getByRole('menuitem', { name: '撤销', exact: true }).first().click({ force: true }); await page.waitForTimeout(2500); } test('undo via menu after console assignment', async ({ 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(1200); 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 page.waitForTimeout(1500); const input = page.getByLabel('Python 输入', { exact: true }).last(); await expect(input).toBeVisible({ timeout: 30_000 }); const run = async (tag: string) => { await input.fill(`print('${tag}', bpy.data.objects['BasicCube'].location.x)`); await input.press('Enter'); await page.waitForTimeout(2500); const out = await page.getByRole('region', { name: 'Python Console', exact: true }).innerText(); const line = out.split('\n').filter(l => l.includes(tag)).pop() ?? 'missing'; console.log(`PROBE ${tag} => ${line.trim()}`); }; await input.fill("bpy.data.objects['BasicCube'].location.x = 3"); await input.press('Enter'); await page.waitForTimeout(3000); await run('XSET'); await menuUndo(page); await run('X1'); await menuUndo(page); await run('X2'); await menuUndo(page); await run('X3'); });