import { test, expect } from "@playwright/test"; import fs from "node:fs"; import path from "node:path"; import { exposeWebTools } from "../fixtures/native-ui-workflow"; const root = path.resolve(import.meta.dirname, "../../.."); const receiptDir = path.join(root, "tests/golden/WBV2-P1425-001/verification"); fs.mkdirSync(receiptDir, { recursive: true }); test("Add menu creates a data instance from the active object", async ({ page }) => { test.setTimeout(120_000); await page.goto("/"); await page.getByTestId("blend-file-input").setInputFiles(path.join(root, "tests/files/web/basic_scene.blend")); await expect(page.getByTestId("engine-status")).toContainText(/SceneIR r\d+/, { timeout: 60_000 }); await exposeWebTools(page); const cubeRow = page.locator('[data-node-id="object:BasicCube"]'); await cubeRow.click(); // Outliner selection is a native Main command; wait for its snapshot before // the Add route resolves the active object's data-block. await expect(cubeRow).toHaveAttribute("aria-selected", "true", { timeout: 60_000 }); await page.getByRole("button", { name: "添加", exact: true }).click(); await page.getByRole("menuitem", { name: "非网格", exact: true }).click(); await page.getByRole("menuitem", { name: "数据实例", exact: true }).click(); await expect(page.getByTestId("engine-status")).toContainText(/已执行:object\.data_instance_add/, { timeout: 60_000 }); await expect(page.getByRole("treeitem", { name: "Cube.001", exact: true })).toBeVisible({ timeout: 60_000 }); fs.writeFileSync(path.join(receiptDir, "data-instance-add-production.json"), JSON.stringify({ schemaVersion: 1, browser: "chromium", scope: "Web Add menu -> active object data lookup -> desktop_operator(object.data_instance_add) -> Main/SceneIR", status: "PASS", evidence: ["engine-status reported 已执行:object.data_instance_add", "Outliner exposed the new Cube.001 linked-data object"], }, null, 2)); });