@@ -1812,17 +1812,25 @@ test.describe("Workspace Manager V2 bootstrap", () => {
18121812 await expect(page.locator("#objectVectorStudioV2ObjectDetails")).not.toContainText("Transform");
18131813 await expect(page.locator("#objectVectorStudioV2ObjectDetails #objectVectorStudioV2MoveShapeButton")).toHaveCount(0);
18141814 await expect(page.locator("#objectVectorStudioV2ObjectTransform")).not.toContainText("Selected Shape:");
1815- await expect(page.locator("#objectVectorStudioV2ObjectTransform .object-vector-studio-v2__transform-summary")).toHaveText("Transform x 0, y 0, rot 0, scale 1 x 1");
1815+ await expect(page.locator("#objectVectorStudioV2ObjectTransform .object-vector-studio-v2__transform-summary")).toHaveText("x 0, y 0, rot 0, scale 1 x 1");
18161816 await expect(page.locator("#objectVectorStudioV2ObjectTransform #objectVectorStudioV2MoveShapeButton")).toHaveCount(1);
18171817 const transformSummaryLayout = await page.locator("#objectVectorStudioV2ObjectTransform").evaluate((panel) => {
1818- const actions = panel.querySelector(".object-vector-studio-v2__shape-actions ");
1818+ const scaleRow = panel.querySelector(".object-vector-studio-v2__scale-control-row ");
18191819 const summary = panel.querySelector(".object-vector-studio-v2__transform-summary");
1820+ const summaryStyle = getComputedStyle(summary);
18201821 return {
1821- summaryAfterActions: Boolean(actions && summary && (actions.compareDocumentPosition(summary) & Node.DOCUMENT_POSITION_FOLLOWING)),
1822- summaryTopAtBottom: summary.getBoundingClientRect().top >= actions.getBoundingClientRect().bottom
1822+ summaryAfterScale: Boolean(scaleRow && summary && (scaleRow.compareDocumentPosition(summary) & Node.DOCUMENT_POSITION_FOLLOWING)),
1823+ summaryCentered: summaryStyle.textAlign === "center",
1824+ summaryStartsWithoutTransform: !summary.textContent.trim().startsWith("Transform"),
1825+ summaryTopAtBottom: summary.getBoundingClientRect().top >= scaleRow.getBoundingClientRect().bottom
18231826 };
18241827 });
1825- expect(transformSummaryLayout).toEqual({ summaryAfterActions: true, summaryTopAtBottom: true });
1828+ expect(transformSummaryLayout).toEqual({
1829+ summaryAfterScale: true,
1830+ summaryCentered: true,
1831+ summaryStartsWithoutTransform: true,
1832+ summaryTopAtBottom: true
1833+ });
18261834 const transformIconState = await page.locator("#objectVectorStudioV2ObjectTransform").evaluate((panel) => ({
18271835 resize: {
18281836 iconKey: panel.querySelector("#objectVectorStudioV2ResizeShapeButton").dataset.ovsIconKey,
@@ -1872,24 +1880,57 @@ test.describe("Workspace Manager V2 bootstrap", () => {
18721880 "Group",
18731881 "None"
18741882 ]);
1875- const transformFieldLayout = await page.locator("#objectVectorStudioV2ObjectTransform").evaluate((panel) => (
1876- Array.from(panel.querySelectorAll(".object-vector-studio-v2__edit-field--inline")).map((field) => {
1877- const label = field.querySelector("span");
1878- const input = field.querySelector("input");
1879- const labelRect = label.getBoundingClientRect();
1880- const inputRect = input.getBoundingClientRect();
1883+ const transformControlLayout = await page.locator("#objectVectorStudioV2ObjectTransform").evaluate((panel) => (
1884+ Array.from(panel.querySelectorAll(".object-vector-studio-v2__transform-control-row")).map((row) => {
1885+ const children = Array.from(row.children);
1886+ const centers = children.map((child) => {
1887+ const rect = child.getBoundingClientRect();
1888+ return Math.round(rect.top + rect.height / 2);
1889+ });
1890+ const button = row.querySelector("button");
18811891 return {
1882- inline: Math.abs((labelRect.top + labelRect.height / 2) - (inputRect.top + inputRect.height / 2)) < 4 && labelRect.right <= inputRect.left,
1883- label: label.textContent.trim()
1892+ allOneLine: centers.every((center) => Math.abs(center - centers[0]) <= 2),
1893+ axisLabels: Array.from(row.querySelectorAll(".object-vector-studio-v2__transform-axis-field > span")).map((element) => element.textContent.trim()),
1894+ buttonId: button?.id || "",
1895+ buttonText: button?.textContent.trim() || "",
1896+ buttonTitle: button?.title || "",
1897+ inputIds: Array.from(row.querySelectorAll("input")).map((input) => input.id),
1898+ label: row.querySelector(".object-vector-studio-v2__transform-control-label")?.textContent.trim() || "",
1899+ rowType: row.dataset.transformControlRow
18841900 };
18851901 })
18861902 ));
1887- expect(transformFieldLayout).toEqual([
1888- { inline: true, label: "Move X" },
1889- { inline: true, label: "Move Y" },
1890- { inline: true, label: "Rotate" },
1891- { inline: true, label: "Origin X" },
1892- { inline: true, label: "Origin Y" }
1903+ expect(transformControlLayout).toEqual([
1904+ {
1905+ allOneLine: true,
1906+ axisLabels: ["X", "Y"],
1907+ buttonId: "objectVectorStudioV2MoveShapeButton",
1908+ buttonText: "Move",
1909+ buttonTitle: "",
1910+ inputIds: ["objectVectorStudioV2MoveXInput", "objectVectorStudioV2MoveYInput"],
1911+ label: "Move",
1912+ rowType: "move"
1913+ },
1914+ {
1915+ allOneLine: true,
1916+ axisLabels: ["X", "Y"],
1917+ buttonId: "objectVectorStudioV2ApplyOriginButton",
1918+ buttonText: "Apply",
1919+ buttonTitle: "Apply Origin",
1920+ inputIds: ["objectVectorStudioV2OriginXInput", "objectVectorStudioV2OriginYInput"],
1921+ label: "Origin",
1922+ rowType: "origin"
1923+ },
1924+ {
1925+ allOneLine: true,
1926+ axisLabels: [],
1927+ buttonId: "objectVectorStudioV2RotateShapeButton",
1928+ buttonText: "Rotate",
1929+ buttonTitle: "",
1930+ inputIds: ["objectVectorStudioV2RotateInput"],
1931+ label: "Rotate",
1932+ rowType: "rotate"
1933+ }
18931934 ]);
18941935 const transformBeforeInvalid = await page.evaluate(() => window.__objectVectorStudioV2App.selectedShape().transform);
18951936 await page.locator("#objectVectorStudioV2MoveXInput").fill("");
@@ -2234,6 +2275,12 @@ test.describe("Workspace Manager V2 bootstrap", () => {
22342275 await page.locator("#objectVectorStudioV2RotateShapeButton").click();
22352276 await expect(page.locator("#objectVectorStudioV2JsonDetails")).toContainText('"rotation": 15');
22362277 await expect(page.locator("#statusLog")).toHaveValue(/OK Rotated shape row 0 by 15 degrees\./);
2278+ await page.locator("#objectVectorStudioV2OriginXInput").fill("2");
2279+ await page.locator("#objectVectorStudioV2OriginYInput").fill("-3");
2280+ await page.locator("#objectVectorStudioV2ApplyOriginButton").click();
2281+ const originAfterApply = await page.evaluate(() => window.__objectVectorStudioV2App.selectedShape().transform.origin);
2282+ expect(originAfterApply).toEqual({ x: 2, y: -3 });
2283+ await expect(page.locator("#statusLog")).toHaveValue(/OK Updated shape row 0 origin\/pivot to 2, -3\./);
22372284
22382285 await page.locator("#objectVectorStudioV2ScaleInput").fill("0");
22392286 await expect(page.locator("#objectVectorStudioV2ScaleInput")).toHaveAttribute("aria-invalid", "true");
@@ -2243,7 +2290,7 @@ test.describe("Workspace Manager V2 bootstrap", () => {
22432290 await expect(page.locator("#objectVectorStudioV2ScaleInput")).not.toHaveAttribute("aria-invalid", "true");
22442291 await expect(page.locator("#statusLog")).toHaveValue(/OK Scale preview set to 1\.2 for shape row 0\./);
22452292 await expect(page.locator("#objectVectorStudioV2JsonDetails")).toContainText('"scaleX": 1.2');
2246- await expect(page.locator("#objectVectorStudioV2ObjectTransform .object-vector-studio-v2__transform-summary")).toHaveText("Transform x 10, y 10, rot 15, scale 1.2 x 1.2");
2293+ await expect(page.locator("#objectVectorStudioV2ObjectTransform .object-vector-studio-v2__transform-summary")).toHaveText("x 10, y 10, rot 15, scale 1.2 x 1.2");
22472294 const selectionBeforeScaleStep = await page.locator("#objectVectorStudioV2RenderSurface [data-selection-bounds='0']").evaluate((box) => ({
22482295 height: Number(box.getAttribute("height")),
22492296 width: Number(box.getAttribute("width"))
@@ -2295,7 +2342,7 @@ test.describe("Workspace Manager V2 bootstrap", () => {
22952342 }
22962343 });
22972344 await expect(page.locator("#objectVectorStudioV2ScaleInput")).toHaveValue("1");
2298- await expect(page.locator("#objectVectorStudioV2ObjectTransform .object-vector-studio-v2__transform-summary")).toHaveText("Transform x 10, y 10, rot 15, scale 1 x 1");
2345+ await expect(page.locator("#objectVectorStudioV2ObjectTransform .object-vector-studio-v2__transform-summary")).toHaveText("x 10, y 10, rot 15, scale 1 x 1");
22992346 await expect(page.locator("#statusLog")).toHaveValue(/OK Resize Geometry applied scale 1\.2 to shape row 0; transform scale reset to 1\./);
23002347
23012348 await page.locator("#objectVectorStudioV2BringForwardButton").click();
@@ -3646,12 +3693,12 @@ test.describe("Workspace Manager V2 bootstrap", () => {
36463693 await page.locator("#objectVectorStudioV2MoveYInput").fill("7");
36473694 await page.locator("#objectVectorStudioV2MoveShapeButton").click();
36483695 await expect(page.locator("#statusLog")).toHaveValue(/OK Moved shape row 0 by 10, 10\./);
3649- await expect(page.locator("#objectVectorStudioV2ObjectTransform .object-vector-studio-v2__transform-summary")).toHaveText("Transform x 10, y 10, rot 0, scale 1 x 1");
3696+ await expect(page.locator("#objectVectorStudioV2ObjectTransform .object-vector-studio-v2__transform-summary")).toHaveText("x 10, y 10, rot 0, scale 1 x 1");
36503697 await page.locator("#objectVectorStudioV2MoveXInput").fill("-5");
36513698 await page.locator("#objectVectorStudioV2MoveYInput").fill("-5");
36523699 await page.locator("#objectVectorStudioV2MoveShapeButton").click();
36533700 await expect(page.locator("#statusLog")).toHaveValue(/OK Moved shape row 0 by -10, -10\./);
3654- await expect(page.locator("#objectVectorStudioV2ObjectTransform .object-vector-studio-v2__transform-summary")).toHaveText("Transform x 0, y 0, rot 0, scale 1 x 1");
3701+ await expect(page.locator("#objectVectorStudioV2ObjectTransform .object-vector-studio-v2__transform-summary")).toHaveText("x 0, y 0, rot 0, scale 1 x 1");
36553702
36563703 await page.locator("#objectVectorStudioV2CopyJsonButton").click();
36573704 const copiedPayload = await page.evaluate(() => JSON.parse(sessionStorage.getItem("object-vector-studio-v2.authoring-copied-json")));
0 commit comments