From b1162a75df421c135c3e117a7884ea7ebb2bdf30 Mon Sep 17 00:00:00 2001 From: Wagner Maciel Date: Fri, 5 Jun 2020 15:16:37 -0700 Subject: [PATCH 1/4] test(menu): add performance tests for mat-menu --- test/benchmarks/material/menu/BUILD.bazel | 26 ++++++++++ test/benchmarks/material/menu/app.module.ts | 50 +++++++++++++++++++ .../material/menu/menu.perf-spec.ts | 34 +++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 test/benchmarks/material/menu/BUILD.bazel create mode 100644 test/benchmarks/material/menu/app.module.ts create mode 100755 test/benchmarks/material/menu/menu.perf-spec.ts diff --git a/test/benchmarks/material/menu/BUILD.bazel b/test/benchmarks/material/menu/BUILD.bazel new file mode 100644 index 000000000000..a85f91a9d6c0 --- /dev/null +++ b/test/benchmarks/material/menu/BUILD.bazel @@ -0,0 +1,26 @@ +load("@npm_angular_dev_infra_private//benchmark/component_benchmark:component_benchmark.bzl", "component_benchmark") + +# TODO(wagnermaciel): Update this target to provide indigo-pink in a way that doesn't require having to import it with +# stylesUrls inside the components once `component_benchmark` supports asset injection. + +component_benchmark( + name = "benchmark", + driver = ":menu.perf-spec.ts", + driver_deps = [ + "@npm//@angular/dev-infra-private", + "@npm//protractor", + "@npm//@types/jasmine", + "//src/cdk/testing", + "//src/cdk/testing/protractor", + "//src/material/menu/testing", + ], + ng_deps = [ + "@npm//@angular/core", + "@npm//@angular/platform-browser", + "//src/material/menu", + "//src/cdk/a11y", + ], + ng_srcs = [":app.module.ts"], + prefix = "", + styles = ["//src/material/prebuilt-themes:indigo-pink"], +) diff --git a/test/benchmarks/material/menu/app.module.ts b/test/benchmarks/material/menu/app.module.ts new file mode 100644 index 000000000000..e6848627d4fb --- /dev/null +++ b/test/benchmarks/material/menu/app.module.ts @@ -0,0 +1,50 @@ +/** + * @license + * Copyright Google Inc. 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 {A11yModule} from '@angular/cdk/a11y'; +import {Component, NgModule, ViewEncapsulation} from '@angular/core'; +import {BrowserModule} from '@angular/platform-browser'; +import {MatMenuModule} from '@angular/material/menu'; + +/** component: mat-menu */ + +@Component({ + selector: 'app-root', + template: ` + + + + + + + + + + + + + + `, + encapsulation: ViewEncapsulation.None, + styleUrls: ['//src/material/core/theming/prebuilt/indigo-pink.css'], +}) +export class MenuBenchmarkApp { +} + + +@NgModule({ + declarations: [MenuBenchmarkApp], + imports: [ + A11yModule, + BrowserModule, + MatMenuModule, + ], + providers: [], + bootstrap: [MenuBenchmarkApp] +}) +export class AppModule {} diff --git a/test/benchmarks/material/menu/menu.perf-spec.ts b/test/benchmarks/material/menu/menu.perf-spec.ts new file mode 100755 index 000000000000..e2e9e12ba5c8 --- /dev/null +++ b/test/benchmarks/material/menu/menu.perf-spec.ts @@ -0,0 +1,34 @@ +/** + * @license + * Copyright Google Inc. 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 {runBenchmark} from '@angular/dev-infra-private/benchmark/driver-utilities'; + +import {HarnessLoader} from '@angular/cdk/testing'; +import {ProtractorHarnessEnvironment} from '@angular/cdk/testing/protractor'; +import {MatMenuHarness} from '@angular/material/menu/testing/menu-harness'; + +let loader: HarnessLoader; + +describe('menu performance benchmarks', () => { + beforeEach(() => { + loader = ProtractorHarnessEnvironment.loader(); + }); + + it('opens a menu with 10 items', async () => { + let menu: MatMenuHarness; + await runBenchmark({ + id: 'menu-open', + url: '', + ignoreBrowserSynchronization: true, + params: [], + setup: async () => menu = await loader.getHarness(MatMenuHarness), + prepare: async () => await menu.close(), + work: async () => await menu.open(), + }); + }); +}); From 02452206f5bc6948fe00cd11358ef2b8ae36921f Mon Sep 17 00:00:00 2001 From: Wagner Maciel Date: Fri, 31 Jul 2020 14:40:02 -0700 Subject: [PATCH 2/4] fixup! test(menu): add performance tests for mat-menu --- test/benchmarks/material/menu/app.module.ts | 2 +- test/benchmarks/material/menu/menu.perf-spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/benchmarks/material/menu/app.module.ts b/test/benchmarks/material/menu/app.module.ts index e6848627d4fb..64f6b37324f2 100644 --- a/test/benchmarks/material/menu/app.module.ts +++ b/test/benchmarks/material/menu/app.module.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright Google Inc. All Rights Reserved. + * 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 diff --git a/test/benchmarks/material/menu/menu.perf-spec.ts b/test/benchmarks/material/menu/menu.perf-spec.ts index e2e9e12ba5c8..280f8115d49b 100755 --- a/test/benchmarks/material/menu/menu.perf-spec.ts +++ b/test/benchmarks/material/menu/menu.perf-spec.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright Google Inc. All Rights Reserved. + * 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 From de8e7ebefaf8238e1a42d50770fa8230616b9194 Mon Sep 17 00:00:00 2001 From: Wagner Maciel Date: Mon, 3 Aug 2020 12:37:23 -0700 Subject: [PATCH 3/4] fixup! test(menu): add performance tests for mat-menu --- test/benchmarks/material/menu/BUILD.bazel | 2 +- test/benchmarks/material/menu/app.module.ts | 19 +-------- test/benchmarks/material/menu/menu.html | 33 +++++++++++++++ .../material/menu/menu.perf-spec.ts | 41 ++++++++++++++++++- 4 files changed, 75 insertions(+), 20 deletions(-) create mode 100644 test/benchmarks/material/menu/menu.html diff --git a/test/benchmarks/material/menu/BUILD.bazel b/test/benchmarks/material/menu/BUILD.bazel index a85f91a9d6c0..5d313a8935e7 100644 --- a/test/benchmarks/material/menu/BUILD.bazel +++ b/test/benchmarks/material/menu/BUILD.bazel @@ -14,11 +14,11 @@ component_benchmark( "//src/cdk/testing/protractor", "//src/material/menu/testing", ], + ng_assets = [":menu.html"], ng_deps = [ "@npm//@angular/core", "@npm//@angular/platform-browser", "//src/material/menu", - "//src/cdk/a11y", ], ng_srcs = [":app.module.ts"], prefix = "", diff --git a/test/benchmarks/material/menu/app.module.ts b/test/benchmarks/material/menu/app.module.ts index 64f6b37324f2..d4dc09f02ba1 100644 --- a/test/benchmarks/material/menu/app.module.ts +++ b/test/benchmarks/material/menu/app.module.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import {A11yModule} from '@angular/cdk/a11y'; import {Component, NgModule, ViewEncapsulation} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {MatMenuModule} from '@angular/material/menu'; @@ -15,21 +14,7 @@ import {MatMenuModule} from '@angular/material/menu'; @Component({ selector: 'app-root', - template: ` - - - - - - - - - - - - - - `, + templateUrl: './menu.html', encapsulation: ViewEncapsulation.None, styleUrls: ['//src/material/core/theming/prebuilt/indigo-pink.css'], }) @@ -40,11 +25,9 @@ export class MenuBenchmarkApp { @NgModule({ declarations: [MenuBenchmarkApp], imports: [ - A11yModule, BrowserModule, MatMenuModule, ], - providers: [], bootstrap: [MenuBenchmarkApp] }) export class AppModule {} diff --git a/test/benchmarks/material/menu/menu.html b/test/benchmarks/material/menu/menu.html new file mode 100644 index 000000000000..eddeaaa4f19d --- /dev/null +++ b/test/benchmarks/material/menu/menu.html @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/benchmarks/material/menu/menu.perf-spec.ts b/test/benchmarks/material/menu/menu.perf-spec.ts index 280f8115d49b..98e3667d6ee3 100755 --- a/test/benchmarks/material/menu/menu.perf-spec.ts +++ b/test/benchmarks/material/menu/menu.perf-spec.ts @@ -26,9 +26,48 @@ describe('menu performance benchmarks', () => { url: '', ignoreBrowserSynchronization: true, params: [], - setup: async () => menu = await loader.getHarness(MatMenuHarness), + setup: async () => { + menu = await loader.getHarness(MatMenuHarness.with({ triggerText: 'Basic Menu' })); + }, prepare: async () => await menu.close(), work: async () => await menu.open(), }); }); + + it('opens a nested menu', async () => { + let menu: MatMenuHarness; + await runBenchmark({ + id: 'nested-menu-open', + url: '', + ignoreBrowserSynchronization: true, + params: [], + setup: async () => { + menu = await loader.getHarness(MatMenuHarness.with({ triggerText: 'Nested Menu' })); + }, + prepare: async () => await menu.close(), + work: async () => await menu.open(), + }); + }); + + // NOTE: This test seems very slow at the moment. This IS NOT because opening nested menus is + // slow. This IS because calls to the loader are expensive. + + it('fully opens a nested menu', async () => { + let menu: MatMenuHarness; + await runBenchmark({ + id: 'nested-menu-open', + url: '', + ignoreBrowserSynchronization: true, + params: [], + setup: async () => { + menu = await loader.getHarness(MatMenuHarness.with({ triggerText: 'Nested Menu' })); + }, + prepare: async () => await menu.close(), + work: async () => { + await menu.open(); + await (await loader.getHarness(MatMenuHarness.with({ triggerText: 'Sub Menu 1' }))).open(); + await (await loader.getHarness(MatMenuHarness.with({ triggerText: 'Sub Menu 2' }))).open(); + }, + }); + }); }); From 5854b0e1cd5f67c9fb97e624eb7efd17eb9e8892 Mon Sep 17 00:00:00 2001 From: Wagner Maciel Date: Mon, 3 Aug 2020 16:28:58 -0700 Subject: [PATCH 4/4] fixup! test(menu): add performance tests for mat-menu --- test/benchmarks/material/menu/BUILD.bazel | 3 - .../material/menu/menu.perf-spec.ts | 68 +++++++++---------- 2 files changed, 32 insertions(+), 39 deletions(-) diff --git a/test/benchmarks/material/menu/BUILD.bazel b/test/benchmarks/material/menu/BUILD.bazel index 5d313a8935e7..57d50dc86b3b 100644 --- a/test/benchmarks/material/menu/BUILD.bazel +++ b/test/benchmarks/material/menu/BUILD.bazel @@ -10,9 +10,6 @@ component_benchmark( "@npm//@angular/dev-infra-private", "@npm//protractor", "@npm//@types/jasmine", - "//src/cdk/testing", - "//src/cdk/testing/protractor", - "//src/material/menu/testing", ], ng_assets = [":menu.html"], ng_deps = [ diff --git a/test/benchmarks/material/menu/menu.perf-spec.ts b/test/benchmarks/material/menu/menu.perf-spec.ts index 98e3667d6ee3..51dcc406d1a3 100755 --- a/test/benchmarks/material/menu/menu.perf-spec.ts +++ b/test/benchmarks/material/menu/menu.perf-spec.ts @@ -6,67 +6,63 @@ * found in the LICENSE file at https://angular.io/license */ +import {$, by, element, ElementFinder, Key} from 'protractor'; import {runBenchmark} from '@angular/dev-infra-private/benchmark/driver-utilities'; -import {HarnessLoader} from '@angular/cdk/testing'; -import {ProtractorHarnessEnvironment} from '@angular/cdk/testing/protractor'; -import {MatMenuHarness} from '@angular/material/menu/testing/menu-harness'; +// Clicking to close a menu is problematic. This is a solution that uses `.sendKeys()` avoids +// issues with `.click()`. -let loader: HarnessLoader; +async function closeMenu(trigger: ElementFinder) { + const backdropId = await trigger.getAttribute('aria-controls'); + if (await $(`#${backdropId}`).isPresent()) { + await $(`#${backdropId}`).sendKeys(Key.ESCAPE); + } +} describe('menu performance benchmarks', () => { - beforeEach(() => { - loader = ProtractorHarnessEnvironment.loader(); - }); - - it('opens a menu with 10 items', async () => { - let menu: MatMenuHarness; + it('opens a basic menu', async () => { + let trigger: ElementFinder; await runBenchmark({ - id: 'menu-open', + id: 'basic-menu-open', url: '', ignoreBrowserSynchronization: true, params: [], - setup: async () => { - menu = await loader.getHarness(MatMenuHarness.with({ triggerText: 'Basic Menu' })); - }, - prepare: async () => await menu.close(), - work: async () => await menu.open(), + setup: async () => trigger = element(by.buttonText('Basic Menu')), + work: async () => { + await trigger.click(); + await closeMenu(trigger); + } }); }); - it('opens a nested menu', async () => { - let menu: MatMenuHarness; + it('opens the root menu of a set of nested menus', async () => { + let trigger: ElementFinder; await runBenchmark({ - id: 'nested-menu-open', + id: 'nested-menu-open-shallow', url: '', ignoreBrowserSynchronization: true, params: [], - setup: async () => { - menu = await loader.getHarness(MatMenuHarness.with({ triggerText: 'Nested Menu' })); + setup: async () => trigger = element(by.buttonText('Nested Menu')), + work: async () => { + await trigger.click(); + await closeMenu(trigger); }, - prepare: async () => await menu.close(), - work: async () => await menu.open(), }); }); - // NOTE: This test seems very slow at the moment. This IS NOT because opening nested menus is - // slow. This IS because calls to the loader are expensive. - - it('fully opens a nested menu', async () => { - let menu: MatMenuHarness; + it('fully opens a menu with nested menus', async () => { + let trigger: ElementFinder; await runBenchmark({ - id: 'nested-menu-open', + id: 'menu-open-deep', url: '', ignoreBrowserSynchronization: true, params: [], - setup: async () => { - menu = await loader.getHarness(MatMenuHarness.with({ triggerText: 'Nested Menu' })); - }, - prepare: async () => await menu.close(), + setup: async () => trigger = element(by.buttonText('Nested Menu')), work: async () => { - await menu.open(); - await (await loader.getHarness(MatMenuHarness.with({ triggerText: 'Sub Menu 1' }))).open(); - await (await loader.getHarness(MatMenuHarness.with({ triggerText: 'Sub Menu 2' }))).open(); + await trigger.click(); + await element(by.buttonText('Sub Menu 1')).click(); + await element(by.buttonText('Sub Menu 2')).click(); + await closeMenu(trigger); }, }); });