diff --git a/e2e/delegated-writes.spec.ts b/e2e/delegated-writes.spec.ts index 68150fffc..5c7cfa565 100644 --- a/e2e/delegated-writes.spec.ts +++ b/e2e/delegated-writes.spec.ts @@ -221,7 +221,14 @@ test.describe("delegated writes", () => { // reads "Add") and then for a `value` input (the form opens on blood // pressure, which has three). Both were wrong from the day they were // written and nobody found out, because the whole file was skipping. - await page.locator('[data-slot="measurement-add"]').click(); + // The owner's list may be empty, in which case its empty state carries + // the add action and the header drops its own. + await page + .locator( + '[data-slot="measurement-add"], [data-slot="measurement-add-first"]', + ) + .first() + .click(); await page.locator("#sys").fill("124"); await page.locator("#dia").fill("78"); await page.getByRole("button", { name: /^save$/i }).click(); diff --git a/e2e/dialog-horizontal-overflow.spec.ts b/e2e/dialog-horizontal-overflow.spec.ts index 54267f858..95302437e 100644 --- a/e2e/dialog-horizontal-overflow.spec.ts +++ b/e2e/dialog-horizontal-overflow.spec.ts @@ -70,13 +70,15 @@ const DIALOGS: DialogCase[] = [ { name: "measurements add", path: "/measurements", - trigger: /^add$/i, + // While a list is empty the header drops its add button and the empty + // state carries the action, so either one opens the dialog. + trigger: /^(add|add your first measurement)$/i, ready: '[data-slot="date-time-field"]', }, { name: "mood add", path: "/mood", - trigger: /^add$/i, + trigger: /^(add|log your first mood)$/i, // The mood sheet opens on the five-face quick check; the timestamp row // (and everything else) appears once a face is picked. Measuring the // quick check alone would measure a sheet that has almost nothing in it. @@ -92,7 +94,7 @@ const DIALOGS: DialogCase[] = [ { name: "labs add", path: "/labs", - trigger: /^add$/i, + trigger: /^(add|add your first result)$/i, ready: '[data-slot="date-time-field"]', }, // The labs sheet's footer holds three buttons (Cancel, Save & add another, @@ -101,7 +103,7 @@ const DIALOGS: DialogCase[] = [ { name: "labs add (German)", path: "/labs", - trigger: /^hinzufügen$/i, + trigger: /^(hinzufügen|ersten wert erfassen)$/i, ready: '[data-slot="date-time-field"]', locale: "de", }, diff --git a/e2e/measurement-flow.spec.ts b/e2e/measurement-flow.spec.ts index 28b48c145..62e4d2137 100644 --- a/e2e/measurement-flow.spec.ts +++ b/e2e/measurement-flow.spec.ts @@ -135,7 +135,13 @@ test.describe("add measurement flow", () => { // v1.5 phase-5: the menu items now have distinct labels — the // measurement entry says "Measurement" / "Messung" instead of "Add", // so we can target it directly. - await page.getByRole("menuitem", { name: /measurement|messung/i }).click(); + // The desktop rail opens a dropdown, the phone shell the capture sheet + // the bottom nav's plus opens; the measurement entry is in either. + await page + .getByRole("menuitem", { name: /measurement|messung/i }) + .or(page.getByRole("button", { name: /^(measurement|messung)\b/i })) + .first() + .click(); // Form should be visible inside the dialog. Switch type to WEIGHT // (combo-box defaults to BLOOD_PRESSURE). diff --git a/e2e/mood-timestamp.spec.ts b/e2e/mood-timestamp.spec.ts index 28daa3df8..f157aa674 100644 --- a/e2e/mood-timestamp.spec.ts +++ b/e2e/mood-timestamp.spec.ts @@ -32,7 +32,9 @@ test.describe("mood timestamp capture", () => { }); await page.goto("/mood", { waitUntil: "domcontentloaded" }); - await page.getByRole("button", { name: "Add", exact: true }).click(); + // The list is mocked empty, so its empty state carries the add action + // (the header drops its own while there is nothing to list). + await page.getByRole("button", { name: "Log your first mood" }).click(); await page.getByRole("radio", { name: "Amazing" }).click(); const details = page.getByRole("button", { name: "Note & details" }); diff --git a/e2e/onboarding-tour-passthrough.spec.ts b/e2e/onboarding-tour-passthrough.spec.ts index a87ac6729..433797e8b 100644 --- a/e2e/onboarding-tour-passthrough.spec.ts +++ b/e2e/onboarding-tour-passthrough.spec.ts @@ -197,7 +197,14 @@ test.describe("v1.4.33 F2 — onboarding tour passes clicks through to the page" await quickAddButton.click(); await expect(quickAddButton).toHaveAttribute("aria-expanded", "true"); - await expect(page.getByRole("menuitem").first()).toBeVisible(); + // The desktop rail opens a dropdown; the phone shell opens the capture + // sheet the bottom nav's plus opens. Either proves the click landed. + await expect( + page + .getByRole("menuitem") + .or(page.locator('[role="dialog"][data-state="open"]')) + .first(), + ).toBeVisible(); // The tour stays mounted — the click went to the underlying button, // not anything in the tour layer. diff --git a/src/components/measurements/measurement-list.tsx b/src/components/measurements/measurement-list.tsx index f74c96bd6..032b28006 100644 --- a/src/components/measurements/measurement-list.tsx +++ b/src/components/measurements/measurement-list.tsx @@ -1087,7 +1087,10 @@ export function MeasurementList({ {t("measurements.emptyResetFilter")} ) : onAddFirst && canAddMeasurement ? ( -