From ca6a019c1ec22fcef7ef6f25527c7a74a77869f3 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Sun, 9 Aug 2026 00:10:49 +0200 Subject: [PATCH] test(v2): stabilize production E2E flows --- .../[locale]/boards/(content)/_board-add-menu.tsx | 2 +- .../[locale]/boards/(content)/_header-actions.tsx | 2 ++ e2e/custom-widgets-custom-jsx-v2.spec.ts | 14 ++++++++++---- e2e/lazy-widgets.spec.ts | 9 +++++++-- packages/translation/src/lang/en.json | 1 + 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_board-add-menu.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_board-add-menu.tsx index 3aaeb9131..0448e1097 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_board-add-menu.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_board-add-menu.tsx @@ -48,7 +48,7 @@ export const BoardAddMenu = () => { return ( - + diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx index fa21341d6..3792ff21f 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx @@ -110,7 +110,9 @@ const EditModeMenu = ({ demoReadOnly }: { demoReadOnly: boolean }) => { diff --git a/e2e/custom-widgets-custom-jsx-v2.spec.ts b/e2e/custom-widgets-custom-jsx-v2.spec.ts index dbd66d005..9de595362 100644 --- a/e2e/custom-widgets-custom-jsx-v2.spec.ts +++ b/e2e/custom-widgets-custom-jsx-v2.spec.ts @@ -36,8 +36,9 @@ describe("Custom JSX v2 workbench", () => { await page.waitForLoadState("networkidle"); await page.getByLabel("Username").fill(adminCredentials.username); await page.locator("#password").fill(adminCredentials.password); + const signedIn = page.waitForURL(baseUrl, { waitUntil: "commit", timeout: 15_000 }); await page.locator("button[type='submit']").click(); - await page.waitForURL(baseUrl, { timeout: 15_000 }); + await signedIn; await page.goto(`${baseUrl}/manage/custom-widgets/new`); await page.locator('input[data-path="name"]:visible').fill("E2E Custom JSX v2"); @@ -75,8 +76,12 @@ describe("Custom JSX v2 workbench", () => { await expect(page.getByText('Widget "E2E Custom JSX v2" updated successfully.')).toBeVisible({ timeout: 15_000 }); await page.goto(baseUrl); - await page.getByRole("button", { name: "Edit", exact: true }).click(); - await page.getByRole("button", { name: "New item", exact: true }).click(); + await page.getByRole("button", { name: "Skip tour", exact: true }).click(); + await expect(page.locator('[data-onboarding-tour-overlay="true"]')).toHaveCount(0); + const editToggle = page.getByTestId("board-edit-mode-toggle"); + await editToggle.click(); + await expect(editToggle).toHaveAttribute("aria-pressed", "true", { timeout: 15_000 }); + await page.getByRole("button", { name: "Add board content", exact: true }).click(); await page.getByRole("menuitem", { name: "New item", exact: true }).click(); const picker = page.getByRole("dialog").last(); const customWidgetCard = picker.getByText("E2E Custom JSX v2", { exact: true }).locator("xpath=../../.."); @@ -87,7 +92,8 @@ describe("Custom JSX v2 workbench", () => { await addDialog.getByRole("button", { name: "Save changes", exact: true }).click(); await expect(page.getByText("Widget definition not found")).not.toBeVisible(); - await page.getByRole("button", { name: "Save", exact: true }).click(); + await editToggle.click(); + await expect(editToggle).toHaveAttribute("aria-pressed", "false", { timeout: 15_000 }); await expect(page.getByText("E2E Widget")).toBeVisible({ timeout: 15_000 }); await expect(page.getByText("42")).toBeVisible({ timeout: 15_000 }); } finally { diff --git a/e2e/lazy-widgets.spec.ts b/e2e/lazy-widgets.spec.ts index 0c31f0492..a406cfa6e 100644 --- a/e2e/lazy-widgets.spec.ts +++ b/e2e/lazy-widgets.spec.ts @@ -78,10 +78,15 @@ describe("lazy widget application graph", () => { await page.goto(`${baseUrl}/auth/login`); await page.getByLabel("Username").fill(adminCredentials.username); await page.locator("#password").fill(adminCredentials.password); + const signedIn = page.waitForURL(baseUrl, { waitUntil: "commit", timeout: 15_000 }); await page.locator("css=button[type='submit']").click(); + await signedIn; await expect(page.locator("[data-homarr-dev-benchmark-board]")).toBeVisible({ timeout: 30_000 }); - await expect(page.locator(`[data-id="${itemId}"] .clock-widget-container`)).toBeVisible({ timeout: 15_000 }); + const clockWidget = page.locator( + `[data-id="${itemId}"] .clock-widget-container, [data-grid-item-id="${itemId}"] .clock-widget-container`, + ); + await expect(clockWidget).toBeVisible({ timeout: 15_000 }); await page.keyboard.press("Control+K"); await expect(page.locator("[data-homarr-dev-benchmark-spotlight]")).toBeVisible(); @@ -100,7 +105,7 @@ describe("lazy widget application graph", () => { .toBe(`${baseUrl}/`); await page.reload(); - await expect(page.locator(`[data-id="${itemId}"] .clock-widget-container`)).toBeVisible({ timeout: 15_000 }); + await expect(clockWidget).toBeVisible({ timeout: 15_000 }); expect(pageErrors).toEqual([]); } finally { await browser.close(); diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index a2661ea54..15cd43c89 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -4521,6 +4521,7 @@ }, "board": { "action": { + "addContent": "Add board content", "duplicate": { "title": "Duplicate board", "message": "This will duplicate the board {name} with all its content. If widgets reference integrations, that you are not allowed to use, they will be removed.",