import { expect, tap } from '@git.zone/tstest/tapbundle'; import { DeesInputWysiwyg } from '../ts_web/elements/wysiwyg/dees-input-wysiwyg.js'; // Initialize the element DeesInputWysiwyg; tap.test('wysiwyg drag and drop should work correctly', async () => { const element = document.createElement('dees-input-wysiwyg'); document.body.appendChild(element); // Wait for element to be ready await element.updateComplete; // Set initial content with multiple blocks element.blocks = [ { id: 'block1', type: 'paragraph', content: 'First paragraph' }, { id: 'block2', type: 'heading-2', content: 'Test Heading' }, { id: 'block3', type: 'paragraph', content: 'Second paragraph' }, ]; element.renderBlocksProgrammatically(); await element.updateComplete; // Check that blocks are rendered const editorContent = element.shadowRoot!.querySelector('.editor-content') as HTMLDivElement; expect(editorContent).toBeTruthy(); const blockWrappers = editorContent.querySelectorAll('.block-wrapper'); expect(blockWrappers.length).toEqual(3); // Test drag handles exist for non-divider blocks const dragHandles = editorContent.querySelectorAll('.drag-handle'); expect(dragHandles.length).toEqual(3); // Get references to specific blocks const firstBlock = editorContent.querySelector('[data-block-id="block1"]') as HTMLElement; const secondBlock = editorContent.querySelector('[data-block-id="block2"]') as HTMLElement; const firstDragHandle = firstBlock.querySelector('.drag-handle') as HTMLElement; expect(firstBlock).toBeTruthy(); expect(secondBlock).toBeTruthy(); expect(firstDragHandle).toBeTruthy(); // Test drag initialization console.log('Testing drag initialization...'); // Create drag event const dragStartEvent = new DragEvent('dragstart', { dataTransfer: new DataTransfer(), clientY: 100, bubbles: true }); // Simulate drag start firstDragHandle.dispatchEvent(dragStartEvent); // Check that drag state is initialized expect(element.dragDropHandler.dragState.draggedBlockId).toEqual('block1'); // Check that dragging class is applied await new Promise(resolve => setTimeout(resolve, 20)); // Wait for setTimeout in drag start expect(firstBlock.classList.contains('dragging')).toBeTrue(); expect(editorContent.classList.contains('dragging')).toBeTrue(); // Test drop indicator creation const dropIndicator = editorContent.querySelector('.drop-indicator'); expect(dropIndicator).toBeTruthy(); // Simulate drag over const dragOverEvent = new DragEvent('dragover', { dataTransfer: new DataTransfer(), clientY: 200, bubbles: true, cancelable: true }); document.dispatchEvent(dragOverEvent); // Check that blocks move out of the way console.log('Checking block movements...'); const blocks = Array.from(editorContent.querySelectorAll('.block-wrapper')); const hasMovedBlocks = blocks.some(block => block.classList.contains('move-up') || block.classList.contains('move-down') ); console.log('Blocks with move classes:', blocks.filter(block => block.classList.contains('move-up') || block.classList.contains('move-down') ).length); // Test drag end const dragEndEvent = new DragEvent('dragend', { bubbles: true }); document.dispatchEvent(dragEndEvent); // Wait for cleanup await new Promise(resolve => setTimeout(resolve, 150)); // Check that drag state is cleaned up expect(element.dragDropHandler.dragState.draggedBlockId).toBeNull(); expect(firstBlock.classList.contains('dragging')).toBeFalse(); expect(editorContent.classList.contains('dragging')).toBeFalse(); // Check that drop indicator is removed const dropIndicatorAfter = editorContent.querySelector('.drop-indicator'); expect(dropIndicatorAfter).toBeFalsy(); // Clean up document.body.removeChild(element); }); tap.test('wysiwyg drag and drop visual feedback', async () => { const element = document.createElement('dees-input-wysiwyg'); document.body.appendChild(element); await element.updateComplete; // Set initial content element.blocks = [ { id: 'block1', type: 'paragraph', content: 'Block 1' }, { id: 'block2', type: 'paragraph', content: 'Block 2' }, { id: 'block3', type: 'paragraph', content: 'Block 3' }, ]; element.renderBlocksProgrammatically(); await element.updateComplete; const editorContent = element.shadowRoot!.querySelector('.editor-content') as HTMLDivElement; const block1 = editorContent.querySelector('[data-block-id="block1"]') as HTMLElement; const dragHandle1 = block1.querySelector('.drag-handle') as HTMLElement; // Start dragging block 1 const dragStartEvent = new DragEvent('dragstart', { dataTransfer: new DataTransfer(), clientY: 50, bubbles: true }); dragHandle1.dispatchEvent(dragStartEvent); // Wait for dragging class await new Promise(resolve => setTimeout(resolve, 20)); // Simulate dragging down const dragOverEvent = new DragEvent('dragover', { dataTransfer: new DataTransfer(), clientY: 150, // Move down past block 2 bubbles: true, cancelable: true }); // Trigger the global drag over handler element.dragDropHandler['handleGlobalDragOver'](dragOverEvent); // Check that transform is applied to dragged block const transform = block1.style.transform; console.log('Dragged block transform:', transform); expect(transform).toContain('translateY'); // Check drop indicator position const dropIndicator = editorContent.querySelector('.drop-indicator') as HTMLElement; if (dropIndicator) { const indicatorStyle = dropIndicator.style; console.log('Drop indicator position:', indicatorStyle.top, 'display:', indicatorStyle.display); } // Clean up document.body.removeChild(element); }); tap.start();