scraping and data

This commit is contained in:
Andras Schmelczer 2026-05-31 15:36:33 +01:00
parent d98819b569
commit 8688b7475e
43 changed files with 4920 additions and 531 deletions

View file

@ -0,0 +1,107 @@
import { cleanup, fireEvent, render, screen } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import MobileDrawer from './MobileDrawer';
vi.mock('react-i18next', () => ({
useTranslation: () => ({
t: (key: string) => key,
}),
}));
const originalSetPointerCapture = HTMLElement.prototype.setPointerCapture;
function renderDrawer(onClose = vi.fn()) {
const view = render(
<MobileDrawer
onClose={onClose}
renderArea={() => <div>Area content</div>}
renderProperties={() => <div>Properties content</div>}
tab="area"
onTabChange={vi.fn()}
/>
);
const handle = view.container.querySelector('[data-mobile-drawer-drag-handle]');
const root = view.container.querySelector('[data-tutorial="right-pane"]');
const panel = view.container.querySelector('[data-tutorial="right-pane"] > div:last-child');
if (!(handle instanceof HTMLElement)) throw new Error('Expected drawer drag handle');
if (!(root instanceof HTMLElement)) throw new Error('Expected drawer root');
if (!(panel instanceof HTMLElement)) throw new Error('Expected drawer panel');
return { ...view, handle, onClose, panel, root };
}
describe('MobileDrawer', () => {
beforeEach(() => {
HTMLElement.prototype.setPointerCapture = vi.fn();
});
afterEach(() => {
cleanup();
Object.defineProperty(HTMLElement.prototype, 'setPointerCapture', {
configurable: true,
value: originalSetPointerCapture,
});
});
it('lowers and stays open when swiped down from the handle', () => {
const { handle, onClose, panel } = renderDrawer();
fireEvent.pointerDown(handle, { pointerId: 1, clientY: 120 });
fireEvent.pointerMove(handle, { pointerId: 1, clientY: 230 });
fireEvent.pointerUp(handle, { pointerId: 1, clientY: 230 });
expect(onClose).not.toHaveBeenCalled();
expect(panel.style.transform).toBe('translateY(110px)');
});
it('can be raised again after being lowered', () => {
const { handle, onClose, panel } = renderDrawer();
fireEvent.pointerDown(handle, { pointerId: 1, clientY: 120 });
fireEvent.pointerMove(handle, { pointerId: 1, clientY: 230 });
fireEvent.pointerUp(handle, { pointerId: 1, clientY: 230 });
fireEvent.pointerDown(handle, { pointerId: 2, clientY: 230 });
fireEvent.pointerMove(handle, { pointerId: 2, clientY: 170 });
fireEvent.pointerUp(handle, { pointerId: 2, clientY: 170 });
expect(onClose).not.toHaveBeenCalled();
expect(panel.style.transform).toBe('translateY(50px)');
});
it('keeps the close control reachable when dragged down far', () => {
const { handle, panel } = renderDrawer();
Object.defineProperty(panel, 'offsetHeight', {
configurable: true,
value: 200,
});
fireEvent.pointerDown(handle, { pointerId: 1, clientY: 120 });
fireEvent.pointerMove(handle, { pointerId: 1, clientY: 420 });
fireEvent.pointerUp(handle, { pointerId: 1, clientY: 420 });
expect(panel.style.transform).toBe('translateY(96px)');
});
it('leaves the rest of the mobile map usable while the panel is open', () => {
const { panel, root } = renderDrawer();
const spacer = root.firstElementChild;
if (!(spacer instanceof HTMLElement)) throw new Error('Expected drawer spacer');
expect(root.className).toContain('pointer-events-none');
expect(panel.className).toContain('pointer-events-auto');
expect(spacer.className).not.toContain('bg-black');
});
it('closes from the close button', () => {
const { onClose } = renderDrawer();
fireEvent.click(screen.getByLabelText('mobileDrawer.closeDrawer'));
expect(onClose).toHaveBeenCalledTimes(1);
});
});