You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/arts/adom/test/body-scroll-lock.test.ts

116 lines
3.0 KiB

// @vitest-environment jsdom
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { BodyScrollLock } from '../body-scroll-lock.svelte';
describe('BodyScrollLock', () => {
beforeEach(() => {
vi.useFakeTimers();
BodyScrollLock.reset();
document.body.setAttribute('style', 'background: red;');
Object.defineProperty(window, 'innerWidth', {
configurable: true,
writable: true,
value: 1200
});
Object.defineProperty(document.documentElement, 'clientWidth', {
configurable: true,
value: 1180
});
});
afterEach(() => {
BodyScrollLock.reset();
vi.useRealTimers();
});
it('locks body scroll and restores the initial body style when unlocked', async () => {
const lock = new BodyScrollLock(true);
await Promise.resolve();
expect(document.body.style.overflow).toBe('hidden');
expect(document.body.style.getPropertyValue('--scrollbar-width')).toBe('20px');
lock.locked.current = false;
vi.runAllTimers();
await Promise.resolve();
expect(document.body.getAttribute('style')).toBe('background: red;');
});
it('does not block pointer events while locked', async () => {
const lock = new BodyScrollLock(true);
await Promise.resolve();
expect(document.body.style.pointerEvents).toBe('');
lock.destroy();
vi.runAllTimers();
await Promise.resolve();
});
it('keeps the body locked until the last lock is released', async () => {
const first = new BodyScrollLock(true);
const second = new BodyScrollLock(true);
await Promise.resolve();
first.locked.current = false;
vi.runAllTimers();
await Promise.resolve();
expect(document.body.style.overflow).toBe('hidden');
second.destroy();
vi.runAllTimers();
await Promise.resolve();
expect(document.body.getAttribute('style')).toBe('background: red;');
});
it('uses the last active lock delay instead of stale unlocked instances', async () => {
const first = new BodyScrollLock(true, () => 200);
const second = new BodyScrollLock(true, () => 50);
await Promise.resolve();
first.locked.current = false;
vi.runAllTimers();
await Promise.resolve();
expect(document.body.style.overflow).toBe('hidden');
second.locked.current = false;
vi.advanceTimersByTime(49);
await Promise.resolve();
expect(document.body.style.overflow).toBe('hidden');
vi.advanceTimersByTime(1);
await Promise.resolve();
expect(document.body.getAttribute('style')).toBe('background: red;');
});
it('keeps the final lock restore delay when destroyed', async () => {
const lock = new BodyScrollLock(true, () => 120);
await Promise.resolve();
lock.destroy();
vi.advanceTimersByTime(119);
await Promise.resolve();
expect(document.body.style.overflow).toBe('hidden');
vi.advanceTimersByTime(1);
await Promise.resolve();
expect(document.body.getAttribute('style')).toBe('background: red;');
});
it('allows creating unlocked instances without mutating the body', () => {
new BodyScrollLock(false);
expect(document.body.getAttribute('style')).toBe('background: red;');
});
});

Powered by TurnKey Linux.