@@ -1823,18 +1823,27 @@ test.describe("Workspace Manager V2 bootstrap", () => {
18231823 await expect(page.locator("#objectVectorStudioV2RenderSurface [data-center-origin='0,0']")).toHaveCount(1);
18241824 await expect(page.locator("#objectVectorStudioV2RenderSurface [data-center-origin='0,0']")).toHaveAttribute("r", "9");
18251825 await expect(page.locator("#objectVectorStudioV2ViewportControls button")).toHaveText(["Out", "In", "Up", "Down", "Left", "Right", "View", "Center"]);
1826- await expect(page.locator("#objectVectorStudioV2CenterDotButton")).not. toHaveAttribute("aria-pressed", /.*/ );
1826+ await expect(page.locator("#objectVectorStudioV2CenterDotButton")).toHaveAttribute("aria-pressed", "true" );
18271827 await page.locator("#objectVectorStudioV2PanRightButton").click();
18281828 await page.locator("#objectVectorStudioV2PanDownButton").click();
1829- await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 2, 2 | Canvas 0,0 centered | Zoom 100%");
1829+ await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 2, 2 | Canvas origin -2,-2 from center | Zoom 100%");
18301830 await expect(page.locator("#objectVectorStudioV2RenderSurface")).toHaveAttribute("viewBox", "-1580 -1080 3200 2200");
18311831 await page.locator("#objectVectorStudioV2RenderSurface").hover({ position: { x: 12, y: 12 } });
18321832 await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toContainText("Pointer");
18331833 await page.locator("#objectVectorStudioV2CenterDotButton").click();
1834+ await expect(page.locator("#objectVectorStudioV2RenderSurface")).toHaveAttribute("viewBox", "-1580 -1080 3200 2200");
1835+ await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toContainText("Canvas origin -2,-2 from center | Zoom 100%");
1836+ await expect(page.locator("#objectVectorStudioV2RenderSurface [data-center-origin='0,0']")).toHaveCount(0);
1837+ await expect(page.locator("#objectVectorStudioV2CenterDotButton")).toHaveAttribute("aria-pressed", "false");
1838+ await expect(page.locator("#statusLog")).toHaveValue(/OK Center dot hidden\./);
1839+ await page.locator("#objectVectorStudioV2ResetViewButton").click();
18341840 await expect(page.locator("#objectVectorStudioV2RenderSurface")).toHaveAttribute("viewBox", "-1600 -1100 3200 2200");
1835- await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, 0 | Canvas 0,0 centered | Zoom 100%");
1841+ await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, 0 | Canvas origin 0,0 centered | Zoom 100%");
1842+ await expect(page.locator("#objectVectorStudioV2RenderSurface [data-center-origin='0,0']")).toHaveCount(0);
1843+ await page.locator("#objectVectorStudioV2CenterDotButton").click();
18361844 await expect(page.locator("#objectVectorStudioV2RenderSurface [data-center-origin='0,0']")).toHaveCount(1);
1837- await expect(page.locator("#statusLog")).toHaveValue(/OK Viewport centered at origin 0,0; zoom 100% preserved\./);
1845+ await expect(page.locator("#objectVectorStudioV2CenterDotButton")).toHaveAttribute("aria-pressed", "true");
1846+ await expect(page.locator("#statusLog")).toHaveValue(/OK Center dot visible\./);
18381847 await expect(page.locator("#objectVectorStudioV2JsonDetails")).toContainText('"name": "Asteroids Ship"');
18391848 await expect(page.locator("#objectVectorStudioV2JsonDetails")).toContainText('"selectedShape": null');
18401849 await expect(page.locator("#objectVectorStudioV2JsonDetails")).not.toContainText('"palette"');
@@ -2366,6 +2375,14 @@ test.describe("Workspace Manager V2 bootstrap", () => {
23662375 const originAfterApply = await page.evaluate(() => window.__objectVectorStudioV2App.selectedShape().transform.origin);
23672376 expect(originAfterApply).toEqual({ x: 2, y: -3 });
23682377 await expect(page.locator("#statusLog")).toHaveValue(/OK Updated shape row 0 origin\/pivot to 2, -3\./);
2378+ const pivotMarkerAfterOrigin = await page.locator("#objectVectorStudioV2RenderSurface [data-pivot-origin='0']").evaluate((pivot) => {
2379+ const [horizontal, vertical] = Array.from(pivot.querySelectorAll("line"));
2380+ return {
2381+ x: Number(vertical.getAttribute("x1")),
2382+ y: Number(horizontal.getAttribute("y1"))
2383+ };
2384+ });
2385+ expect(pivotMarkerAfterOrigin).toEqual({ x: 120, y: 70 });
23692386
23702387 await page.locator("#objectVectorStudioV2ScaleInput").fill("0");
23712388 await expect(page.locator("#objectVectorStudioV2ScaleInput")).toHaveAttribute("aria-invalid", "true");
@@ -2521,25 +2538,25 @@ test.describe("Workspace Manager V2 bootstrap", () => {
25212538 await expect(page.locator("#objectVectorStudioV2RenderSurface")).toHaveAttribute("viewBox", "-1454.545 -1000 2909.091 2000");
25222539 await page.locator("#objectVectorStudioV2PanRightButton").click();
25232540 await expect(page.locator("#objectVectorStudioV2RenderSurface")).toHaveAttribute("viewBox", "-1434.545 -1000 2909.091 2000");
2524- await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 2, 0 | Canvas 0 ,0 centered | Zoom 110%");
2541+ await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 2, 0 | Canvas origin -2 ,0 from center | Zoom 110%");
25252542 await page.locator("#objectVectorStudioV2ResetViewButton").click();
25262543 await expect(page.locator("#objectVectorStudioV2RenderSurface")).toHaveAttribute("viewBox", "-1600 -1100 3200 2200");
2527- await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, 0 | Canvas 0,0 centered | Zoom 100%");
2544+ await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, 0 | Canvas origin 0,0 centered | Zoom 100%");
25282545 await expect(page.locator("#statusLog")).toHaveValue(/OK Viewport reset to 100% at origin 0,0\./);
25292546 await page.evaluate(() => {
25302547 window.__objectVectorStudioV2App.viewport.zoom = 0.095;
25312548 window.__objectVectorStudioV2App.updateViewport();
25322549 });
2533- await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, 0 | Canvas 0,0 centered | Zoom 100%");
2550+ await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, 0 | Canvas origin 0,0 centered | Zoom 100%");
25342551 await page.evaluate(() => {
25352552 window.__objectVectorStudioV2App.zoomViewport(2.5);
25362553 });
2537- await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, 0 | Canvas 0,0 centered | Zoom 500%");
2554+ await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, 0 | Canvas origin 0,0 centered | Zoom 500%");
25382555 await expect(page.locator("#objectVectorStudioV2RenderSurface")).toHaveAttribute("viewBox", "-320 -220 640 440");
25392556 await page.evaluate(() => {
25402557 window.__objectVectorStudioV2App.zoomViewport(0);
25412558 });
2542- await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, 0 | Canvas 0,0 centered | Zoom 10%");
2559+ await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, 0 | Canvas origin 0,0 centered | Zoom 10%");
25432560 await expect(page.locator("#objectVectorStudioV2RenderSurface")).toHaveAttribute("viewBox", "-16000 -11000 32000 22000");
25442561 await page.locator("#objectVectorStudioV2ResetViewButton").click();
25452562 await expect(page.locator("#objectVectorStudioV2RenderSurface")).toHaveAttribute("viewBox", "-1600 -1100 3200 2200");
@@ -3017,18 +3034,33 @@ test.describe("Workspace Manager V2 bootstrap", () => {
30173034 viewBox: "-640 -440 1280 880"
30183035 });
30193036
3037+ const beforePanShapeState = await page.evaluate(() => {
3038+ const shape = window.__objectVectorStudioV2App.selectedShape();
3039+ return {
3040+ geometry: JSON.stringify(shape.geometry),
3041+ transform: JSON.stringify(shape.transform || null)
3042+ };
3043+ });
30203044 await page.locator("#objectVectorStudioV2PanRightButton").click();
30213045 await expect(page.locator("#objectVectorStudioV2RenderSurface")).toHaveAttribute("viewBox", "-620 -440 1280 880");
3022- await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 2, 0 | Canvas 0 ,0 centered | Zoom 250%");
3046+ await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 2, 0 | Canvas origin -2 ,0 from center | Zoom 250%");
30233047 await page.locator("#objectVectorStudioV2PanLeftButton").click();
30243048 await expect(page.locator("#objectVectorStudioV2RenderSurface")).toHaveAttribute("viewBox", "-640 -440 1280 880");
3025- await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, 0 | Canvas 0,0 centered | Zoom 250%");
3049+ await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, 0 | Canvas origin 0,0 centered | Zoom 250%");
30263050 await page.locator("#objectVectorStudioV2PanUpButton").click();
30273051 await expect(page.locator("#objectVectorStudioV2RenderSurface")).toHaveAttribute("viewBox", "-640 -460 1280 880");
3028- await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, -2 | Canvas 0,0 centered | Zoom 250%");
3052+ await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, -2 | Canvas origin 0,2 from center | Zoom 250%");
30293053 await page.locator("#objectVectorStudioV2PanDownButton").click();
30303054 await expect(page.locator("#objectVectorStudioV2RenderSurface")).toHaveAttribute("viewBox", "-640 -440 1280 880");
3031- await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, 0 | Canvas 0,0 centered | Zoom 250%");
3055+ await expect(page.locator("#objectVectorStudioV2CoordinateDisplay")).toHaveText("Origin: 0, 0 | Canvas origin 0,0 centered | Zoom 250%");
3056+ const afterPanShapeState = await page.evaluate(() => {
3057+ const shape = window.__objectVectorStudioV2App.selectedShape();
3058+ return {
3059+ geometry: JSON.stringify(shape.geometry),
3060+ transform: JSON.stringify(shape.transform || null)
3061+ };
3062+ });
3063+ expect(afterPanShapeState).toEqual(beforePanShapeState);
30323064 const examplePointerScreen = await page.locator("#objectVectorStudioV2RenderSurface").evaluate((surface) => {
30333065 const point = surface.createSVGPoint();
30343066 point.x = -140;
@@ -6589,6 +6621,10 @@ test.describe("Workspace Manager V2 bootstrap", () => {
65896621 ship: "object.asteroids.ship"
65906622 }
65916623 };
6624+ const invalidUnknownGameDataManifest = structuredClone(manifest);
6625+ invalidUnknownGameDataManifest.game.gameData.debugUnknown = true;
6626+ const invalidUnknownWorkspaceManifest = structuredClone(manifest.game.workspace);
6627+ invalidUnknownWorkspaceManifest.debugUnknown = true;
65926628 return {
65936629 gameManifestValidation: await service.validateGameManifest(manifest),
65946630 hasGameData: Boolean(manifest.game?.gameData),
@@ -6598,6 +6634,8 @@ test.describe("Workspace Manager V2 bootstrap", () => {
65986634 runtimeWorkspaceValidation: await service.validateGameManifest(invalidRuntimeWorkspaceManifest),
65996635 rootDocumentKind: manifest.documentKind || "",
66006636 schema: manifest.schema,
6637+ unknownGameDataValidation: await service.validateGameManifest(invalidUnknownGameDataManifest),
6638+ unknownWorkspaceValidation: await service.validateGeneratedManifest(invalidUnknownWorkspaceManifest),
66016639 workspaceDocumentKind: manifest.game?.workspace?.documentKind,
66026640 workspaceValidation: await service.validateGeneratedManifest(manifest.game.workspace)
66036641 };
@@ -6610,9 +6648,14 @@ test.describe("Workspace Manager V2 bootstrap", () => {
66106648 objectVectorRuntimeValidation: { ok: false },
66116649 rootDocumentKind: "",
66126650 schema: "html-js-gaming.game-manifest",
6651+ unknownGameDataValidation: { ok: false },
6652+ unknownWorkspaceValidation: { ok: false },
66136653 workspaceDocumentKind: "workspace-manifest",
66146654 workspaceValidation: { ok: true }
66156655 });
6656+ expect(asteroidsGameManifestShape.objectVectorRuntimeValidation.message).toContain("root.game.gameData.objectVectorRuntime is not allowed");
6657+ expect(asteroidsGameManifestShape.unknownGameDataValidation.message).toContain("root.game.gameData.debugUnknown is not allowed");
6658+ expect(asteroidsGameManifestShape.unknownWorkspaceValidation.message).toContain("root.debugUnknown is not allowed");
66166659 expect(asteroidsGameManifestShape.runtimeWorkspaceValidation.ok).toBe(false);
66176660 expect(asteroidsGameManifestShape.runtimeWorkspaceValidation.message).toContain("runtime data must not depend on editor/tool workspace state");
66186661
0 commit comments