diff --git a/test/benchmarks/material/menu/BUILD.bazel b/test/benchmarks/material/menu/BUILD.bazel new file mode 100644 index 000000000000..57d50dc86b3b --- /dev/null +++ b/test/benchmarks/material/menu/BUILD.bazel @@ -0,0 +1,23 @@ +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", + ], + ng_assets = [":menu.html"], + ng_deps = [ + "@npm//@angular/core", + "@npm//@angular/platform-browser", + "//src/material/menu", + ], + 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..d4dc09f02ba1 --- /dev/null +++ b/test/benchmarks/material/menu/app.module.ts @@ -0,0 +1,33 @@ +/** + * @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 {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', + templateUrl: './menu.html', + encapsulation: ViewEncapsulation.None, + styleUrls: ['//src/material/core/theming/prebuilt/indigo-pink.css'], +}) +export class MenuBenchmarkApp { +} + + +@NgModule({ + declarations: [MenuBenchmarkApp], + imports: [ + BrowserModule, + MatMenuModule, + ], + 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 new file mode 100755 index 000000000000..51dcc406d1a3 --- /dev/null +++ b/test/benchmarks/material/menu/menu.perf-spec.ts @@ -0,0 +1,69 @@ +/** + * @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 {$, by, element, ElementFinder, Key} from 'protractor'; +import {runBenchmark} from '@angular/dev-infra-private/benchmark/driver-utilities'; + +// Clicking to close a menu is problematic. This is a solution that uses `.sendKeys()` avoids +// issues with `.click()`. + +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', () => { + it('opens a basic menu', async () => { + let trigger: ElementFinder; + await runBenchmark({ + id: 'basic-menu-open', + url: '', + ignoreBrowserSynchronization: true, + params: [], + setup: async () => trigger = element(by.buttonText('Basic Menu')), + work: async () => { + await trigger.click(); + await closeMenu(trigger); + } + }); + }); + + it('opens the root menu of a set of nested menus', async () => { + let trigger: ElementFinder; + await runBenchmark({ + id: 'nested-menu-open-shallow', + url: '', + ignoreBrowserSynchronization: true, + params: [], + setup: async () => trigger = element(by.buttonText('Nested Menu')), + work: async () => { + await trigger.click(); + await closeMenu(trigger); + }, + }); + }); + + it('fully opens a menu with nested menus', async () => { + let trigger: ElementFinder; + await runBenchmark({ + id: 'menu-open-deep', + url: '', + ignoreBrowserSynchronization: true, + params: [], + setup: async () => trigger = element(by.buttonText('Nested Menu')), + work: async () => { + await trigger.click(); + await element(by.buttonText('Sub Menu 1')).click(); + await element(by.buttonText('Sub Menu 2')).click(); + await closeMenu(trigger); + }, + }); + }); +});