refactor(overlay): convert fullscreen overlay container e2e tests into unit tests (#13657)

This commit is contained in:
Kristiyan Kostadinov
2018-10-18 19:17:33 +03:00
committed by Joey Perrott
parent e48a6a95ae
commit 0c00e70542
8 changed files with 128 additions and 121 deletions
-2
View File
@@ -156,7 +156,6 @@
/e2e/components/checkbox-e2e.spec.ts @jelbourn @devversion
/e2e/components/dialog-e2e.spec.ts @jelbourn @crisbeto
/e2e/components/expansion-e2e.spec.ts @josephperrott @jelbourn
/e2e/components/fullscreen-e2e.spec.ts @jelbourn
/e2e/components/grid-list-e2e.spec.ts @jelbourn
/e2e/components/icon-e2e.spec.ts @jelbourn
/e2e/components/input-e2e.spec.ts @mmalerba
@@ -178,7 +177,6 @@
/src/e2e-app/checkbox/** @jelbourn @devversion
/src/e2e-app/dialog/** @jelbourn @crisbeto
/src/e2e-app/e2e-app/** @jelbourn
/src/e2e-app/fullscreen/** @jelbourn
/src/e2e-app/grid-list/** @jelbourn
/src/e2e-app/icon/** @jelbourn
/src/e2e-app/input/** @mmalerba
-40
View File
@@ -1,40 +0,0 @@
import {browser, by, element} from 'protractor';
describe('fullscreen', () => {
beforeEach(() => browser.get('/fullscreen'));
it('should open a dialog inside a fullscreen element and move it to the body', async () => {
element(by.id('fullscreen-open')).click();
element(by.id('dialog-open')).click();
await expectOverlayInFullscreen();
element(by.id('dialog-fullscreen-exit')).click();
await expectOverlayInBody();
});
it('should open a dialog inside the body and move it to a fullscreen element', async () => {
element(by.id('dialog-open')).click();
await expectOverlayInBody();
element(by.id('dialog-fullscreen-open')).click();
await expectOverlayInFullscreen();
element(by.id('dialog-fullscreen-exit')).click();
await expectOverlayInBody();
});
/** Expects the overlay container to be inside of the body element. */
async function expectOverlayInBody() {
expect(await browser.isElementPresent(by.css('body > .cdk-overlay-container')))
.toBe(true, 'Expected the overlay container to be inside of the body.');
}
/** Expects the overlay container to be in fullscreen mode. */
async function expectOverlayInFullscreen() {
expect(await browser.isElementPresent(by.css('#fullscreen-pane > .cdk-overlay-container')))
.toBe(true, 'Expected the overlay container to be in fullscreen mode.');
}
});
@@ -0,0 +1,127 @@
import {async, inject, TestBed} from '@angular/core/testing';
import {Component, NgModule, ViewChild, ViewContainerRef} from '@angular/core';
import {PortalModule, CdkPortal} from '@angular/cdk/portal';
import {DOCUMENT} from '@angular/platform-browser';
import {Overlay, OverlayContainer, OverlayModule, FullscreenOverlayContainer} from './index';
describe('FullscreenOverlayContainer', () => {
let overlay: Overlay;
let overlayContainer: FullscreenOverlayContainer;
let fullscreenListeners: Set<Function>;
let fakeDocument: any;
beforeEach(async(() => {
fullscreenListeners = new Set();
TestBed.configureTestingModule({
imports: [OverlayTestModule],
providers: [{
provide: DOCUMENT,
useFactory: () => {
// Provide a (very limited) stub for the document. This is the most practical solution for
// now since we only hit a handful of Document APIs. If we end up having to add more
// stubs here, we should reconsider whether to use a Proxy instead. Avoiding a proxy for
// now since it isn't supported on IE. See:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
fakeDocument = {
body: document.body,
fullscreenElement: document.createElement('div'),
fullscreenEnabled: true,
addEventListener: function(eventName: string, listener: Function) {
if (eventName === 'fullscreenchange') {
fullscreenListeners.add(listener);
} else {
document.addEventListener.apply(document, arguments);
}
},
removeEventListener: function(eventName: string, listener: Function) {
if (eventName === 'fullscreenchange') {
fullscreenListeners.delete(listener);
} else {
document.addEventListener.apply(document, arguments);
}
},
querySelectorAll: function() {
return document.querySelectorAll.apply(document, arguments);
},
createElement: function() {
return document.createElement.apply(document, arguments);
},
};
return fakeDocument;
}
}]
}).compileComponents();
}));
beforeEach(inject([Overlay, OverlayContainer], (o: Overlay, oc: OverlayContainer) => {
overlay = o;
overlayContainer = oc as FullscreenOverlayContainer;
}));
afterEach(() => {
overlayContainer.ngOnDestroy();
fakeDocument = null;
});
it('should open an overlay inside a fullscreen element and move it to the body', () => {
const fixture = TestBed.createComponent(TestComponentWithTemplatePortals);
const overlayRef = overlay.create();
const fullscreenElement = fakeDocument.fullscreenElement;
overlayRef.attach(fixture.componentInstance.templatePortal);
fixture.detectChanges();
expect(fullscreenElement.contains(overlayRef.overlayElement)).toBe(true);
fakeDocument.fullscreenElement = null;
fullscreenListeners.forEach(listener => listener());
fixture.detectChanges();
expect(fullscreenElement.contains(overlayRef.overlayElement)).toBe(false);
expect(document.body.contains(overlayRef.overlayElement)).toBe(true);
});
it('should open an overlay inside the body and move it to a fullscreen element', () => {
const fullscreenElement = fakeDocument.fullscreenElement;
fakeDocument.fullscreenElement = null;
const fixture = TestBed.createComponent(TestComponentWithTemplatePortals);
const overlayRef = overlay.create();
overlayRef.attach(fixture.componentInstance.templatePortal);
fixture.detectChanges();
expect(fullscreenElement.contains(overlayRef.overlayElement)).toBe(false);
expect(document.body.contains(overlayRef.overlayElement)).toBe(true);
fakeDocument.fullscreenElement = fullscreenElement;
fullscreenListeners.forEach(listener => listener());
fixture.detectChanges();
expect(fullscreenElement.contains(overlayRef.overlayElement)).toBe(true);
});
});
/** Test-bed component that contains a TempatePortal and an ElementRef. */
@Component({
template: `<ng-template cdk-portal>Cake</ng-template>`,
providers: [Overlay],
})
class TestComponentWithTemplatePortals {
@ViewChild(CdkPortal) templatePortal: CdkPortal;
constructor(public viewContainerRef: ViewContainerRef) { }
}
@NgModule({
imports: [OverlayModule, PortalModule],
declarations: [TestComponentWithTemplatePortals],
providers: [{
provide: OverlayContainer,
useClass: FullscreenOverlayContainer
}]
})
class OverlayTestModule { }
+1 -8
View File
@@ -1,7 +1,6 @@
import {DialogModule} from '@angular/cdk-experimental/dialog';
import {DragDropModule} from '@angular/cdk/drag-drop';
import {ScrollingModule as ExperimentalScrollingModule} from '@angular/cdk-experimental/scrolling';
import {FullscreenOverlayContainer, OverlayContainer} from '@angular/cdk/overlay';
import {ScrollingModule} from '@angular/cdk/scrolling';
import {NgModule} from '@angular/core';
import {ReactiveFormsModule} from '@angular/forms';
@@ -35,7 +34,6 @@ import {SimpleCheckboxes} from './checkbox/checkbox-e2e';
import {DialogE2E, TestDialog} from './dialog/dialog-e2e';
import {E2EApp, Home} from './e2e-app/e2e-app';
import {E2E_APP_ROUTES} from './e2e-app/routes';
import {FullscreenE2E, TestDialogFullScreen} from './fullscreen/fullscreen-e2e';
import {GridListE2E} from './grid-list/grid-list-e2e';
import {IconE2E} from './icon/icon-e2e';
import {InputE2E} from './input/input-e2e';
@@ -93,7 +91,6 @@ export class E2eMaterialModule {}
ButtonE2E,
DialogE2E,
E2EApp,
FullscreenE2E,
GridListE2E,
Home,
IconE2E,
@@ -106,14 +103,10 @@ export class E2eMaterialModule {}
SimpleRadioButtons,
SlideToggleE2E,
TestDialog,
TestDialogFullScreen,
BlockScrollStrategyE2E,
VirtualScrollE2E,
],
bootstrap: [E2EApp],
providers: [
{provide: OverlayContainer, useClass: FullscreenOverlayContainer}
],
entryComponents: [TestDialog, TestDialogFullScreen]
entryComponents: [TestDialog]
})
export class E2eAppModule { }
-1
View File
@@ -7,7 +7,6 @@
<a mat-list-item [routerLink]="['checkbox']">Checkbox</a>
<a mat-list-item [routerLink]="['dialog']">Dialog</a>
<a mat-list-item [routerLink]="['expansion']">Expansion</a>
<a mat-list-item [routerLink]="['fullscreen']">Fullscreen</a>
<a mat-list-item [routerLink]="['grid-list']">Grid list</a>
<a mat-list-item [routerLink]="['icon']">Icon</a>
<a mat-list-item [routerLink]="['input']">Input</a>
-2
View File
@@ -12,7 +12,6 @@ import {GridListE2E} from '../grid-list/grid-list-e2e';
import {ProgressBarE2E} from '../progress-bar/progress-bar-e2e';
import {ProgressSpinnerE2E} from '../progress-spinner/progress-spinner-e2e';
import {SlideToggleE2E} from '../slide-toggle/slide-toggle-e2e';
import {FullscreenE2E} from '../fullscreen/fullscreen-e2e';
import {InputE2E} from '../input/input-e2e';
import {SidenavE2E} from '../sidenav/sidenav-e2e';
import {BlockScrollStrategyE2E} from '../block-scroll-strategy/block-scroll-strategy-e2e';
@@ -33,7 +32,6 @@ export const E2E_APP_ROUTES: Routes = [
{path: 'checkbox', component: SimpleCheckboxes},
{path: 'dialog', component: DialogE2E},
{path: 'expansion', component: ExpansionOverviewExample},
{path: 'fullscreen', component: FullscreenE2E},
{path: 'grid-list', component: GridListE2E},
{path: 'icon', component: IconE2E},
{path: 'input', component: InputE2E},
@@ -1,6 +0,0 @@
<button id="fullscreen-open" (click)="openFullscreen()">Open Fullscreen</button>
<div id="fullscreen-pane">
<button id="dialog-open" (click)="openDialog()">Open Dialog</button>
<button id="fullscreen-exit" (click)="exitFullscreen()">Exit Fullscreen</button>
</div>
-62
View File
@@ -1,62 +0,0 @@
import {Component, ElementRef, Output, EventEmitter} from '@angular/core';
import {MatDialog, MatDialogRef} from '@angular/material';
@Component({
moduleId: module.id,
selector: 'fullscreen-e2e',
templateUrl: 'fullscreen-e2e.html'
})
export class FullscreenE2E {
dialogRef: MatDialogRef<TestDialogFullScreen> | null;
constructor (private _element: ElementRef<HTMLElement>, private _dialog: MatDialog) { }
openDialog() {
this.dialogRef = this._dialog.open(TestDialogFullScreen);
this.dialogRef.componentInstance.openFullscreen.subscribe(() => this.openFullscreen());
this.dialogRef.componentInstance.exitFullscreen.subscribe(() => this.exitFullscreen());
this.dialogRef.afterClosed().subscribe(() => this.dialogRef = null);
}
openFullscreen() {
let element = this._element.nativeElement.querySelector('#fullscreen-pane') as any;
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.webkitRequestFullScreen) {
element.webkitRequestFullScreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.msRequestFullScreen) {
element.msRequestFullScreen();
}
}
exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if ((document as any).webkitExitFullscreen) {
(document as any).webkitExitFullscreen();
} else if ((document as any).mozExitFullScreen) {
(document as any).mozExitFullScreen();
} else if ((document as any).msExitFullScreen) {
(document as any).msExitFullScreen();
}
}
}
@Component({
template: `
<button id="dialog-fullscreen-open" (click)="openFullscreen.emit()">Open Fullscreen</button>
<button id="dialog-fullscreen-exit" (click)="exitFullscreen.emit()">Exit Fullscreen</button>
<button (click)="dialogRef.close()" id="close">Close Dialog</button>
`
})
export class TestDialogFullScreen {
@Output() openFullscreen = new EventEmitter<void>();
@Output() exitFullscreen = new EventEmitter<void>();
constructor(public dialogRef: MatDialogRef<TestDialogFullScreen>) {}
}