diff --git a/e2e-app/src/app/modal/autoclose/modal-autoclose.e2e-spec.ts b/e2e-app/src/app/modal/autoclose/modal-autoclose.e2e-spec.ts index d9ff4fc004..634d35480d 100644 --- a/e2e-app/src/app/modal/autoclose/modal-autoclose.e2e-spec.ts +++ b/e2e-app/src/app/modal/autoclose/modal-autoclose.e2e-spec.ts @@ -1,6 +1,6 @@ import {ModalAutoClosePage} from './modal-autoclose.po'; import {expectNoOpenModals, openUrl, sendKey} from '../../tools.po'; -import {Key} from 'protractor'; +import {browser, Key} from 'protractor'; describe('Modal', () => { let page: ModalAutoClosePage; @@ -44,15 +44,44 @@ describe('Modal', () => { it('should close modal on backdrop click', async() => { const modal = await page.openModal(); + // dialog click + await page.getModalDialog().click(); + expect(await modal.isPresent()).toBeTruthy('The modal should stay opened on dialog click'); + // close await modal.click(); expect(await modal.isPresent()).toBeFalsy('The modal should be closed on backdrop click'); expect(await page.getDismissReason()).toBe('Click', `Modal should have been dismissed with 'Click' reason`); }); + it('should close modal when dragging from backdrop -> dialog', async() => { + const modal = await page.openModal(); + + // close + const dialog = await page.getModalDialog(); + await browser.actions().dragAndDrop(modal, dialog).mouseUp().perform(); + expect(await modal.isPresent()).toBeFalsy('The modal should be closed on drag from backdrop -> dialog'); + expect(await page.getDismissReason()).toBe('Click', `Modal should have been dismissed with 'Click' reason`); + }); + + it('should NOT close modal when dragging from dialog -> backdrop', async() => { + const modal = await page.openModal(); + + // close + const dialog = await page.getModalDialog(); + await browser.actions().dragAndDrop(dialog, modal).mouseUp().perform(); + expect(await modal.isPresent()).toBeTruthy('The modal should stay opened on drag from dialog -> backdrop'); + await page.getModalCloseButton().click(); + }); + + it(`should NOT close modal on 'static' backdrop click`, async() => { const modal = await page.openModal('backdrop-static'); + // dialog click + await page.getModalDialog().click(); + expect(await modal.isPresent()).toBeTruthy('The modal should stay opened on dialog click'); + // close await modal.click(); expect(await modal.isPresent()).toBeTruthy('The modal should stay opened on backdrop click'); @@ -62,6 +91,10 @@ describe('Modal', () => { it(`should NOT close modal on click with no backdrop`, async() => { const modal = await page.openModal('backdrop-false'); + // dialog click + await page.getModalDialog().click(); + expect(await modal.isPresent()).toBeTruthy('The modal should stay opened on dialog click'); + // close await modal.click(); expect(await modal.isPresent()).toBeTruthy('The modal should stay opened on backdrop click'); diff --git a/e2e-app/src/app/modal/autoclose/modal-autoclose.po.ts b/e2e-app/src/app/modal/autoclose/modal-autoclose.po.ts index 89029044ca..942c61b5fa 100644 --- a/e2e-app/src/app/modal/autoclose/modal-autoclose.po.ts +++ b/e2e-app/src/app/modal/autoclose/modal-autoclose.po.ts @@ -3,6 +3,8 @@ import {$} from 'protractor'; export class ModalAutoClosePage { getModal(selector = 'ngb-modal-window') { return $(selector); } + getModalDialog() { return $('.modal-dialog'); } + getModalCloseButton() { return $('#modal-close-button'); } getDismissReason() { return $('#dismiss-reason').getText(); } diff --git a/src/modal/modal-window.ts b/src/modal/modal-window.ts index 3554383d0a..1dd2c20aff 100644 --- a/src/modal/modal-window.ts +++ b/src/modal/modal-window.ts @@ -10,10 +10,11 @@ import { OnDestroy, OnInit, Output, + ViewChild, ViewEncapsulation } from '@angular/core'; import {fromEvent} from 'rxjs'; -import {filter, map, takeUntil, withLatestFrom} from 'rxjs/operators'; +import {filter, take, takeUntil, tap} from 'rxjs/operators'; import {getFocusableBoundaryElements} from '../util/focus-trap'; import {Key} from '../util/key'; @@ -29,7 +30,7 @@ import {ModalDismissReasons} from './modal-dismiss-reasons'; '[attr.aria-labelledby]': 'ariaLabelledBy', }, template: ` -