import { expect, tap } from '@git.zone/tstest/tapbundle'; import { DeesInputWysiwyg } from '../ts_web/elements/00group-input/dees-input-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; // Wait for nested block components to also complete their updates await new Promise(resolve => setTimeout(resolve, 50)); // 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(); // Verify drag drop handler exists expect(element.dragDropHandler).toBeTruthy(); expect(element.dragDropHandler.dragState).toBeTruthy(); // Test drag initialization - synthetic DragEvents may not fully work in all browsers 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); // Wait for setTimeout in drag start await new Promise(resolve => setTimeout(resolve, 50)); // Note: Synthetic DragEvents may not fully initialize drag state in all test environments // The test verifies the structure and that events can be dispatched console.log('Drag state after start:', element.dragDropHandler.dragState.draggedBlockId); // Test drag end cleanup const dragEndEvent = new DragEvent('dragend', { bubbles: true }); document.dispatchEvent(dragEndEvent); // Wait for cleanup await new Promise(resolve => setTimeout(resolve, 150)); // 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; // Wait for nested block components to also complete their updates await new Promise(resolve => setTimeout(resolve, 50)); 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); }); export default tap.start();