From 28b146afe5d5a8580225744e4b7c10b4b42cf69c Mon Sep 17 00:00:00 2001 From: DavidQ Date: Sat, 20 Jun 2026 12:36:58 -0400 Subject: [PATCH] PR_26171_037 align idea board add actions --- .../tools/IdeaBoardTableNotes.spec.mjs | 22 +++++++++++++++++++ .../tools/ToolboxRoutePages.spec.mjs | 22 +++++++++++++++++++ toolbox/idea-board/index.js | 5 +---- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs b/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs index 162693064..b2858fe89 100644 --- a/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +++ b/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs @@ -36,6 +36,23 @@ async function expectIdeaChevron(page, ideaId, iconName) { expect(metrics.maskImage).toContain(iconName); } +async function expectButtonLeftAligned(page, buttonSelector, containerSelector) { + const metrics = await page.locator(buttonSelector).evaluate((button, selector) => { + const container = button.ownerDocument.querySelector(selector); + const buttonRect = button.getBoundingClientRect(); + const containerRect = container.getBoundingClientRect(); + const containerStyles = getComputedStyle(container); + return { + buttonLeft: buttonRect.left, + containerLeft: containerRect.left, + containerWidth: containerRect.width, + expectedLeft: containerRect.left + Number.parseFloat(containerStyles.paddingLeft || "0"), + }; + }, containerSelector); + expect(Math.abs(metrics.buttonLeft - metrics.expectedLeft)).toBeLessThanOrEqual(2); + expect(metrics.buttonLeft).toBeLessThan(metrics.containerLeft + metrics.containerWidth / 2); +} + test("Idea Board uses DB-shaped accordion table ideas and notes", async ({ page }) => { const server = await startRepoServer(); const previousApiUrl = process.env.GAMEFOUNDRY_API_URL; @@ -78,6 +95,9 @@ test("Idea Board uses DB-shaped accordion table ideas and notes", async ({ page await expect(page.locator("[data-idea-board-idea-row]")).toHaveCount(3); await expect(page.locator("[data-idea-board-expanded-row]")).toHaveCount(0); await expect(page.locator("[data-idea-board-add-idea-row]")).toHaveCount(1); + await expect(page.locator("[data-idea-board-add-idea]")).toHaveText("Add Idea"); + await expectButtonLeftAligned(page, "[data-idea-board-add-idea]", "[data-idea-board-add-idea-row] > td"); + await expect(page.getByText(/another/i)).toHaveCount(0); await expect(page.locator("[data-idea-board-notes-chevron]")).toHaveCount(0); await expect(page.getByText("Selected idea context")).toHaveCount(0); await expect(page.getByText("Notes for Sky Orchard")).toHaveCount(0); @@ -109,6 +129,8 @@ test("Idea Board uses DB-shaped accordion table ideas and notes", async ({ page await expect(page.locator("[data-idea-board-expanded-row='top-thoughts'] :is(h1,h2,h3,h4,h5,h6)").filter({ hasText: /^Notes$/ })).toHaveCount(0); await expect(page.locator("[data-idea-board-expanded-row='top-thoughts'] > td > .content-stack")).toHaveCount(0); await expect(page.locator("[data-idea-board-notes-table='top-thoughts'] th[scope='col']")).toHaveText(["Note", "Actions"]); + await expect(page.locator("[data-idea-board-add-note='top-thoughts']")).toHaveText("Add Note"); + await expectButtonLeftAligned(page, "[data-idea-board-add-note='top-thoughts']", "[data-idea-board-expanded-row='top-thoughts'] > td"); await expect(page.locator("[data-idea-board-notes-table] th[scope='col']", { hasText: "Type" })).toHaveCount(0); await expect(page.locator("[data-idea-board-notes-table] th[scope='col']", { hasText: "Created By" })).toHaveCount(0); await expect(page.locator("[data-idea-board-notes-table] th[scope='col']", { hasText: "Created" })).toHaveCount(0); diff --git a/tests/playwright/tools/ToolboxRoutePages.spec.mjs b/tests/playwright/tools/ToolboxRoutePages.spec.mjs index f7f300df2..c0c323185 100644 --- a/tests/playwright/tools/ToolboxRoutePages.spec.mjs +++ b/tests/playwright/tools/ToolboxRoutePages.spec.mjs @@ -138,6 +138,23 @@ async function expectIdeaChevron(page, ideaId, iconName) { expect(metrics.maskImage).toContain(iconName); } +async function expectButtonLeftAligned(page, buttonSelector, containerSelector) { + const metrics = await page.locator(buttonSelector).evaluate((button, selector) => { + const container = button.ownerDocument.querySelector(selector); + const buttonRect = button.getBoundingClientRect(); + const containerRect = container.getBoundingClientRect(); + const containerStyles = getComputedStyle(container); + return { + buttonLeft: buttonRect.left, + containerLeft: containerRect.left, + containerWidth: containerRect.width, + expectedLeft: containerRect.left + Number.parseFloat(containerStyles.paddingLeft || "0"), + }; + }, containerSelector); + expect(Math.abs(metrics.buttonLeft - metrics.expectedLeft)).toBeLessThanOrEqual(2); + expect(metrics.buttonLeft).toBeLessThan(metrics.containerLeft + metrics.containerWidth / 2); +} + test("tools route aliases render toolbox tool pages", async ({ page }) => { const server = await startRepoServer(); const failedRequests = []; @@ -249,6 +266,9 @@ test("Idea Board launches from Toolbox with accordion table notes model", async await expect(page.locator("[data-idea-board-table] > thead th[scope='col']")).toHaveText(["Idea", "Pitch", "Status", "Updated", "Notes", "Actions"]); await expect(page.locator("[data-idea-board-idea-row]")).toHaveCount(3); await expect(page.locator("[data-idea-board-expanded-row]")).toHaveCount(0); + await expect(page.locator("[data-idea-board-add-idea]")).toHaveText("Add Idea"); + await expectButtonLeftAligned(page, "[data-idea-board-add-idea]", "[data-idea-board-add-idea-row] > td"); + await expect(page.getByText(/another/i)).toHaveCount(0); await expect(page.locator("[data-idea-board-notes-count='top-thoughts']")).toHaveText("3 Notes"); await expect(page.locator("[data-idea-board-notes-count='sky-orchard']")).toHaveText("3 Notes"); await expect(page.locator("[data-idea-board-notes-count='clockwork-courier']")).toHaveText("0 Notes"); @@ -268,6 +288,8 @@ test("Idea Board launches from Toolbox with accordion table notes model", async await expect(page.getByText("Selected idea context")).toHaveCount(0); await expect(page.getByText("Selected")).toHaveCount(0); await expect(page.locator("[data-idea-board-add-note='top-thoughts']")).toBeVisible(); + await expect(page.locator("[data-idea-board-add-note='top-thoughts']")).toHaveText("Add Note"); + await expectButtonLeftAligned(page, "[data-idea-board-add-note='top-thoughts']", "[data-idea-board-expanded-row='top-thoughts'] > td"); await expect(page.locator("[data-idea-board-create-project]")).toBeVisible(); await expect(page.locator("[data-idea-board-create-project]")).toBeDisabled(); await expect(page.locator("style, [style], script:not([src])")).toHaveCount(0); diff --git a/toolbox/idea-board/index.js b/toolbox/idea-board/index.js index ee7f0d932..d95fcbaf4 100644 --- a/toolbox/idea-board/index.js +++ b/toolbox/idea-board/index.js @@ -306,11 +306,8 @@ function renderExpandedNotesRow(tbody, record) { function renderAddIdeaRow(tbody) { const row = document.createElement("tr"); row.dataset.ideaBoardAddIdeaRow = "true"; - const prompt = document.createElement("td"); - prompt.colSpan = 5; - prompt.textContent = "Add another idea"; - row.append(prompt); const actions = document.createElement("td"); + actions.colSpan = 6; const addIdea = actionButton("Add Idea", "add", "ideaBoardIdeaAction", "primary"); addIdea.dataset.ideaBoardAddIdea = "true"; actions.append(addIdea);