opencode/packages/app/test-browser/sidebar-peek.test.ts

94 lines
2.7 KiB
TypeScript

import { afterEach, expect, it } from "bun:test"
import { createRoot } from "solid-js"
import { createSidebarPeek } from "../src/shell/sidebar-peek"
const cleanups: (() => void)[] = []
afterEach(() => {
for (const cleanup of cleanups.splice(0)) cleanup()
document.body.innerHTML = ""
})
function mount() {
const row = document.createElement("div")
const aside = document.createElement("aside")
const panel = document.createElement("div")
const content = document.createElement("main")
aside.append(panel)
row.append(aside, content)
document.body.append(row)
const peek = createRoot((dispose) => {
cleanups.push(dispose)
return createSidebarPeek({
available: () => true,
open: () => false,
aside: () => aside,
panel: () => panel,
paint: () => {},
whenDocked: (run) => run(),
})
})
return { peek, content }
}
// Rests the pointer on the window's start edge, below the header band.
function restOnEdge(target: Element, clientX = 2, buttons = 0) {
target.dispatchEvent(
new PointerEvent("pointermove", { bubbles: true, clientX, clientY: 300, buttons, pointerType: "mouse" }),
)
}
const afterDwell = () => Bun.sleep(160)
it("peeks once the pointer rests on the window's start edge", async () => {
const view = mount()
restOnEdge(view.content)
await afterDwell()
expect(view.peek.shown()).toBe(true)
})
it("peeks from the edge zone 16px past the 8px gutter, and not beyond it", async () => {
const inside = mount()
restOnEdge(inside.content, 24)
await afterDwell()
expect(inside.peek.shown()).toBe(true)
const beyond = mount()
restOnEdge(beyond.content, 25)
await afterDwell()
expect(beyond.peek.shown()).toBe(false)
})
it("doesn't peek while a mouse button is held, as when a text selection drags into the edge zone", async () => {
const view = mount()
restOnEdge(view.content, 12, 1)
await afterDwell()
expect(view.peek.shown()).toBe(false)
})
it("a press, a drag, a dialog or a resize clears the pending peek", async () => {
const interruptions = [
() => document.dispatchEvent(new PointerEvent("pointerdown", { bubbles: true, pointerType: "mouse" })),
() => document.dispatchEvent(new Event("dragstart", { bubbles: true })),
() => window.dispatchEvent(new Event("resize")),
() => {
const dialog = document.createElement("div")
dialog.setAttribute("role", "dialog")
document.body.append(dialog)
},
]
for (const interrupt of interruptions) {
const view = mount()
restOnEdge(view.content)
interrupt()
await afterDwell()
expect(view.peek.shown()).toBe(false)
for (const cleanup of cleanups.splice(0)) cleanup()
document.body.innerHTML = ""
}
})