mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
107 lines
3.0 KiB
TypeScript
107 lines
3.0 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
|
|
import { installMockBridge } from "../helpers/bridge";
|
|
|
|
async function dispatchWheelPrevented(
|
|
page: import("@playwright/test").Page,
|
|
selector: string,
|
|
deltas: { deltaX?: number; deltaY?: number },
|
|
) {
|
|
return page.evaluate(
|
|
({ selector, deltaX, deltaY }) => {
|
|
const element = document.querySelector(selector);
|
|
if (!element) {
|
|
throw new Error(`Missing element for selector: ${selector}`);
|
|
}
|
|
|
|
const event = new WheelEvent("wheel", {
|
|
bubbles: true,
|
|
cancelable: true,
|
|
deltaX,
|
|
deltaY,
|
|
});
|
|
element.dispatchEvent(event);
|
|
return event.defaultPrevented;
|
|
},
|
|
{ selector, deltaX: deltas.deltaX ?? 0, deltaY: deltas.deltaY ?? 0 },
|
|
);
|
|
}
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
await installMockBridge(page);
|
|
});
|
|
|
|
test("locks viewport rubber-band outside conversation scrollers", async ({
|
|
page,
|
|
}) => {
|
|
await page.goto("/");
|
|
await page.getByTestId("channel-general").click();
|
|
await expect(page.getByTestId("message-timeline")).toBeVisible();
|
|
|
|
await expect(
|
|
dispatchWheelPrevented(page, '[data-testid="app-top-chrome"]', {
|
|
deltaY: -120,
|
|
}),
|
|
).resolves.toBe(true);
|
|
await expect(
|
|
dispatchWheelPrevented(page, '[data-testid="sidebar-pinned-header"]', {
|
|
deltaY: -120,
|
|
}),
|
|
).resolves.toBe(true);
|
|
await expect(
|
|
dispatchWheelPrevented(page, '[data-testid="app-sidebar-scroll-anchor"]', {
|
|
deltaY: -120,
|
|
}),
|
|
).resolves.toBe(true);
|
|
await expect(
|
|
dispatchWheelPrevented(page, '[data-testid="chat-title"]', {
|
|
deltaY: -120,
|
|
}),
|
|
).resolves.toBe(true);
|
|
|
|
await expect(
|
|
dispatchWheelPrevented(page, '[data-testid="message-timeline"]', {
|
|
deltaY: -120,
|
|
}),
|
|
).resolves.toBe(false);
|
|
});
|
|
|
|
test("locks horizontal viewport pan everywhere", async ({ page }) => {
|
|
await page.goto("/");
|
|
await page.getByTestId("channel-general").click();
|
|
await expect(page.getByTestId("message-timeline")).toBeVisible();
|
|
|
|
for (const deltaX of [-120, 120]) {
|
|
await expect(
|
|
dispatchWheelPrevented(page, '[data-testid="app-top-chrome"]', {
|
|
deltaX,
|
|
}),
|
|
).resolves.toBe(true);
|
|
await expect(
|
|
dispatchWheelPrevented(page, '[data-testid="sidebar-pinned-header"]', {
|
|
deltaX,
|
|
}),
|
|
).resolves.toBe(true);
|
|
await expect(
|
|
dispatchWheelPrevented(page, '[data-testid="chat-title"]', { deltaX }),
|
|
).resolves.toBe(true);
|
|
|
|
// Unlike vertical, horizontal pans over the conversation pane are locked
|
|
// too — there is no horizontal elastic affordance.
|
|
await expect(
|
|
dispatchWheelPrevented(page, '[data-testid="message-timeline"]', {
|
|
deltaX,
|
|
}),
|
|
).resolves.toBe(true);
|
|
}
|
|
|
|
// A predominantly vertical gesture with slight horizontal drift still
|
|
// reaches the conversation scroller.
|
|
await expect(
|
|
dispatchWheelPrevented(page, '[data-testid="message-timeline"]', {
|
|
deltaX: -10,
|
|
deltaY: -120,
|
|
}),
|
|
).resolves.toBe(false);
|
|
});
|