From 3d172f42ef24ae8010ca9195f8fd1df7e63226d1 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Wed, 6 Nov 2019 07:35:20 +0900 Subject: [PATCH] feat(bottom-sheet): add test harness Sets up a test harness for the bottom sheet. --- src/material/bottom-sheet/testing/BUILD.bazel | 52 ++++++++++++ .../testing/bottom-sheet-harness-filters.ts | 11 +++ .../testing/bottom-sheet-harness.spec.ts | 7 ++ .../testing/bottom-sheet-harness.ts | 43 ++++++++++ src/material/bottom-sheet/testing/index.ts | 9 ++ .../bottom-sheet/testing/public-api.ts | 10 +++ .../bottom-sheet/testing/shared.spec.ts | 85 +++++++++++++++++++ src/material/config.bzl | 1 + test/karma-system-config.js | 2 + 9 files changed, 220 insertions(+) create mode 100644 src/material/bottom-sheet/testing/BUILD.bazel create mode 100644 src/material/bottom-sheet/testing/bottom-sheet-harness-filters.ts create mode 100644 src/material/bottom-sheet/testing/bottom-sheet-harness.spec.ts create mode 100644 src/material/bottom-sheet/testing/bottom-sheet-harness.ts create mode 100644 src/material/bottom-sheet/testing/index.ts create mode 100644 src/material/bottom-sheet/testing/public-api.ts create mode 100644 src/material/bottom-sheet/testing/shared.spec.ts diff --git a/src/material/bottom-sheet/testing/BUILD.bazel b/src/material/bottom-sheet/testing/BUILD.bazel new file mode 100644 index 000000000000..8f95f79dfc99 --- /dev/null +++ b/src/material/bottom-sheet/testing/BUILD.bazel @@ -0,0 +1,52 @@ +package(default_visibility = ["//visibility:public"]) + +load("//tools:defaults.bzl", "ng_test_library", "ng_web_test_suite", "ts_library") + +ts_library( + name = "testing", + srcs = glob( + ["**/*.ts"], + exclude = ["**/*.spec.ts"], + ), + module_name = "@angular/material/bottom-sheet/testing", + deps = [ + "//src/cdk/testing", + "//src/material/bottom-sheet", + ], +) + +filegroup( + name = "source-files", + srcs = glob(["**/*.ts"]), +) + +ng_test_library( + name = "harness_tests_lib", + srcs = ["shared.spec.ts"], + deps = [ + ":testing", + "//src/cdk/overlay", + "//src/cdk/testing", + "//src/cdk/testing/testbed", + "//src/material/bottom-sheet", + "@npm//@angular/platform-browser", + ], +) + +ng_test_library( + name = "unit_tests_lib", + srcs = glob( + ["**/*.spec.ts"], + exclude = ["shared.spec.ts"], + ), + deps = [ + ":harness_tests_lib", + ":testing", + "//src/material/bottom-sheet", + ], +) + +ng_web_test_suite( + name = "unit_tests", + deps = [":unit_tests_lib"], +) diff --git a/src/material/bottom-sheet/testing/bottom-sheet-harness-filters.ts b/src/material/bottom-sheet/testing/bottom-sheet-harness-filters.ts new file mode 100644 index 000000000000..671d2087a5d5 --- /dev/null +++ b/src/material/bottom-sheet/testing/bottom-sheet-harness-filters.ts @@ -0,0 +1,11 @@ +/** + * @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 {BaseHarnessFilters} from '@angular/cdk/testing'; + +export interface BottomSheetHarnessFilters extends BaseHarnessFilters {} diff --git a/src/material/bottom-sheet/testing/bottom-sheet-harness.spec.ts b/src/material/bottom-sheet/testing/bottom-sheet-harness.spec.ts new file mode 100644 index 000000000000..299fd1f7e4c7 --- /dev/null +++ b/src/material/bottom-sheet/testing/bottom-sheet-harness.spec.ts @@ -0,0 +1,7 @@ +import {MatBottomSheetModule} from '@angular/material/bottom-sheet'; +import {runHarnessTests} from '@angular/material/bottom-sheet/testing/shared.spec'; +import {MatBottomSheetHarness} from './bottom-sheet-harness'; + +describe('Non-MDC-based MatBottomSheetHarness', () => { + runHarnessTests(MatBottomSheetModule, MatBottomSheetHarness); +}); diff --git a/src/material/bottom-sheet/testing/bottom-sheet-harness.ts b/src/material/bottom-sheet/testing/bottom-sheet-harness.ts new file mode 100644 index 000000000000..d73cf62aaa25 --- /dev/null +++ b/src/material/bottom-sheet/testing/bottom-sheet-harness.ts @@ -0,0 +1,43 @@ +/** + * @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, TestKey} from '@angular/cdk/testing'; +import {BottomSheetHarnessFilters} from './bottom-sheet-harness-filters'; + +/** + * Harness for interacting with a standard MatBottomSheet in tests. + * @dynamic + */ +export class MatBottomSheetHarness extends ComponentHarness { + // Developers can provide a custom component or template for the + // bottom sheet. The canonical parent is the ".mat-bottom-sheet-container". + static hostSelector = '.mat-bottom-sheet-container'; + + /** + * Gets a `HarnessPredicate` that can be used to search for a bottom sheet with + * specific attributes. + * @param options Options for narrowing the search. + * @return a `HarnessPredicate` configured with the given options. + */ + static with(options: BottomSheetHarnessFilters = {}): HarnessPredicate { + return new HarnessPredicate(MatBottomSheetHarness, options); + } + + /** Gets the value of the bottom sheet's "aria-label" attribute. */ + async getAriaLabel(): Promise { + return (await this.host()).getAttribute('aria-label'); + } + + /** + * Dismisses the bottom sheet by pressing escape. Note that this method cannot + * be used if "disableClose" has been set to true via the config. + */ + async dismiss(): Promise { + await (await this.host()).sendKeys(TestKey.ESCAPE); + } +} diff --git a/src/material/bottom-sheet/testing/index.ts b/src/material/bottom-sheet/testing/index.ts new file mode 100644 index 000000000000..676ca90f1ffa --- /dev/null +++ b/src/material/bottom-sheet/testing/index.ts @@ -0,0 +1,9 @@ +/** + * @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 + */ + +export * from './public-api'; diff --git a/src/material/bottom-sheet/testing/public-api.ts b/src/material/bottom-sheet/testing/public-api.ts new file mode 100644 index 000000000000..da2082d8c0ff --- /dev/null +++ b/src/material/bottom-sheet/testing/public-api.ts @@ -0,0 +1,10 @@ +/** + * @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 + */ + +export * from './bottom-sheet-harness'; +export * from './bottom-sheet-harness-filters'; diff --git a/src/material/bottom-sheet/testing/shared.spec.ts b/src/material/bottom-sheet/testing/shared.spec.ts new file mode 100644 index 000000000000..f3dd78b92673 --- /dev/null +++ b/src/material/bottom-sheet/testing/shared.spec.ts @@ -0,0 +1,85 @@ +import {HarnessLoader} from '@angular/cdk/testing'; +import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed'; +import {Component, TemplateRef, ViewChild} from '@angular/core'; +import {ComponentFixture, TestBed, inject} from '@angular/core/testing'; +import { + MatBottomSheet, + MatBottomSheetConfig, + MatBottomSheetModule, +} from '@angular/material/bottom-sheet'; +import {NoopAnimationsModule} from '@angular/platform-browser/animations'; +import {OverlayContainer} from '@angular/cdk/overlay'; +import {MatBottomSheetHarness} from './bottom-sheet-harness'; + +/** Shared tests to run on both the original and MDC-based bottom sheets. */ +export function runHarnessTests( + bottomSheetModule: typeof MatBottomSheetModule, harness: typeof MatBottomSheetHarness) { + let fixture: ComponentFixture; + let loader: HarnessLoader; + let overlayContainer: OverlayContainer; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [bottomSheetModule, NoopAnimationsModule], + declarations: [BottomSheetHarnessTest], + }).compileComponents(); + + fixture = TestBed.createComponent(BottomSheetHarnessTest); + fixture.detectChanges(); + loader = TestbedHarnessEnvironment.documentRootLoader(fixture); + inject([OverlayContainer], (oc: OverlayContainer) => { + overlayContainer = oc; + })(); + }); + + afterEach(() => { + // Dismiss the bottom sheet once the tests are done. This is necessary because the + // "MatBottomSheet" service is not destroyed automatically by TestBed, and it could + // mean that bottom sheets are left in the DOM. + fixture.componentInstance.bottomSheet.dismiss(); + fixture.detectChanges(); + + // Angular won't call this for us so we need to do it ourselves to avoid leaks. + overlayContainer.ngOnDestroy(); + }); + + it('should load harness for a bottom sheet', async () => { + fixture.componentInstance.open(); + const bottomSheets = await loader.getAllHarnesses(harness); + expect(bottomSheets.length).toBe(1); + }); + + it('should be able to get aria-label of the bottom sheet', async () => { + fixture.componentInstance.open({ariaLabel: 'Confirm purchase.'}); + const bottomSheet = await loader.getHarness(harness); + expect(await bottomSheet.getAriaLabel()).toBe('Confirm purchase.'); + }); + + it('should be able to dismiss the bottom sheet', async () => { + fixture.componentInstance.open(); + let bottomSheets = await loader.getAllHarnesses(harness); + + expect(bottomSheets.length).toBe(1); + await bottomSheets[0].dismiss(); + + bottomSheets = await loader.getAllHarnesses(harness); + expect(bottomSheets.length).toBe(0); + }); +} + +@Component({ + template: ` + + Hello from the bottom sheet! + + ` +}) +class BottomSheetHarnessTest { + @ViewChild(TemplateRef) template: TemplateRef; + + constructor(readonly bottomSheet: MatBottomSheet) {} + + open(config?: MatBottomSheetConfig) { + return this.bottomSheet.open(this.template, config); + } +} diff --git a/src/material/config.bzl b/src/material/config.bzl index e72c129e505f..60a54ee1866e 100644 --- a/src/material/config.bzl +++ b/src/material/config.bzl @@ -3,6 +3,7 @@ entryPoints = [ "autocomplete/testing", "badge", "bottom-sheet", + "bottom-sheet/testing", "button", "button/testing", "button-toggle", diff --git a/test/karma-system-config.js b/test/karma-system-config.js index 6bc810cd16ae..a8352a2e03c7 100644 --- a/test/karma-system-config.js +++ b/test/karma-system-config.js @@ -101,6 +101,8 @@ System.config({ '@angular/material/autocomplete/testing/shared.spec': 'dist/packages/material/autocomplete/testing/shared.spec.js', '@angular/material/badge': 'dist/packages/material/badge/index.js', '@angular/material/bottom-sheet': 'dist/packages/material/bottom-sheet/index.js', + '@angular/material/bottom-sheet/testing': 'dist/packages/material/bottom-sheet/testing/index.js', + '@angular/material/bottom-sheet/testing/shared.spec': 'dist/packages/material/bottom-sheet/testing/shared.spec.js', '@angular/material/button': 'dist/packages/material/button/index.js', '@angular/material/button/testing': 'dist/packages/material/button/testing/index.js', '@angular/material/button/testing/shared.spec': 'dist/packages/material/button/testing/shared.spec.js',