Skip to content

Commit ab5cb65

Browse files
committed
test(mdc-menu): add performance tests for mdc-menu
* Also cleaned up a small ts error I was getting from the material menu's driver.
1 parent f00f46a commit ab5cb65

File tree

5 files changed

+163
-1
lines changed

5 files changed

+163
-1
lines changed

test/benchmarks/material/menu/menu.perf-spec.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ describe('menu performance benchmarks', () => {
5757
url: '',
5858
ignoreBrowserSynchronization: true,
5959
params: [],
60-
setup: async () => trigger = element(by.buttonText('Nested Menu')),
60+
setup: () => {
61+
trigger = element(by.buttonText('Nested Menu'));
62+
},
6163
work: async () => {
6264
await trigger.click();
6365
await element(by.buttonText('Sub Menu 1')).click();

test/benchmarks/mdc/menu/BUILD.bazel

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
load("@npm_angular_dev_infra_private//benchmark/component_benchmark:component_benchmark.bzl", "component_benchmark")
2+
3+
# TODO(wagnermaciel): Update this target to provide indigo-pink in a way that doesn't require having to import it with
4+
# stylesUrls inside the components once `component_benchmark` supports asset injection.
5+
6+
component_benchmark(
7+
name = "benchmark",
8+
driver = ":menu.perf-spec.ts",
9+
driver_deps = [
10+
"@npm//@angular/dev-infra-private",
11+
"@npm//protractor",
12+
"@npm//@types/jasmine",
13+
],
14+
ng_assets = [":menu.html"],
15+
ng_deps = [
16+
"@npm//@angular/core",
17+
"@npm//@angular/platform-browser",
18+
"//src/material-experimental/mdc-menu",
19+
],
20+
ng_srcs = [":app.module.ts"],
21+
prefix = "",
22+
styles = ["//src/material-experimental/mdc-theming:indigo_pink_prebuilt"],
23+
)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {Component, NgModule, ViewEncapsulation} from '@angular/core';
10+
import {BrowserModule} from '@angular/platform-browser';
11+
import {MatMenuModule} from '@angular/material-experimental/mdc-menu';
12+
13+
/** component: mdc-menu */
14+
15+
@Component({
16+
selector: 'app-root',
17+
templateUrl: './menu.html',
18+
encapsulation: ViewEncapsulation.None,
19+
styleUrls: ['//src/material-experimental/mdc-theming/prebuilt/indigo-pink.css'],
20+
})
21+
export class MenuBenchmarkApp {
22+
}
23+
24+
25+
@NgModule({
26+
declarations: [MenuBenchmarkApp],
27+
imports: [
28+
BrowserModule,
29+
MatMenuModule,
30+
],
31+
bootstrap: [MenuBenchmarkApp]
32+
})
33+
export class AppModule {}

test/benchmarks/mdc/menu/menu.html

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<button mat-button [matMenuTriggerFor]="basic">Basic Menu</button>
2+
<button mat-button [matMenuTriggerFor]="nested">Nested Menu</button>
3+
4+
<mat-menu #basic="matMenu">
5+
<button mat-menu-item>Item 1</button>
6+
<button mat-menu-item>Item 2</button>
7+
<button mat-menu-item>Item 3</button>
8+
<button mat-menu-item>Item 4</button>
9+
<button mat-menu-item>Item 5</button>
10+
<button mat-menu-item>Item 6</button>
11+
<button mat-menu-item>Item 7</button>
12+
<button mat-menu-item>Item 8</button>
13+
<button mat-menu-item>Item 9</button>
14+
<button mat-menu-item>Item 10</button>
15+
</mat-menu>
16+
17+
<!-- Nested Menu with 3 Levels -->
18+
19+
<mat-menu #nested="matMenu">
20+
<button mat-menu-item [matMenuTriggerFor]="sub1">Sub Menu 1</button>
21+
</mat-menu>
22+
23+
<mat-menu #sub1="matMenu">
24+
<button mat-menu-item [matMenuTriggerFor]="sub2">Sub Menu 2</button>
25+
</mat-menu>
26+
27+
<mat-menu #sub2="matMenu">
28+
<button mat-menu-item>Item 1</button>
29+
<button mat-menu-item>Item 2</button>
30+
<button mat-menu-item>Item 3</button>
31+
<button mat-menu-item>Item 4</button>
32+
<button mat-menu-item>Item 5</button>
33+
</mat-menu>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {$, by, element, ElementFinder, Key} from 'protractor';
10+
import {runBenchmark} from '@angular/dev-infra-private/benchmark/driver-utilities';
11+
12+
// Clicking to close a menu is problematic. This is a solution that uses `.sendKeys()` avoids
13+
// issues with `.click()`.
14+
15+
async function closeMenu(trigger: ElementFinder) {
16+
const backdropId = await trigger.getAttribute('aria-controls');
17+
if (await $(`#${backdropId}`).isPresent()) {
18+
await $(`#${backdropId}`).sendKeys(Key.ESCAPE);
19+
}
20+
}
21+
22+
describe('menu performance benchmarks', () => {
23+
it('opens a basic menu', async () => {
24+
let trigger: ElementFinder;
25+
await runBenchmark({
26+
id: 'basic-menu-open',
27+
url: '',
28+
ignoreBrowserSynchronization: true,
29+
params: [],
30+
setup: async () => {
31+
trigger = element(by.buttonText('Basic Menu'));
32+
},
33+
work: async () => {
34+
await trigger.click();
35+
await closeMenu(trigger);
36+
}
37+
});
38+
});
39+
40+
it('opens the root menu of a set of nested menus', async () => {
41+
let trigger: ElementFinder;
42+
await runBenchmark({
43+
id: 'nested-menu-open-shallow',
44+
url: '',
45+
ignoreBrowserSynchronization: true,
46+
params: [],
47+
setup: async () => trigger = element(by.buttonText('Nested Menu')),
48+
work: async () => {
49+
await trigger.click();
50+
await closeMenu(trigger);
51+
},
52+
});
53+
});
54+
55+
it('fully opens a menu with nested menus', async () => {
56+
let trigger: ElementFinder;
57+
await runBenchmark({
58+
id: 'menu-open-deep',
59+
url: '',
60+
ignoreBrowserSynchronization: true,
61+
params: [],
62+
setup: async () => trigger = element(by.buttonText('Nested Menu')),
63+
work: async () => {
64+
await trigger.click();
65+
await element(by.buttonText('Sub Menu 1')).click();
66+
await element(by.buttonText('Sub Menu 2')).click();
67+
await closeMenu(trigger);
68+
},
69+
});
70+
});
71+
});

0 commit comments

Comments
 (0)