9dfa06ffee
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
Signed-off-by: cls_宁波本机 <908705107@qq.com>
161 lines
4.8 KiB
TypeScript
161 lines
4.8 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);
|
|
|
|
// Buzz Term consumes wheel gestures as custom scrollback rather than through
|
|
// a native scroll container. The viewport lock must leave that vertical
|
|
// gesture alone so the substrate's own handler can receive it.
|
|
await page.evaluate(() => {
|
|
const terminal = document.createElement("section");
|
|
terminal.dataset.terminalOwner = "terminal";
|
|
terminal.dataset.testid = "terminal-wheel-target";
|
|
document.body.append(terminal);
|
|
});
|
|
await expect(
|
|
dispatchWheelPrevented(page, '[data-testid="terminal-wheel-target"]', {
|
|
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);
|
|
}
|
|
|
|
await page.evaluate(() => {
|
|
const terminal = document.createElement("section");
|
|
terminal.dataset.terminalOwner = "terminal";
|
|
terminal.dataset.testid = "terminal-wheel-target";
|
|
document.body.append(terminal);
|
|
});
|
|
for (const [deltaX, deltaY, prevented] of [
|
|
[120, 0, true],
|
|
[0, 120, false],
|
|
[120, 120, false],
|
|
[120, 20, true],
|
|
] as const) {
|
|
await expect(
|
|
dispatchWheelPrevented(page, '[data-testid="terminal-wheel-target"]', {
|
|
deltaX,
|
|
deltaY,
|
|
}),
|
|
).resolves.toBe(prevented);
|
|
}
|
|
|
|
// A concealed substrate is not an active custom wheel consumer. Keep dead
|
|
// space locked even if a future layout places Buzz content inside it.
|
|
await page.evaluate(() => {
|
|
const terminal = document.querySelector<HTMLElement>(
|
|
'[data-testid="terminal-wheel-target"]',
|
|
);
|
|
const buzzContent = document.createElement("div");
|
|
buzzContent.dataset.testid = "concealed-terminal-dead-space";
|
|
terminal?.append(buzzContent);
|
|
if (terminal) terminal.dataset.terminalOwner = "buzz";
|
|
});
|
|
await expect(
|
|
dispatchWheelPrevented(
|
|
page,
|
|
'[data-testid="concealed-terminal-dead-space"]',
|
|
{ deltaY: 120 },
|
|
),
|
|
).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);
|
|
});
|