Files
driver.js/packages/driver/tests/scroll.test.ts
Kamran Ahmed 75edd1b4bc Restructure as a Turborepo monorepo
packages/driver is the library (still published as driver.js, with
repository.directory set); playground and docs move to apps/. One root
pnpm workspace and lockfile replace the three standalone projects, with
turbo orchestrating build/test/lint:package (apps depend on the library
build; local + CI caching via .turbo).

Apps keep importing the library from source for HMR — the aliases now
point at ../../packages/driver/src and each app gains a workspace:*
dependency so the task graph knows the edge. The dev-server fs scope
widens to the repo root accordingly.

Releases run from packages/driver (root `pnpm release` delegates). The
changelog still lives in the docs app, so the release scripts reach it
via ../../../apps/docs and the after:bump hook stages it explicitly —
release-it no longer sits above both directories.

The merged workspace settings keep sharp unbuilt on purpose (prebuilt
binaries; building from source needs node-gyp and fails) — the docs app
had this right and the playground setting was the accident. postcss and
postcss-scss were unreferenced devDependencies and are dropped; prettier
moves to the root as the only shared tool.
2026-07-16 19:45:23 +01:00

71 lines
2.5 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it, vi } from "vitest";
import { createDriver, SAMPLE_STEPS, useDriverHarness } from "./utils";
useDriverHarness();
const hasNoScroll = () => document.body.classList.contains("driver-no-scroll");
// Forces #intro out of view and spies on its scrollIntoView so the chosen
// scroll behavior can be asserted. jsdom reports a 0×0 box that always counts as
// in-view, so without this the library never scrolls.
function spyOnScrollIntoView(): ReturnType<typeof vi.fn> {
const el = document.querySelector<HTMLElement>("#intro")!;
el.getBoundingClientRect = () =>
({ top: -500, left: 0, right: 0, bottom: -480, width: 0, height: 0, x: 0, y: 0, toJSON() {} }) as DOMRect;
const scrollIntoView = vi.fn();
el.scrollIntoView = scrollIntoView;
return scrollIntoView;
}
describe("allowScroll", () => {
it("allows body scrolling by default", () => {
const d = createDriver({ animate: false });
d.highlight({ element: "#intro", popover: { title: "Intro" } });
expect(d.getConfig().allowScroll).toBe(true);
expect(hasNoScroll()).toBe(false);
});
it("locks body scrolling when allowScroll is false", () => {
const d = createDriver({ animate: false, allowScroll: false });
d.highlight({ element: "#intro", popover: { title: "Intro" } });
expect(hasNoScroll()).toBe(true);
});
it("locks body scrolling for a tour when allowScroll is false", () => {
const d = createDriver({ animate: false, allowScroll: false, steps: SAMPLE_STEPS });
d.drive();
expect(hasNoScroll()).toBe(true);
});
it("releases the scroll lock on destroy", () => {
const d = createDriver({ animate: false, allowScroll: false });
d.highlight({ element: "#intro", popover: { title: "Intro" } });
d.destroy();
expect(hasNoScroll()).toBe(false);
});
});
describe("smoothScroll", () => {
it("scrolls instantly by default", () => {
const scrollIntoView = spyOnScrollIntoView();
const d = createDriver({ animate: false });
d.highlight({ element: "#intro", popover: { title: "Intro" } });
expect(scrollIntoView).toHaveBeenCalledTimes(1);
expect(scrollIntoView.mock.calls[0][0]).toMatchObject({ behavior: "auto" });
});
it("scrolls smoothly when smoothScroll is enabled", () => {
const scrollIntoView = spyOnScrollIntoView();
const d = createDriver({ animate: false, smoothScroll: true });
d.highlight({ element: "#intro", popover: { title: "Intro" } });
expect(scrollIntoView).toHaveBeenCalledTimes(1);
expect(scrollIntoView.mock.calls[0][0]).toMatchObject({ behavior: "smooth" });
});
});