Skip to content

Commit

Permalink
feat(material-experimental/drawer): add harness for mat-drawer (#17010)
Browse files Browse the repository at this point in the history
* feat(material-experimental): add harness for mat-drawer

Follow-up from #16695. Adds a separate harness for `mat-drawer` and has `mat-sidenav` inherit from it.

* fix bad rebase
  • Loading branch information
crisbeto authored and mmalerba committed Sep 17, 2019
1 parent ef439b4 commit 2001965
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 78 deletions.
1 change: 1 addition & 0 deletions src/material-experimental/mdc-sidenav/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ sass_binary(
ng_test_library(
name = "sidenav_tests_lib",
srcs = [
"harness/drawer-harness.spec.ts",
"harness/sidenav-harness.spec.ts",
],
deps = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@

import {BaseHarnessFilters} from '@angular/cdk/testing';

export interface SidenavHarnessFilters extends BaseHarnessFilters {}
export interface DrawerHarnessFilters extends BaseHarnessFilters {}
108 changes: 108 additions & 0 deletions src/material-experimental/mdc-sidenav/harness/drawer-harness.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import {HarnessLoader} from '@angular/cdk/testing';
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
import {Component} from '@angular/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {MatSidenavModule} from '@angular/material/sidenav';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {MatSidenavModule as MatMdcSidenavModule} from '../index';
import {MatDrawerHarness} from './drawer-harness';
import {MatDrawerHarness as MatMdcDrawerHarness} from './mdc-drawer-harness';

let fixture: ComponentFixture<DrawerHarnessTest>;
let loader: HarnessLoader;
let harness: typeof MatDrawerHarness;

describe('MatDrawerHarness', () => {
describe('non-MDC-based', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [MatSidenavModule, NoopAnimationsModule],
declarations: [DrawerHarnessTest],
}).compileComponents();

fixture = TestBed.createComponent(DrawerHarnessTest);
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
harness = MatDrawerHarness;
});

runTests();
});

describe('MDC-based', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [MatMdcSidenavModule, NoopAnimationsModule],
declarations: [DrawerHarnessTest],
}).compileComponents();

fixture = TestBed.createComponent(DrawerHarnessTest);
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
// Public APIs are the same as MatDrawerHarness, but cast
// is necessary because of different private fields.
harness = MatMdcDrawerHarness as any;
});

// TODO: enable after MDC drawer is implemented
// runTests();
});
});

/** Shared tests to run on both the original and MDC-based drawer. */
function runTests() {
it('should load all drawer harnesses', async () => {
const drawers = await loader.getAllHarnesses(harness);
expect(drawers.length).toBe(3);
});

it('should be able to get whether the drawer is open', async () => {
const drawers = await loader.getAllHarnesses(harness);

expect(await drawers[0].isOpen()).toBe(false);
expect(await drawers[1].isOpen()).toBe(false);
expect(await drawers[2].isOpen()).toBe(true);

fixture.componentInstance.threeOpened = false;
fixture.detectChanges();

expect(await drawers[0].isOpen()).toBe(false);
expect(await drawers[1].isOpen()).toBe(false);
expect(await drawers[2].isOpen()).toBe(false);
});

it('should be able to get the position of a drawer', async () => {
const drawers = await loader.getAllHarnesses(harness);

expect(await drawers[0].getPosition()).toBe('start');
expect(await drawers[1].getPosition()).toBe('end');
expect(await drawers[2].getPosition()).toBe('start');
});

it('should be able to get the mode of a drawer', async () => {
const drawers = await loader.getAllHarnesses(harness);

expect(await drawers[0].getMode()).toBe('over');
expect(await drawers[1].getMode()).toBe('side');
expect(await drawers[2].getMode()).toBe('push');
});
}

@Component({
template: `
<mat-drawer-container>
<mat-drawer id="one" [opened]="oneOpened" position="start">One</mat-drawer>
<mat-drawer id="two" mode="side" position="end">Two</mat-drawer>
<mat-drawer-content>Content</mat-drawer-content>
</mat-drawer-container>
<mat-drawer-container>
<mat-drawer id="three" mode="push" [opened]="threeOpened">Three</mat-drawer>
<mat-drawer-content>Content</mat-drawer-content>
</mat-drawer-container>
`
})
class DrawerHarnessTest {
threeOpened = true;
}

54 changes: 54 additions & 0 deletions src/material-experimental/mdc-sidenav/harness/drawer-harness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {ComponentHarness, HarnessPredicate} from '@angular/cdk/testing';
import {DrawerHarnessFilters} from './drawer-harness-filters';

/**
* Harness for interacting with a standard mat-drawer in tests.
* @dynamic
*/
export class MatDrawerHarness extends ComponentHarness {
static hostSelector = '.mat-drawer';

/**
* Gets a `HarnessPredicate` that can be used to search for a drawer with
* specific attributes.
* @param options Options for narrowing the search.
* @return `HarnessPredicate` configured with the given options.
*/
static with(options: DrawerHarnessFilters = {}): HarnessPredicate<MatDrawerHarness> {
return new HarnessPredicate(MatDrawerHarness, options);
}

/** Gets whether the drawer is open. */
async isOpen(): Promise<boolean> {
return (await this.host()).hasClass('mat-drawer-opened');
}

/** Gets the position of the drawer inside its container. */
async getPosition(): Promise<'start'|'end'> {
const host = await this.host();
return (await host.hasClass('mat-drawer-end')) ? 'end' : 'start';
}

/** Gets the mode that the drawer is in. */
async getMode(): Promise<'over'|'push'|'side'> {
const host = await this.host();

if (await host.hasClass('mat-drawer-push')) {
return 'push';
}

if (await host.hasClass('mat-drawer-side')) {
return 'side';
}

return 'over';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {ComponentHarness} from '@angular/cdk/testing';


/**
* Harness for interacting with a MDC-based drawer in tests.
* @dynamic
*/
export class MatDrawerHarness extends ComponentHarness {
// TODO: implement once MDC drawer is done.
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
* found in the LICENSE file at https://angular.io/license
*/

import {ComponentHarness} from '@angular/cdk/testing';
import {MatDrawerHarness} from './mdc-drawer-harness';


/**
* Harness for interacting with a MDC-based mat-sidenav in tests.
* @dynamic
*/
export class MatSidenavHarness extends ComponentHarness {
export class MatSidenavHarness extends MatDrawerHarness {
// TODO: implement once MDC sidenav is done.
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {MatSidenavModule} from '@angular/material/sidenav';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {MatSidenavModule as MatMdcSidenavModule} from '../index';
import {MatSidenavHarness} from './sidenav-harness';
import {MatSidenavHarness as MatMdcSidenavHarness} from './mdc-sidenav-harness';
import {MatDrawerHarness as MatMdcSidenavHarness} from './mdc-drawer-harness';

let fixture: ComponentFixture<SidenavHarnessTest>;
let loader: HarnessLoader;
Expand Down Expand Up @@ -49,44 +49,11 @@ describe('MatSidenavHarness', () => {
});
});

/** Shared tests to run on both the original and MDC-based sidenav. */
/**
* Shared tests to run on both the original and MDC-based sidenav. Only tests logic that
* is specific to `mat-sidenav`, everything else is with the `mat-drawer` tests.
*/
function runTests() {
it('should load all sidenav harnesses', async () => {
const sidenavs = await loader.getAllHarnesses(harness);
expect(sidenavs.length).toBe(3);
});

it('should be able to get whether the sidenav is open', async () => {
const sidenavs = await loader.getAllHarnesses(harness);

expect(await sidenavs[0].isOpen()).toBe(false);
expect(await sidenavs[1].isOpen()).toBe(false);
expect(await sidenavs[2].isOpen()).toBe(true);

fixture.componentInstance.threeOpened = false;
fixture.detectChanges();

expect(await sidenavs[0].isOpen()).toBe(false);
expect(await sidenavs[1].isOpen()).toBe(false);
expect(await sidenavs[2].isOpen()).toBe(false);
});

it('should be able to get the position of a sidenav', async () => {
const sidenavs = await loader.getAllHarnesses(harness);

expect(await sidenavs[0].getPosition()).toBe('start');
expect(await sidenavs[1].getPosition()).toBe('end');
expect(await sidenavs[2].getPosition()).toBe('start');
});

it('should be able to get the mode of a sidenav', async () => {
const sidenavs = await loader.getAllHarnesses(harness);

expect(await sidenavs[0].getMode()).toBe('over');
expect(await sidenavs[1].getMode()).toBe('side');
expect(await sidenavs[2].getMode()).toBe('push');
});

it('should be able to get whether a sidenav is fixed in the viewport', async () => {
const sidenavs = await loader.getAllHarnesses(harness);

Expand All @@ -99,18 +66,16 @@ function runTests() {
@Component({
template: `
<mat-sidenav-container>
<mat-sidenav id="one" [opened]="oneOpened" position="start">One</mat-sidenav>
<mat-sidenav id="two" mode="side" position="end">Two</mat-sidenav>
<mat-sidenav id="one" position="start">One</mat-sidenav>
<mat-sidenav id="two" position="end">Two</mat-sidenav>
<mat-sidenav-content>Content</mat-sidenav-content>
</mat-sidenav-container>
<mat-sidenav-container>
<mat-sidenav id="three" mode="push" [opened]="threeOpened" fixedInViewport>Three</mat-sidenav>
<mat-sidenav id="three" fixedInViewport>Three</mat-sidenav>
<mat-sidenav-content>Content</mat-sidenav-content>
</mat-sidenav-container>
`
})
class SidenavHarnessTest {
threeOpened = true;
}
class SidenavHarnessTest {}

37 changes: 6 additions & 31 deletions src/material-experimental/mdc-sidenav/harness/sidenav-harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
* found in the LICENSE file at https://angular.io/license
*/

import {ComponentHarness, HarnessPredicate} from '@angular/cdk/testing';
import {SidenavHarnessFilters} from './sidenav-harness-filters';
import {HarnessPredicate} from '@angular/cdk/testing';
import {MatDrawerHarness} from './drawer-harness';
import {DrawerHarnessFilters} from './drawer-harness-filters';

/**
* Harness for interacting with a standard mat-sidenav in tests.
* @dynamic
*/
export class MatSidenavHarness extends ComponentHarness {
export class MatSidenavHarness extends MatDrawerHarness {
static hostSelector = '.mat-sidenav';

/**
Expand All @@ -22,34 +23,8 @@ export class MatSidenavHarness extends ComponentHarness {
* @param options Options for narrowing the search.
* @return `HarnessPredicate` configured with the given options.
*/
static with(options: SidenavHarnessFilters = {}): HarnessPredicate<MatSidenavHarness> {
return new HarnessPredicate(MatSidenavHarness, options);
}

/** Gets whether the sidenav is open. */
async isOpen(): Promise<boolean> {
return (await this.host()).hasClass('mat-drawer-opened');
}

/** Gets the position of the sidenav inside its container. */
async getPosition(): Promise<'start'|'end'> {
const host = await this.host();
return (await host.hasClass('mat-drawer-end')) ? 'end' : 'start';
}

/** Gets the mode that the sidenav is in. */
async getMode(): Promise<'over'|'push'|'side'> {
const host = await this.host();

if (await host.hasClass('mat-drawer-push')) {
return 'push';
}

if (await host.hasClass('mat-drawer-side')) {
return 'side';
}

return 'over';
static with(options: DrawerHarnessFilters = {}): HarnessPredicate<MatDrawerHarness> {
return new HarnessPredicate(MatDrawerHarness, options);
}

/** Gets whether the sidenav is fixed in the viewport. */
Expand Down

0 comments on commit 2001965

Please sign in to comment.