fix: contain settings page overscroll (#1316)
This commit is contained in:
@@ -192,6 +192,11 @@
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--scrollbar-thumb) transparent;
|
||||
}
|
||||
/* App shell: lock the document to the viewport; each route owns its scroll container. */
|
||||
html,
|
||||
body {
|
||||
@apply h-full overflow-hidden overscroll-none;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
|
||||
@@ -116,7 +116,10 @@ function SettingsShell({
|
||||
/>
|
||||
{/* Scroll the content, not the topbar: min-h-0 lets this flex child
|
||||
shrink below its content height so overflow-y-auto can take effect. */}
|
||||
<div className="flex min-w-0 min-h-0 flex-1 flex-col gap-4 overflow-y-auto p-4 pt-0 pb-20">
|
||||
<div
|
||||
data-testid="settings-scroll-container"
|
||||
className="flex min-w-0 min-h-0 flex-1 flex-col gap-4 overflow-y-auto overscroll-contain p-4 pt-0 pb-20"
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -227,6 +227,32 @@ test.describe("Automations settings page", () => {
|
||||
});
|
||||
});
|
||||
|
||||
test("create page keeps scrolling inside the settings pane", async ({ testPage, seedData }) => {
|
||||
const automations = new AutomationsPage(testPage, seedData.workspaceId);
|
||||
await automations.gotoNew();
|
||||
|
||||
const rootScrollStyles = await testPage.evaluate(() => ({
|
||||
htmlOverflowY: getComputedStyle(document.documentElement).overflowY,
|
||||
htmlOverscrollY: getComputedStyle(document.documentElement).overscrollBehaviorY,
|
||||
bodyOverflowY: getComputedStyle(document.body).overflowY,
|
||||
bodyOverscrollY: getComputedStyle(document.body).overscrollBehaviorY,
|
||||
}));
|
||||
expect(rootScrollStyles).toEqual({
|
||||
htmlOverflowY: "hidden",
|
||||
htmlOverscrollY: "none",
|
||||
bodyOverflowY: "hidden",
|
||||
bodyOverscrollY: "none",
|
||||
});
|
||||
|
||||
const settingsScroller = testPage.getByTestId("settings-scroll-container");
|
||||
await expect(settingsScroller).toBeVisible();
|
||||
await expect(settingsScroller).toHaveCSS("overflow-y", "auto");
|
||||
await expect(settingsScroller).toHaveCSS("overscroll-behavior-y", "contain");
|
||||
|
||||
await testPage.mouse.wheel(0, 3000);
|
||||
await expect.poll(() => testPage.evaluate(() => window.scrollY), { timeout: 5_000 }).toBe(0);
|
||||
});
|
||||
|
||||
test("enable/disable toggle on list page", async ({ testPage, seedData }) => {
|
||||
const automations = new AutomationsPage(testPage, seedData.workspaceId);
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import type { Locator, Page } from "@playwright/test";
|
||||
import { test, expect } from "../fixtures/test-base";
|
||||
import { AutomationsPage } from "../pages/automations-page";
|
||||
|
||||
/** Swipe up on a scroll container — the touch equivalent of wheel-down at scroll bottom. */
|
||||
async function swipeUpOnElement(page: Page, element: Locator): Promise<void> {
|
||||
const box = await element.boundingBox();
|
||||
if (!box) throw new Error("scroll container has no bounding box");
|
||||
|
||||
const cdp = await page.context().newCDPSession(page);
|
||||
const centerX = box.x + box.width / 2;
|
||||
const startY = box.y + box.height - 20;
|
||||
const endY = box.y + 20;
|
||||
|
||||
await cdp.send("Input.dispatchTouchEvent", {
|
||||
type: "touchStart",
|
||||
touchPoints: [{ x: centerX, y: startY }],
|
||||
});
|
||||
for (let i = 1; i <= 8; i++) {
|
||||
const y = startY + ((endY - startY) * i) / 8;
|
||||
await cdp.send("Input.dispatchTouchEvent", {
|
||||
type: "touchMove",
|
||||
touchPoints: [{ x: centerX, y }],
|
||||
});
|
||||
}
|
||||
await cdp.send("Input.dispatchTouchEvent", {
|
||||
type: "touchEnd",
|
||||
touchPoints: [],
|
||||
});
|
||||
}
|
||||
|
||||
test.describe("Automations settings on mobile", () => {
|
||||
test("create page does not hand off bottom overscroll to the document", async ({
|
||||
testPage,
|
||||
seedData,
|
||||
}) => {
|
||||
const automations = new AutomationsPage(testPage, seedData.workspaceId);
|
||||
await automations.gotoNew();
|
||||
|
||||
const settingsScroller = testPage.getByTestId("settings-scroll-container");
|
||||
await expect(settingsScroller).toBeVisible();
|
||||
await expect(settingsScroller).toHaveCSS("overscroll-behavior-y", "contain");
|
||||
|
||||
await settingsScroller.evaluate((el) => {
|
||||
el.scrollTop = el.scrollHeight;
|
||||
});
|
||||
await swipeUpOnElement(testPage, settingsScroller);
|
||||
|
||||
await expect.poll(() => testPage.evaluate(() => window.scrollY), { timeout: 5_000 }).toBe(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user