UNPKG

igniteui-angular-sovn

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

1,092 lines (888 loc) 92.7 kB
import { Component, ViewChildren, QueryList, ViewChild, ElementRef, TemplateRef, Renderer2 } from '@angular/core'; import { TestBed, ComponentFixture, waitForAsync } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { UIInteractions, wait} from '../../test-utils/ui-interactions.spec'; import { configureTestSuite } from '../../test-utils/configure-suite'; import { first } from 'rxjs/operators'; import { IgxInsertDropStrategy, IgxAppendDropStrategy, IgxPrependDropStrategy } from './drag-drop.strategy'; import { IgxDragDirective, IgxDropDirective, IgxDragLocation, IDropDroppedEventArgs, DragDirection, IgxDragHandleDirective, IgxDragIgnoreDirective } from './drag-drop.directive'; describe('General igxDrag/igxDrop', () => { let fix: ComponentFixture<TestDragDropComponent>; let dropArea: IgxDropDirective; let dropAreaRects = { top: 0, left: 0, right: 0, bottom: 0}; let dragDirsRects = [{ top: 0, left: 0, right: 0, bottom: 0}]; configureTestSuite(); beforeAll(waitForAsync(() => { TestBed.configureTestingModule({ imports: [TestDragDropComponent] }) .compileComponents(); })); beforeEach(() => { fix = TestBed.createComponent(TestDragDropComponent); fix.detectChanges(); dragDirsRects = getDragDirsRects(fix.componentInstance.dragElems); dropArea = fix.componentInstance.dropArea; dropAreaRects = getElemRects(dropArea.element.nativeElement); }); it('should correctly initialize drag and drop directives.', () => { const ignoredElem = fix.debugElement.query(By.css('.ignoredElem')).nativeElement; expect(fix.componentInstance.dragElems.length).toEqual(3); expect(fix.componentInstance.dragElems.last.data).toEqual({ key: 3 }); expect(fix.componentInstance.dropArea).toBeTruthy(); expect(fix.componentInstance.dropArea.data).toEqual({ key: 333 }); expect(fix.componentInstance.dragElems.last.dragIgnoredElems.length).toEqual(1); expect(fix.componentInstance.dragElems.last.dragIgnoredElems.first.element.nativeElement).toEqual(ignoredElem); }); it('should create drag ghost element and trigger ghostCreate/ghostDestroy.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; spyOn(firstDrag.ghostCreate, 'emit'); spyOn(firstDrag.ghostDestroy, 'emit'); expect(document.getElementsByClassName('dragElem').length).toEqual(3); // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); expect(firstDrag.ghostCreate.emit).not.toHaveBeenCalled(); expect(firstDrag.ghostDestroy.emit).not.toHaveBeenCalled(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); expect(firstDrag.ghostCreate.emit).toHaveBeenCalled(); expect(firstDrag.ghostDestroy.emit).not.toHaveBeenCalled(); expect(firstDrag.ghostElement).toBeDefined(); expect(firstDrag.ghostElement.id).toEqual('firstDrag'); expect(firstDrag.ghostElement.className).toEqual('dragElem igx-drag igx-drag--select-disabled'); expect(document.getElementsByClassName('dragElem').length).toEqual(4); // Step 3. // We need to trigger the pointerup on the ghostElement because this is the element we move and is under the mouse UIInteractions.simulatePointerEvent('pointerup', firstDrag.ghostElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(); expect(firstDrag.ghostElement).toBeNull(); expect(document.getElementsByClassName('dragElem').length).toEqual(3); expect(firstDrag.ghostCreate.emit).toHaveBeenCalled(); expect(firstDrag.ghostDestroy.emit).toHaveBeenCalled(); }); it('should trigger dragStart/dragMove/dragEnd events in that order.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; spyOn(firstDrag.dragStart, 'emit'); spyOn(firstDrag.dragMove, 'emit'); spyOn(firstDrag.dragEnd, 'emit'); // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); expect(firstDrag.dragStart.emit).not.toHaveBeenCalled(); expect(firstDrag.dragMove.emit).not.toHaveBeenCalled(); expect(firstDrag.dragEnd.emit).not.toHaveBeenCalled(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); expect(firstDrag.dragStart.emit).toHaveBeenCalled(); expect(firstDrag.dragMove.emit).toHaveBeenCalled(); expect(firstDrag.dragEnd.emit).not.toHaveBeenCalled(); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); expect(firstDrag.dragStart.emit).toHaveBeenCalled(); expect(firstDrag.dragMove.emit).toHaveBeenCalled(); expect(firstDrag.dragEnd.emit).not.toHaveBeenCalled(); // Step 4. // We need to trigger the pointerup on the ghostElement because this is the element we move and is under the mouse UIInteractions.simulatePointerEvent('pointerup', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); expect(firstDrag.dragStart.emit).toHaveBeenCalled(); expect(firstDrag.dragMove.emit).toHaveBeenCalled(); expect(firstDrag.dragEnd.emit).toHaveBeenCalled(); }); it('should trigger dragStart/dragMove/dragEnd events in that order when pointer is lost', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; spyOn(firstDrag.dragStart, 'emit'); spyOn(firstDrag.dragMove, 'emit'); spyOn(firstDrag.dragEnd, 'emit'); // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); expect(firstDrag.dragStart.emit).not.toHaveBeenCalled(); expect(firstDrag.dragMove.emit).not.toHaveBeenCalled(); expect(firstDrag.dragEnd.emit).not.toHaveBeenCalled(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); expect(firstDrag.dragStart.emit).toHaveBeenCalled(); expect(firstDrag.dragMove.emit).toHaveBeenCalled(); expect(firstDrag.dragEnd.emit).not.toHaveBeenCalled(); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); expect(firstDrag.dragStart.emit).toHaveBeenCalled(); expect(firstDrag.dragMove.emit).toHaveBeenCalled(); expect(firstDrag.dragEnd.emit).not.toHaveBeenCalled(); // Step 4. // We need to trigger the pointerup on the ghostElement because this is the element we move and is under the mouse UIInteractions.simulatePointerEvent('lostpointercapture', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); expect(firstDrag.dragStart.emit).toHaveBeenCalled(); expect(firstDrag.dragMove.emit).toHaveBeenCalled(); expect(firstDrag.dragEnd.emit).toHaveBeenCalled(); }); it('should not create drag ghost element when the dragged amount is less than dragTolerance.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstDrag.dragTolerance = 15; spyOn(firstDrag.ghostCreate, 'emit'); spyOn(firstDrag.ghostDestroy, 'emit'); spyOn(firstDrag.dragClick, 'emit'); expect(document.getElementsByClassName('dragElem').length).toEqual(3); // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); expect(firstDrag.ghostCreate.emit).not.toHaveBeenCalled(); expect(firstDrag.ghostDestroy.emit).not.toHaveBeenCalled(); expect(firstDrag.dragClick.emit).not.toHaveBeenCalled(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement).not.toBeDefined(); expect(document.getElementsByClassName('dragElem').length).toEqual(3); expect(firstDrag.ghostCreate.emit).not.toHaveBeenCalled(); expect(firstDrag.ghostDestroy.emit).not.toHaveBeenCalled(); expect(firstDrag.dragClick.emit).not.toHaveBeenCalled(); // Step 3. // We need to trigger the pointerup on the ghostElement because this is the element we move and is under the mouse UIInteractions.simulatePointerEvent('pointerup', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(); expect(firstDrag.ghostElement).not.toBeDefined(); expect(document.getElementsByClassName('dragElem').length).toEqual(3); expect(firstDrag.ghostCreate.emit).not.toHaveBeenCalled(); expect(firstDrag.ghostDestroy.emit).not.toHaveBeenCalled(); expect(firstDrag.dragClick.emit).toHaveBeenCalled(); }); it('should position ghost at the same position relative to the mouse when drag started.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); // We compare the base position and the new position + how much the mouse has moved. expect(firstDrag.ghostElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 20); expect(firstDrag.ghostElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 20); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); }); it('should move ghost only horizontally when drag direction is set to horizontal.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstDrag.dragDirection = DragDirection.HORIZONTAL; // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); // We compare the base position and the new position + how much the mouse has moved. expect(firstDrag.ghostElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 20); expect(firstDrag.ghostElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); }); it('should move ghost only vertically when drag direction is set to vertical.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstDrag.dragDirection = DragDirection.VERTICAL; // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); // We compare the base position and the new position + how much the mouse has moved. expect(firstDrag.ghostElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left); expect(firstDrag.ghostElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 20); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); }); it('should position ghost relative to the mouse using offsetX and offsetY correctly.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstDrag.ghostOffsetX = 0; firstDrag.ghostOffsetY = 0; // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(50); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement.getBoundingClientRect().left).toEqual(startingX + 20); expect(firstDrag.ghostElement.getBoundingClientRect().top).toEqual(startingY + 20); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); }); it('should position ghost at the same position relative to the mouse when drag started when host is defined.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstDrag.ghostHost = firstElement.parentElement; // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); // We compare the base position and the new position + how much the mouse has moved. expect(firstDrag.ghostElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 20); expect(firstDrag.ghostElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 20); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); }); it(`should create ghost at the same position relative to the mouse when drag started when host has custom style position.`, async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstElement.parentElement.style.left = '50px'; firstElement.parentElement.style.top = '50px'; firstElement.parentElement.style.position = 'relative'; firstDrag.ghostHost = firstElement.parentElement; UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); (firstDrag as any).createGhost(startingX + 10, startingY + 10); fix.detectChanges(); expect(firstDrag.ghostElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 60); expect(firstDrag.ghostElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 60); }); it('should allow customizing of ghost element by passing template reference and position it correctly.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstDrag.ghostTemplate = fix.componentInstance.ghostTemplate; // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); // We compare the base position and the new position + how much the mouse has moved. expect(firstDrag.ghostElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 20); expect(firstDrag.ghostElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 20); expect(firstDrag.ghostElement.innerText).toEqual('Drag Template'); expect(firstDrag.ghostElement.className).toEqual('ghostElement'); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); }); it('should position custom ghost relative to the mouse using offsetX and offsetY correctly.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstDrag.ghostOffsetX = 0; firstDrag.ghostOffsetY = 0; firstDrag.ghostTemplate = fix.componentInstance.ghostTemplate; // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); // We compare the base position and the new position + how much the mouse has moved. // + 10 margin to the final ghost position expect(firstDrag.ghostElement.getBoundingClientRect().left).toEqual(startingX + 20); expect(firstDrag.ghostElement.getBoundingClientRect().top).toEqual(startingY + 20); expect(firstDrag.ghostElement.innerText).toEqual('Drag Template'); expect(firstDrag.ghostElement.className).toEqual('ghostElement'); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); }); it(`should take first child when creating ghost from template that has display content`, async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstDrag.ghostOffsetX = 0; firstDrag.ghostOffsetY = 0; firstDrag.ghostTemplate = fix.componentInstance.ghostTemplateContents; // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); // We compare the base position and the new position + how much the mouse has moved. // + 10 margin to the final ghost position expect(firstDrag.ghostElement.getBoundingClientRect().left).toEqual(startingX + 20); expect(firstDrag.ghostElement.getBoundingClientRect().top).toEqual(startingY + 20); expect(firstDrag.ghostElement.innerText).toEqual('Drag Template Content'); expect(firstDrag.ghostElement.id).toEqual('contentsTemplate'); expect(firstDrag.ghostElement.style.display).toEqual('block'); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); }); it('should correctly move igxDrag element when ghost is disabled and trigger dragStart/dragMove/dragEnd events.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstDrag.ghost = false; spyOn(firstDrag.dragStart, 'emit'); spyOn(firstDrag.dragMove, 'emit'); spyOn(firstDrag.dragEnd, 'emit'); // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); expect(firstDrag.dragStart.emit).not.toHaveBeenCalled(); expect(firstDrag.dragMove.emit).not.toHaveBeenCalled(); expect(firstDrag.dragEnd.emit).not.toHaveBeenCalled(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement).not.toBeDefined(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 10); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 10); expect(firstDrag.dragStart.emit).toHaveBeenCalled(); expect(firstDrag.dragMove.emit).toHaveBeenCalled(); expect(firstDrag.dragEnd.emit).not.toHaveBeenCalled(); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement).not.toBeDefined(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 20); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 20); expect(firstDrag.dragStart.emit).toHaveBeenCalled(); expect(firstDrag.dragMove.emit).toHaveBeenCalled(); expect(firstDrag.dragEnd.emit).not.toHaveBeenCalled(); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 20); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 20); expect(firstDrag.dragStart.emit).toHaveBeenCalled(); expect(firstDrag.dragMove.emit).toHaveBeenCalled(); expect(firstDrag.dragEnd.emit).toHaveBeenCalled(); }); it('should move igxDrag element only horizontally when ghost is disabled and direction is set to horizontal.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstDrag.ghost = false; firstDrag.dragDirection = DragDirection.HORIZONTAL; fix.detectChanges(); // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement).not.toBeDefined(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 10); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement).not.toBeDefined(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 20); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 20); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top); }); it('should move igxDrag element only vertically when ghost is disabled and direction is set to vertical.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstDrag.ghost = false; firstDrag.dragDirection = DragDirection.VERTICAL; fix.detectChanges(); // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement).not.toBeDefined(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 10); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement).not.toBeDefined(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 20); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 20); }); it('should prevent dragging if it does not exceed dragTolerance and ghost is disabled.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstDrag.ghost = false; firstDrag.dragTolerance = 25; spyOn(firstDrag.dragStart, 'emit'); spyOn(firstDrag.dragClick, 'emit'); // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); expect(firstDrag.dragStart.emit).not.toHaveBeenCalled(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement).not.toBeDefined(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top); expect(firstDrag.dragStart.emit).not.toHaveBeenCalled(); expect(firstDrag.dragClick.emit).not.toHaveBeenCalled(); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement).not.toBeDefined(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top); expect(firstDrag.dragStart.emit).not.toHaveBeenCalled(); expect(firstDrag.dragClick.emit).not.toHaveBeenCalled(); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top); expect(firstDrag.dragStart.emit).not.toHaveBeenCalled(); expect(firstDrag.dragClick.emit).toHaveBeenCalled(); }); it('should correctly apply dragTolerance of 0 when it is set to 0 and ghost is disabled.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstDrag.ghost = false; firstDrag.dragTolerance = 0; spyOn(firstDrag.dragStart, 'emit'); // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); expect(firstDrag.dragStart.emit).not.toHaveBeenCalled(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 3, startingY + 3); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement).not.toBeDefined(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 3); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 3); expect(firstDrag.dragStart.emit).toHaveBeenCalled(); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 4, startingY + 4); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement).not.toBeDefined(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 4); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 4); expect(firstDrag.dragStart.emit).toHaveBeenCalled(); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstElement, startingX + 4, startingY + 4); fix.detectChanges(); await wait(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 4); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 4); expect(firstDrag.dragStart.emit).toHaveBeenCalled(); }); it('should position the base element relative to the mouse using offsetX and offsetY correctly.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstDrag.ghost = false; firstDrag.ghostOffsetX = 0; firstDrag.ghostOffsetY = 0; firstDrag.ghostTemplate = fix.componentInstance.ghostTemplate; // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); // We compare the base position and the new position + how much the mouse has moved. // + 10 margin to the final ghost position expect(firstElement.getBoundingClientRect().left).toEqual(startingX + 20); expect(firstElement.getBoundingClientRect().top).toEqual(startingY + 20); expect(firstElement.innerText).toEqual('Drag 1'); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); }); it('should correctly set location using setLocation() method when ghost is disabled', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; const initialPageX = firstDrag.pageX; const initialPageY = firstDrag.pageY; firstDrag.ghost = false; expect(initialPageX).toEqual(dragDirsRects[0].left); expect(initialPageY).toEqual(dragDirsRects[0].top); // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement).not.toBeDefined(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 10); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 10); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement).not.toBeDefined(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 20); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 20); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 20); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 20); firstDrag.setLocation(new IgxDragLocation(initialPageX, initialPageY)); expect(firstElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left); expect(firstElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top); }); it('should correctly set location using setLocation() method when ghost is rendered.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; const initialPageX = firstDrag.pageX; const initialPageY = firstDrag.pageY; expect(initialPageX).toEqual(dragDirsRects[0].left); expect(initialPageY).toEqual(dragDirsRects[0].top); // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement).toBeTruthy(); expect(firstDrag.ghostElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left + 10); expect(firstDrag.ghostElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top + 10); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); firstDrag.setLocation(new IgxDragLocation(initialPageX, initialPageY)); fix.detectChanges(); await wait(100); expect(firstDrag.ghostElement).toBeTruthy(); expect(firstDrag.ghostElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left); expect(firstDrag.ghostElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstDrag.ghostElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); expect(firstDrag.ghostElement).not.toBeTruthy(); }); it('should correctly drag using drag handle and not the whole element', async () => { const thirdDrag = fix.componentInstance.dragElems.last; const thirdElement = thirdDrag.element.nativeElement; const startingX = (dragDirsRects[2].left + dragDirsRects[2].right) / 2; const startingY = (dragDirsRects[2].top + dragDirsRects[2].bottom) / 2; thirdDrag.ghost = false; thirdDrag.dragTolerance = 0; spyOn(thirdDrag.dragStart, 'emit'); // Check if drag element itself is not draggable. UIInteractions.simulatePointerEvent('pointerdown', thirdElement, startingX, startingY); fix.detectChanges(); await wait(); UIInteractions.simulatePointerEvent('pointermove', thirdElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); UIInteractions.simulatePointerEvent('pointermove', thirdElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); UIInteractions.simulatePointerEvent('pointerup', thirdElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(); expect(thirdElement.getBoundingClientRect().left).toEqual(dragDirsRects[2].left); expect(thirdElement.getBoundingClientRect().top).toEqual(dragDirsRects[2].top); expect(thirdDrag.dragStart.emit).not.toHaveBeenCalled(); // Try dragging through drag handle. const dragHandle = thirdElement.children[0]; const dragHandleRects = dragHandle.getBoundingClientRect(); const handleStartX = (dragHandleRects.left + dragHandleRects.right) / 2; const handleStartY = (dragHandleRects.top + dragHandleRects.bottom) / 2; UIInteractions.simulatePointerEvent('pointerdown', dragHandle, handleStartX, handleStartY); fix.detectChanges(); await wait(); UIInteractions.simulatePointerEvent('pointermove', dragHandle, handleStartX + 10, handleStartY + 10); fix.detectChanges(); await wait(100); UIInteractions.simulatePointerEvent('pointermove', dragHandle, handleStartX + 20, handleStartY + 20); fix.detectChanges(); await wait(100); UIInteractions.simulatePointerEvent('pointerup', dragHandle, handleStartX + 20, handleStartY + 20); fix.detectChanges(); await wait(); expect(thirdElement.getBoundingClientRect().left).toEqual(dragDirsRects[2].left + 20); expect(thirdElement.getBoundingClientRect().top).toEqual(dragDirsRects[2].top + 20); expect(thirdDrag.dragStart.emit).toHaveBeenCalled(); }); it('should trigger enter, dropped and leave events when element is dropped inside igxDrop element.', async () => { fix.componentInstance.dropArea.dropStrategy = IgxInsertDropStrategy; fix.detectChanges(); const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; spyOn(dropArea.enter, 'emit'); spyOn(dropArea.leave, 'emit'); spyOn(dropArea.dropped, 'emit'); UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); expect(fix.componentInstance.container.nativeElement.children.length).toEqual(3); expect(dropArea.element.nativeElement.children.length).toEqual(0); UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(); const event = UIInteractions.simulatePointerEvent('pointermove', firstDrag.ghostElement, dropAreaRects.left + 100, dropAreaRects.top + 5 ); fix.detectChanges(); await wait(100); expect(dropArea.enter.emit).toHaveBeenCalledWith({ originalEvent: event, owner: dropArea, drag: firstDrag, dragData: firstDrag.data, startX: startingX, startY: startingY, pageX: dropAreaRects.left + 100, pageY: dropAreaRects.top + 5, offsetX: 100, offsetY: 5 }); // We need to trigger the pointerup on the ghostElement because this is the element we move and is under the mouse const eventUp = UIInteractions.simulatePointerEvent('pointerup', firstDrag.ghostElement, dropAreaRects.left + 100, dropAreaRects.top + 20 ); fix.detectChanges(); await wait(); expect(dropArea.dropped.emit).toHaveBeenCalledWith({ originalEvent: eventUp, owner: dropArea, drag: firstDrag, dragData: firstDrag.data, startX: startingX, startY: startingY, pageX: dropAreaRects.left + 100, pageY: dropAreaRects.top + 20, offsetX: 100, offsetY: 20, cancel: false }); expect(dropArea.leave.emit).toHaveBeenCalledWith({ originalEvent: eventUp, owner: dropArea, drag: firstDrag, dragData: firstDrag.data, startX: startingX, startY: startingY, pageX: dropAreaRects.left + 100, pageY: dropAreaRects.top + 20, offsetX: 100, offsetY: 20 }); expect(fix.componentInstance.container.nativeElement.children.length).toEqual(2); expect(dropArea.element.nativeElement.children.length).toEqual(1); }); it('should return the base element to its original position with transitionToOrigin() after dragging.', async () => { const firstDrag = fix.componentInstance.dragElems.first; const firstElement = firstDrag.element.nativeElement; const startingX = (dragDirsRects[0].left + dragDirsRects[0].right) / 2; const startingY = (dragDirsRects[0].top + dragDirsRects[0].bottom) / 2; firstDrag.ghost = false; firstDrag.dragEnd.pipe(first()).subscribe(() => { firstDrag.transitionToOrigin(); }); firstDrag.transitioned.pipe(first()).subscribe(() => { expect(firstDrag.originLocation.pageX).toEqual(dragDirsRects[0].left); expect(firstDrag.originLocation.pageY).toEqual(dragDirsRects[0].top); expect(firstDrag.element.nativeElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left); expect(firstDrag.element.nativeElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top); }); expect(firstDrag.originLocation.pageX).toEqual(dragDirsRects[0].left); expect(firstDrag.originLocation.pageY).toEqual(dragDirsRects[0].top); expect(firstDrag.element.nativeElement.getBoundingClientRect().left).toEqual(dragDirsRects[0].left); expect(firstDrag.element.nativeElement.getBoundingClientRect().top).toEqual(dragDirsRects[0].top); // Step 1. UIInteractions.simulatePointerEvent('pointerdown', firstElement, startingX, startingY); fix.detectChanges(); await wait(); // Step 2. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 10, startingY + 10); fix.detectChanges(); await wait(100); // Step 3. UIInteractions.simulatePointerEvent('pointermove', firstElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); let currLeft = firstDrag.element.nativeElement.getBoundingClientRect().left; let currTop = firstDrag.element.nativeElement.getBoundingClientRect().top; expect(firstDrag.location.pageX).toEqual(currLeft); expect(firstDrag.location.pageY).toEqual(currTop); expect(firstDrag.originLocation.pageX).toEqual(dragDirsRects[0].left); expect(firstDrag.originLocation.pageY).toEqual(dragDirsRects[0].top); expect(currLeft).toEqual(dragDirsRects[0].left + 20); expect(currTop).toEqual(dragDirsRects[0].top + 20); // Step 4. UIInteractions.simulatePointerEvent('pointerup', firstElement, startingX + 20, startingY + 20); fix.detectChanges(); await wait(100); currLeft = firstDrag.element.nativeElement.getBoundingClientRect().left; currTop = firstDrag.element.nativeElement.getBoundingClientRect().top; expec