Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions e2e/smoke/responsive-mobile.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// TEMPLATE: adaptable example.
/**
* E2E smoke: the new features fit a 375px mobile viewport.
*
* Catches the horizontal-overflow class of responsive bug (a fixed-width
* element wider than the screen) on the surfaces added this cycle. The
* assertion is document-wide: scrollWidth must not exceed the viewport.
*/
import {test, expect, cancelDialog} from "../fixtures/base";
import type {Page} from "@playwright/test";

test.use({viewport: {width: 375, height: 812}});

/** Horizontal overflow in px (<= 1 means the page fits the viewport). */
async function horizontalOverflow(page: Page): Promise<number> {
return page.evaluate(() => document.documentElement.scrollWidth - window.innerWidth);
}

test.describe("Mobile 375px - new surfaces fit the viewport", () => {
test("command palette overlay fits", async ({page}) => {
await page.goto("/");
await page.keyboard.press("Control+k");
await expect(page.getByTestId("command-palette")).toBeVisible();
expect(await horizontalOverflow(page)).toBeLessThanOrEqual(1);
});

test("About tab + QR modal fit", async ({page}) => {
await page.goto("/settings?tab=about");
await expect(page.getByTestId("about-tab")).toBeVisible();
expect(await horizontalOverflow(page)).toBeLessThanOrEqual(1);
await page.getByTestId("about-share-button").click();
await expect(page.getByTestId("qr-modal")).toBeVisible();
expect(await horizontalOverflow(page)).toBeLessThanOrEqual(1);
});

test("Appearance + Data tabs fit", async ({page}) => {
await page.goto("/settings?tab=appearance");
await expect(page.getByTestId("appearance-settings")).toBeVisible();
expect(await horizontalOverflow(page)).toBeLessThanOrEqual(1);

await page.goto("/settings?tab=data");
await expect(page.getByTestId("data-settings")).toBeVisible();
expect(await horizontalOverflow(page)).toBeLessThanOrEqual(1);
// Destructive action must still confirm on mobile; cancel to avoid reload.
await page.getByTestId("data-clear-cache").click();
await cancelDialog(page);
});
});
11 changes: 7 additions & 4 deletions frontend/src/components/QrCodeModal.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,18 @@
}

.qr {
width: 240px;
height: 240px;
width: 100%;
max-width: 240px;
height: auto;
aspect-ratio: 1 / 1;
background: #ffffff; /* token-exempt: QR must stay black-on-white to scan */
border-radius: var(--radius-sm);
}

.qrPlaceholder {
width: 240px;
height: 240px;
width: 100%;
max-width: 240px;
aspect-ratio: 1 / 1;
background: var(--bg-hover, var(--border));
border-radius: var(--radius-sm);
}
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/components/pwa/UpdatePrompt.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
transform: translateX(-50%);
z-index: 9999;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.75rem;
justify-content: flex-end;
gap: 0.5rem 0.75rem;
max-width: calc(100vw - 2rem);
padding: 0.625rem 0.875rem;
background: var(--bg-card);
Expand Down