diff --git a/frontend/playwright/ui/visual-specs/visual-dashboard.spec.js b/frontend/playwright/ui/visual-specs/visual-dashboard.spec.js index d4563b69d2..9729d035bc 100644 --- a/frontend/playwright/ui/visual-specs/visual-dashboard.spec.js +++ b/frontend/playwright/ui/visual-specs/visual-dashboard.spec.js @@ -630,6 +630,42 @@ test.describe("Onboarding questions controls", () => { }); }); +test.describe("Profile page controls", () => { + const shot = { maxDiffPixelRatio: 0, threshold: 0 }; + + test("Profile page avatar, form and links", async ({ page }) => { + const dashboardPage = new DashboardPage(page); + await dashboardPage.goToDashboard(); + await dashboardPage.goToAccount(); + + const container = page.locator( + "[class*='settings_profile__form-container']", + ); + await expect(page.getByText("Change email")).toBeVisible(); + await page.mouse.move(10, 700); + await expect(container).toHaveScreenshot(shot); + + // The "Update" overlay shows when the pointer is on the avatar. + await page.locator("[class*='image-change-field']").hover(); + await expect(container).toHaveScreenshot(shot); + + // Save turns enabled once the name changes. + await page.getByLabel("Your name").fill("Renamed user"); + await page.mouse.move(10, 700); + await expect(container).toHaveScreenshot(shot); + + await page.getByText("Change email").hover(); + await expect(container).toHaveScreenshot(shot); + + // The "Update" overlay is a button: it shows on keyboard focus too. + await page.mouse.move(10, 700); + await page.getByRole("button", { name: "Update" }).focus(); + await page.keyboard.press("Shift+Tab"); + await page.keyboard.press("Tab"); + await expect(container).toHaveScreenshot(shot); + }); +}); + test.describe("Templates section controls", () => { const shot = { maxDiffPixelRatio: 0, threshold: 0 }; diff --git a/frontend/src/app/main/ui/settings/profile.cljs b/frontend/src/app/main/ui/settings/profile.cljs index 1c1add422b..de5e3a89de 100644 --- a/frontend/src/app/main/ui/settings/profile.cljs +++ b/frontend/src/app/main/ui/settings/profile.cljs @@ -119,8 +119,10 @@ [:form {:class (stl/css :avatar-form)} [:div {:class (stl/css :image-change-field)} - [:span {:class (stl/css :update-overlay) - :on-click on-image-click} (tr "labels.update")] + [:button {:type "button" + :class (stl/css :update-overlay) + :on-click on-image-click} + (tr "labels.update")] [:img {:src photo}] (when has-photo? [:button {:type "button" diff --git a/frontend/src/app/main/ui/settings/profile.scss b/frontend/src/app/main/ui/settings/profile.scss index 1a6fca03c6..d9e628c971 100644 --- a/frontend/src/app/main/ui/settings/profile.scss +++ b/frontend/src/app/main/ui/settings/profile.scss @@ -277,7 +277,16 @@ form.avatar-form { line-height: 6; text-align: center; background: var(--color-accent-tertiary); + border: none; + + // The button centers its 144px line in the 148px circle; the bottom + // padding keeps the label where the old span drew it. + padding: 0 0 $s-4; z-index: $z-index-modal; + + &:focus-visible { + opacity: 0.8; + } } .delete-overlay {