Files
portal/app/tests/Frontend/DevIndexOverlay.spec.ts
T
2026-05-12 12:05:53 +03:00

159 lines
5.3 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import DevIndexOverlay from '../../resources/js/components/DevIndexOverlay.vue';
import { useDevIndices } from '../../resources/js/composables/useDevIndices';
describe('DevIndexOverlay', () => {
beforeEach(() => useDevIndices().reset());
it('hidden when no current target', () => {
mount(DevIndexOverlay, { attachTo: document.body });
expect(document.querySelector('.dx-badge')).toBeNull();
});
it('shows badge with id + tag when target is set', async () => {
const el = document.createElement('button');
el.setAttribute('data-dx', '1030');
el.textContent = 'Создать';
document.body.appendChild(el);
const dx = useDevIndices();
dx.setTarget(el);
mount(DevIndexOverlay, { attachTo: document.body });
await nextTick();
const badge = document.querySelector('.dx-badge');
expect(badge).not.toBeNull();
expect(badge!.textContent).toContain('1030');
expect(badge!.textContent!.toLowerCase()).toContain('button');
document.body.removeChild(el);
});
it('Esc clears the target', async () => {
const el = document.createElement('div');
el.setAttribute('data-dx', '5');
document.body.appendChild(el);
const dx = useDevIndices();
dx.setTarget(el);
mount(DevIndexOverlay, { attachTo: document.body });
await nextTick();
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }));
await nextTick();
expect(dx.currentId.value).toBeNull();
document.body.removeChild(el);
});
it('clicking the badge copies "#<id>" to clipboard', async () => {
const writeText = vi.fn().mockResolvedValue(undefined);
Object.defineProperty(navigator, 'clipboard', {
value: { writeText },
configurable: true,
});
const el = document.createElement('button');
el.setAttribute('data-dx', '1030');
document.body.appendChild(el);
useDevIndices().setTarget(el);
mount(DevIndexOverlay, { attachTo: document.body });
await nextTick();
const badge = document.querySelector('.dx-badge') as HTMLElement;
expect(badge).not.toBeNull();
badge.click();
await nextTick();
expect(writeText).toHaveBeenCalledWith('#1030');
document.body.removeChild(el);
});
});
describe('DevIndexOverlay — Alt-keys + overlay-mode', () => {
beforeEach(() => useDevIndices().reset());
it('Alt+ArrowUp walks to parent', async () => {
const grand = document.createElement('div');
grand.setAttribute('data-dx', '100');
const child = document.createElement('button');
child.setAttribute('data-dx', '200');
grand.appendChild(child);
document.body.appendChild(grand);
const dx = useDevIndices();
dx.setTarget(child);
mount(DevIndexOverlay, { attachTo: document.body });
await nextTick();
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowUp', altKey: true }));
await nextTick();
expect(dx.currentId.value).toBe(100);
document.body.removeChild(grand);
});
it('Alt+ArrowDown walks to first descendant', async () => {
const parent = document.createElement('div');
parent.setAttribute('data-dx', '1');
const child = document.createElement('span');
child.setAttribute('data-dx', '2');
parent.appendChild(child);
document.body.appendChild(parent);
const dx = useDevIndices();
dx.setTarget(parent);
mount(DevIndexOverlay, { attachTo: document.body });
await nextTick();
document.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', altKey: true }));
await nextTick();
expect(dx.currentId.value).toBe(2);
document.body.removeChild(parent);
});
it('Alt+Shift+I toggles overlay-mode', async () => {
mount(DevIndexOverlay, { attachTo: document.body });
await nextTick();
const dx = useDevIndices();
expect(dx.overlayMode.value).toBe(false);
document.dispatchEvent(
new KeyboardEvent('keydown', { key: 'I', altKey: true, shiftKey: true }),
);
await nextTick();
expect(dx.overlayMode.value).toBe(true);
document.dispatchEvent(
new KeyboardEvent('keydown', { key: 'I', altKey: true, shiftKey: true }),
);
await nextTick();
expect(dx.overlayMode.value).toBe(false);
});
it('overlay-mode renders mini-badges on all [data-dx] elements', async () => {
const a = document.createElement('div');
a.setAttribute('data-dx', '1');
const b = document.createElement('div');
b.setAttribute('data-dx', '2');
document.body.append(a, b);
mount(DevIndexOverlay, { attachTo: document.body });
useDevIndices().toggleOverlay();
await nextTick();
const minis = document.querySelectorAll('.dx-mini');
expect(minis.length).toBeGreaterThanOrEqual(2);
document.body.removeChild(a);
document.body.removeChild(b);
});
});