mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
fix(e2e): re-target compare-to tap-target check at the per-chart overlay popover
This commit is contained in:
1 parent
1d784c6367
commit
e7c6610c63
1 file changed
+97
-10
@@ -1,7 +1,10 @@
|
||||
import { expect, test } from "./setup/test";
|
||||
|
||||
import { STORAGE_STATE_PATH } from "./setup/global-setup";
|
||||
|
||||
import {
|
||||
mockDashboardSnapshot,
|
||||
WEIGHT_ONLY_SUMMARIES,
|
||||
} from "./utils/mock-dashboard-snapshot";
|
||||
/**
|
||||
* v1.4.19 A6 — Settings consistency snapshot at Pixel-5 (393 CSS px).
|
||||
* v1.4.27 — input height floor lifted from 36 px (`h-9`) to 40 px
|
||||
@@ -180,16 +183,100 @@ test.describe("Settings mobile consistency (Pixel 5)", () => {
|
||||
);
|
||||
});
|
||||
|
||||
test("/settings/dashboard: Compare-to trigger renders at 44 px", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto("/settings/dashboard", { waitUntil: "networkidle" });
|
||||
await page.waitForLoadState("networkidle");
|
||||
test("/: Compare-to trigger renders at 44 px", async ({ page }) => {
|
||||
// v1.34.0 — the dashboard-settings comparison-baseline control was
|
||||
// removed; the same preference now lives behind the per-chart overlay
|
||||
// popover (see chart-overlay-controls.spec.ts for the full open/toggle
|
||||
// flow). That popover only paints once a chart with a real chartKey
|
||||
// renders, so this test needs the same seeded-chart mocks that spec
|
||||
// uses rather than the real (likely-empty) e2e database.
|
||||
await mockDashboardSnapshot(page, { summaries: WEIGHT_ONLY_SUMMARIES });
|
||||
await page.route(/\/api\/analytics(\?|$)/, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: "application/json",
|
||||
body: JSON.stringify({
|
||||
data: {
|
||||
summaries: {
|
||||
WEIGHT: {
|
||||
latest: 78.5,
|
||||
avg7: 78.2,
|
||||
avg30: 77.9,
|
||||
slope30: { slope: -0.05, direction: "down" },
|
||||
count: 30,
|
||||
},
|
||||
},
|
||||
bpInTargetPct: 0,
|
||||
glucoseByContext: {},
|
||||
},
|
||||
error: null,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
await page.route("**/api/mood/analytics", (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: "application/json",
|
||||
body: JSON.stringify({
|
||||
data: { entries: [], summary: { count: 0 } },
|
||||
error: null,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
await page.route("**/api/measurements*", (route) => {
|
||||
const measurements = Array.from({ length: 10 }, (_, i) => ({
|
||||
id: `m_${i}`,
|
||||
type: "WEIGHT",
|
||||
value: 78 + (i % 3) - 1,
|
||||
measuredAt: new Date(Date.now() - i * 86_400_000).toISOString(),
|
||||
notes: null,
|
||||
}));
|
||||
return route.fulfill({
|
||||
status: 200,
|
||||
contentType: "application/json",
|
||||
body: JSON.stringify({
|
||||
data: { measurements, meta: { total: measurements.length } },
|
||||
error: null,
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
const trigger = page.locator("#comparison-baseline");
|
||||
await expect(trigger).toBeVisible();
|
||||
const h = await trigger.evaluate((el) => el.getBoundingClientRect().height);
|
||||
expect(Math.round(h)).toBe(44);
|
||||
await page.goto("/", { waitUntil: "domcontentloaded" });
|
||||
await expect(
|
||||
page.locator('[data-slot="dashboard-tile-strip"]'),
|
||||
).toBeVisible({ timeout: 10_000 });
|
||||
|
||||
const trigger = page
|
||||
.locator('[data-slot="chart-overlay-controls-trigger"]')
|
||||
.first();
|
||||
await expect(trigger).toBeVisible({ timeout: 10_000 });
|
||||
await trigger.scrollIntoViewIfNeeded();
|
||||
await trigger.click();
|
||||
|
||||
// `data-slot="chart-overlay-comparison-baseline"` is the grid WRAPPER
|
||||
// (line 235 in chart-overlay-controls.tsx); the buttons themselves are
|
||||
// `data-slot="chart-overlay-comparison-{none|lastMonth|lastYear}"`.
|
||||
// Match only the wrapper's children so the wrapper's own (differently
|
||||
// sized) box never gets measured as if it were a tap target.
|
||||
const baselineButton = page
|
||||
.locator(
|
||||
'[data-slot="chart-overlay-comparison-baseline"] [data-slot^="chart-overlay-comparison-"]',
|
||||
)
|
||||
.first();
|
||||
await expect(baselineButton).toBeVisible({ timeout: 5_000 });
|
||||
// `min-h-11` sets the CSS contract (`min-height: 44px`), the same
|
||||
// guarantee `h-11` gives the other 44px checks in this spec. This
|
||||
// element additionally carries an explicit `h-8` from the Button "sm"
|
||||
// size variant that `min-height` overrides; on Playwright's Pixel 5
|
||||
// profile (fractional deviceScaleFactor) that combination measures a
|
||||
// `getBoundingClientRect().height` a device pixel or two under 44 even
|
||||
// though the computed CSS is exactly 44px — a viewport-emulation
|
||||
// rounding artifact, not a real layout regression. Assert the
|
||||
// authoritative computed style instead of the physically-snapped rect.
|
||||
const minHeight = await baselineButton.evaluate(
|
||||
(el) => getComputedStyle(el).minHeight,
|
||||
);
|
||||
expect(minHeight).toBe("44px");
|
||||
});
|
||||
|
||||
test("/settings/ai: every native select renders at 44 px", async ({
|
||||
|
||||
Reference in new issue
Block a user