88 lines
4.2 KiB
TypeScript
88 lines
4.2 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
|
|
const basicBlend = path.resolve(import.meta.dirname, "../../../tests/files/web/basic_scene.blend");
|
|
const materialBlend = path.resolve(import.meta.dirname, "../../../tests/files/web/attribute_scene.blend");
|
|
|
|
test("M7-17 keeps Worker detail out of the UI and exports it in a diagnostics report", async ({ page }) => {
|
|
await page.goto("/?worker-fault=engine");
|
|
await expect(page.getByTestId("engine-status")).toContainText("ready, open a .blend file", { timeout: 20_000 });
|
|
const app = page.locator("main.blender-app");
|
|
await page.getByTestId("blend-file-input").setInputFiles(basicBlend);
|
|
await expect(page.getByText("BasicCube", { exact: true })).toBeVisible();
|
|
const revision = Number(await app.getAttribute("data-current-main-revision"));
|
|
|
|
await page.getByTestId("inject-worker-crash").click();
|
|
await expect(app).toHaveAttribute("data-worker-fault-code", "WORKER_TERMINATED");
|
|
await expect(app).toHaveAttribute("data-last-diagnostic-code", "ENGINE_WORKER_TERMINATED");
|
|
await expect(page.getByTestId("engine-status")).toHaveText("Engine: Worker stopped; project remains available");
|
|
await expect(page.locator("body")).not.toContainText("WORKER_CRASH_INJECTED");
|
|
|
|
const downloadPromise = page.waitForEvent("download");
|
|
await page.getByTestId("export-diagnostics").click();
|
|
const download = await downloadPromise;
|
|
expect(download.suggestedFilename()).toBe("blender-web-diagnostics.json");
|
|
const reportPath = await download.path();
|
|
expect(reportPath).not.toBeNull();
|
|
const report = JSON.parse(await fs.readFile(reportPath!, "utf8"));
|
|
|
|
expect(report).toMatchObject({
|
|
schemaVersion: 1,
|
|
product: "Web Blender Modeler V1",
|
|
runtime: {
|
|
url: expect.stringMatching(/^http:\/\/127\.0\.0\.1:\d+\/$/),
|
|
userAgent: expect.any(String),
|
|
language: expect.any(String),
|
|
crossOriginIsolated: true,
|
|
},
|
|
project: { projectId: "basic_scene", revision },
|
|
});
|
|
expect(report.generatedAt).toMatch(/^\d{4}-\d{2}-\d{2}T/);
|
|
expect(report.entries).toHaveLength(1);
|
|
expect(report.entries[0]).toMatchObject({
|
|
schemaVersion: 1,
|
|
sequence: 1,
|
|
area: "ENGINE",
|
|
code: "ENGINE_WORKER_TERMINATED",
|
|
summary: "Engine: Worker stopped; project remains available",
|
|
sourceCode: "WORKER_TERMINATED",
|
|
context: { projectId: "basic_scene", revision },
|
|
});
|
|
expect(report.entries[0].detail).toContain("WORKER_CRASH_INJECTED");
|
|
});
|
|
|
|
test("M7-17 records open and import details behind stable user messages", async ({ page }) => {
|
|
await page.goto("/");
|
|
await expect(page.getByTestId("engine-status")).toContainText("ready, open a .blend file", { timeout: 20_000 });
|
|
const app = page.locator("main.blender-app");
|
|
await page.getByTestId("blend-file-input").setInputFiles(materialBlend);
|
|
await expect(page.getByText("AttributeMeshObject", { exact: true })).toBeVisible();
|
|
|
|
await page.getByTestId("blend-file-input").setInputFiles({
|
|
name: "invalid.blend",
|
|
mimeType: "application/octet-stream",
|
|
buffer: Buffer.from([0x42, 0x41, 0x44]),
|
|
});
|
|
await expect(page.getByTestId("engine-status")).toHaveText("Engine: .blend open failed");
|
|
await expect(app).toHaveAttribute("data-last-diagnostic-code", "BLEND_OPEN_FAILED");
|
|
|
|
await page.locator("label.file-button input[type=file]").setInputFiles({
|
|
name: "invalid.png",
|
|
mimeType: "image/png",
|
|
buffer: Buffer.from("not-a-png"),
|
|
});
|
|
await expect(page.getByTestId("engine-status")).toHaveText("Image import failed");
|
|
await expect(app).toHaveAttribute("data-last-diagnostic-code", "IMAGE_IMPORT_FAILED");
|
|
await expect(app).toHaveAttribute("data-diagnostic-count", "2");
|
|
|
|
const downloadPromise = page.waitForEvent("download");
|
|
await page.getByTestId("export-diagnostics").click();
|
|
const reportPath = await (await downloadPromise).path();
|
|
const report = JSON.parse(await fs.readFile(reportPath!, "utf8"));
|
|
expect(report.entries.map((entry: { code: string }) => entry.code)).toEqual(["BLEND_OPEN_FAILED", "IMAGE_IMPORT_FAILED"]);
|
|
expect(report.entries.every((entry: { detail: string }) => entry.detail.length > 0)).toBe(true);
|
|
expect(report.entries[0].summary).toBe("Engine: .blend open failed");
|
|
expect(report.entries[1].summary).toBe("Image import failed");
|
|
});
|