diff --git a/e2e/components/dialog/dialog.e2e.ts b/e2e/components/dialog/dialog.e2e.ts new file mode 100644 index 00000000000..105f8e91abe --- /dev/null +++ b/e2e/components/dialog/dialog.e2e.ts @@ -0,0 +1,105 @@ +describe('dialog', () => { + beforeEach(() => browser.get('/dialog')); + + it('should open a dialog', () => { + element(by.id('default')).click(); + waitForDialog().then(isPresent => expect(isPresent).toBe(true)); + }); + + it('should close by clicking on the backdrop', () => { + element(by.id('default')).click(); + + waitForDialog().then(() => { + clickOnBackrop(); + waitForDialog().then(isPresent => expect(isPresent).toBe(false)); + }); + }); + + it('should close by pressing escape', () => { + element(by.id('default')).click(); + + waitForDialog().then(() => { + pressEscape(); + waitForDialog().then(isPresent => expect(isPresent).toBe(false)); + }); + }); + + it('should close by clicking on the "close" button', () => { + element(by.id('default')).click(); + + waitForDialog().then(() => { + element(by.id('close')).click(); + waitForDialog().then(isPresent => expect(isPresent).toBe(false)); + }); + }); + + it('should focus the first focusable element', () => { + element(by.id('default')).click(); + + waitForDialog().then(() => { + expectFocusOn(element(by.css('md-dialog-container input'))); + }); + }); + + it('should restore focus to the element that opened the dialog', () => { + let openButton = element(by.id('default')); + + openButton.click(); + + waitForDialog().then(() => { + clickOnBackrop(); + expectFocusOn(openButton); + }); + }); + + it('should prevent tabbing out of the dialog', () => { + element(by.id('default')).click(); + + waitForDialog().then(() => { + let tab = protractor.Key.TAB; + + browser.actions().sendKeys(tab, tab, tab).perform(); + expectFocusOn(element(by.id('close'))); + }); + }); + + it('should be able to prevent closing by clicking on the backdrop', () => { + element(by.id('disabled')).click(); + + waitForDialog().then(() => { + clickOnBackrop(); + waitForDialog().then(isPresent => expect(isPresent).toBe(true)); + }); + }); + + it('should be able to prevent closing by pressing escape', () => { + element(by.id('disabled')).click(); + + waitForDialog().then(() => { + pressEscape(); + waitForDialog().then(isPresent => expect(isPresent).toBe(true)); + }); + }); + + function waitForDialog() { + return browser.isElementPresent(by.css('md-dialog-container')); + } + + function clickOnBackrop() { + browser.actions() + // We need to move the cursor to the top left so + // the dialog doesn't receive the click accidentally. + .mouseMove(element(by.css('.md-overlay-backdrop')).getWebElement(), { x: 0, y: 0 }) + .click() + .perform(); + } + + function pressEscape() { + browser.actions().sendKeys(protractor.Key.ESCAPE).perform(); + } + + // TODO(crisbeto): should be moved to a common util. copied from the menu e2e setup. + function expectFocusOn(el: any): void { + expect(browser.driver.switchTo().activeElement().getInnerHtml()).toBe(el.getInnerHtml()); + } +}); diff --git a/src/e2e-app/dialog/dialog-e2e.html b/src/e2e-app/dialog/dialog-e2e.html new file mode 100644 index 00000000000..827bfee99ca --- /dev/null +++ b/src/e2e-app/dialog/dialog-e2e.html @@ -0,0 +1,2 @@ + + diff --git a/src/e2e-app/dialog/dialog-e2e.ts b/src/e2e-app/dialog/dialog-e2e.ts new file mode 100644 index 00000000000..068406bbc5c --- /dev/null +++ b/src/e2e-app/dialog/dialog-e2e.ts @@ -0,0 +1,42 @@ +import {Component} from '@angular/core'; +import {MdDialog, MdDialogRef, MdDialogConfig} from '@angular/material'; + +@Component({ + selector: 'dialog-e2e', + moduleId: module.id, + templateUrl: 'dialog-e2e.html' +}) +export class DialogE2E { + dialogRef: MdDialogRef; + + constructor (private _dialog: MdDialog) { } + + private _openDialog(config?: MdDialogConfig) { + this.dialogRef = this._dialog.open(TestDialog, config); + + this.dialogRef.afterClosed().subscribe(() => { + this.dialogRef = null; + }); + } + + openDefault() { + this._openDialog(); + } + + openDisabled() { + this._openDialog({ + disableClose: true + }); + } +} + +@Component({ + selector: 'dialog-e2e-test', + template: ` +

Lorem ipsum dolor sit amet, consectetur adipisicing elit.

+ + ` +}) +export class TestDialog { + constructor(public dialogRef: MdDialogRef) { } +} diff --git a/src/e2e-app/e2e-app-module.ts b/src/e2e-app/e2e-app-module.ts index 59b560d71bb..246872d1620 100644 --- a/src/e2e-app/e2e-app-module.ts +++ b/src/e2e-app/e2e-app-module.ts @@ -8,6 +8,7 @@ import {ButtonE2E} from './button/button-e2e'; import {MenuE2E} from './menu/menu-e2e'; import {SimpleRadioButtons} from './radio/radio-e2e'; import {BasicTabs} from './tabs/tabs-e2e'; +import {DialogE2E, TestDialog} from './dialog/dialog-e2e'; import {MaterialModule} from '@angular/material'; import {E2E_APP_ROUTES} from './e2e-app/routes'; @@ -27,10 +28,13 @@ import {E2E_APP_ROUTES} from './e2e-app/routes'; SimpleRadioButtons, SimpleCheckboxes, Home, + DialogE2E, + TestDialog, ], bootstrap: [E2EApp], providers: [ {provide: AnimationDriver, useValue: AnimationDriver.NOOP} - ] + ], + entryComponents: [TestDialog] }) export class E2eAppModule { } diff --git a/src/e2e-app/e2e-app/e2e-app.html b/src/e2e-app/e2e-app/e2e-app.html index 084d2d854f5..8ca1b82bf45 100644 --- a/src/e2e-app/e2e-app/e2e-app.html +++ b/src/e2e-app/e2e-app/e2e-app.html @@ -1,5 +1,6 @@ Button Checkbox +Dialog Icon Menu Radios diff --git a/src/e2e-app/e2e-app/routes.ts b/src/e2e-app/e2e-app/routes.ts index 8ed58c0bae2..cf42c461866 100644 --- a/src/e2e-app/e2e-app/routes.ts +++ b/src/e2e-app/e2e-app/routes.ts @@ -6,6 +6,7 @@ import {IconE2E} from '../icon/icon-e2e'; import {MenuE2E} from '../menu/menu-e2e'; import {SimpleRadioButtons} from '../radio/radio-e2e'; import {SimpleCheckboxes} from '../checkbox/checkbox-e2e'; +import {DialogE2E} from '../dialog/dialog-e2e'; export const E2E_APP_ROUTES: Routes = [ {path: '', component: Home}, @@ -14,6 +15,6 @@ export const E2E_APP_ROUTES: Routes = [ {path: 'menu', component: MenuE2E}, {path: 'icon', component: IconE2E}, {path: 'radio', component: SimpleRadioButtons}, - {path: 'tabs', component: BasicTabs} - + {path: 'tabs', component: BasicTabs}, + {path: 'dialog', component: DialogE2E}, ];