199 lines
7.2 KiB
TypeScript
199 lines
7.2 KiB
TypeScript
|
|
import {Component} from '@angular/core';
|
||
|
|
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
||
|
|
import {HarnessLoader} from '@angular/cdk/testing';
|
||
|
|
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
|
||
|
|
import {MatMenuModule} from '@angular/material/menu';
|
||
|
|
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
|
||
|
|
import {MatMenuHarness} from './menu-harness';
|
||
|
|
|
||
|
|
describe('MatMenuHarness', () => {
|
||
|
|
describe('single-level menu', () => {
|
||
|
|
let fixture: ComponentFixture<MenuHarnessTest>;
|
||
|
|
let loader: HarnessLoader;
|
||
|
|
|
||
|
|
beforeEach(() => {
|
||
|
|
TestBed.configureTestingModule({
|
||
|
|
imports: [MatMenuModule, NoopAnimationsModule, MenuHarnessTest],
|
||
|
|
});
|
||
|
|
|
||
|
|
fixture = TestBed.createComponent(MenuHarnessTest);
|
||
|
|
fixture.detectChanges();
|
||
|
|
loader = TestbedHarnessEnvironment.loader(fixture);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should load all menu harnesses', async () => {
|
||
|
|
const menues = await loader.getAllHarnesses(MatMenuHarness);
|
||
|
|
expect(menues.length).toBe(2);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should load menu with exact text', async () => {
|
||
|
|
const menus = await loader.getAllHarnesses(MatMenuHarness.with({triggerText: 'Settings'}));
|
||
|
|
expect(menus.length).toBe(1);
|
||
|
|
expect(await menus[0].getTriggerText()).toBe('Settings');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should load menu with regex label match', async () => {
|
||
|
|
const menus = await loader.getAllHarnesses(MatMenuHarness.with({triggerText: /settings/i}));
|
||
|
|
expect(menus.length).toBe(1);
|
||
|
|
expect(await menus[0].getTriggerText()).toBe('Settings');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should get disabled state', async () => {
|
||
|
|
const [enabledMenu, disabledMenu] = await loader.getAllHarnesses(MatMenuHarness);
|
||
|
|
expect(await enabledMenu.isDisabled()).toBe(false);
|
||
|
|
expect(await disabledMenu.isDisabled()).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should get menu text', async () => {
|
||
|
|
const [firstMenu, secondMenu] = await loader.getAllHarnesses(MatMenuHarness);
|
||
|
|
expect(await firstMenu.getTriggerText()).toBe('Settings');
|
||
|
|
expect(await secondMenu.getTriggerText()).toBe('Disabled menu');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should focus and blur a menu', async () => {
|
||
|
|
const menu = await loader.getHarness(MatMenuHarness.with({triggerText: 'Settings'}));
|
||
|
|
expect(await menu.isFocused()).toBe(false);
|
||
|
|
await menu.focus();
|
||
|
|
expect(await menu.isFocused()).toBe(true);
|
||
|
|
await menu.blur();
|
||
|
|
expect(await menu.isFocused()).toBe(false);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should open and close', async () => {
|
||
|
|
const menu = await loader.getHarness(MatMenuHarness.with({triggerText: 'Settings'}));
|
||
|
|
expect(await menu.isOpen()).toBe(false);
|
||
|
|
await menu.open();
|
||
|
|
expect(await menu.isOpen()).toBe(true);
|
||
|
|
await menu.open();
|
||
|
|
expect(await menu.isOpen()).toBe(true);
|
||
|
|
await menu.close();
|
||
|
|
expect(await menu.isOpen()).toBe(false);
|
||
|
|
await menu.close();
|
||
|
|
expect(await menu.isOpen()).toBe(false);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should get all items', async () => {
|
||
|
|
const menu = await loader.getHarness(MatMenuHarness.with({triggerText: 'Settings'}));
|
||
|
|
await menu.open();
|
||
|
|
expect((await menu.getItems()).length).toBe(2);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should get filtered items', async () => {
|
||
|
|
const menu = await loader.getHarness(MatMenuHarness.with({triggerText: 'Settings'}));
|
||
|
|
await menu.open();
|
||
|
|
const items = await menu.getItems({text: 'Account'});
|
||
|
|
expect(items.length).toBe(1);
|
||
|
|
expect(await items[0].getText()).toBe('Account');
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('multi-level menu', () => {
|
||
|
|
let fixture: ComponentFixture<NestedMenuHarnessTest>;
|
||
|
|
let loader: HarnessLoader;
|
||
|
|
|
||
|
|
beforeEach(() => {
|
||
|
|
TestBed.configureTestingModule({
|
||
|
|
imports: [MatMenuModule, NoopAnimationsModule, NestedMenuHarnessTest],
|
||
|
|
});
|
||
|
|
|
||
|
|
fixture = TestBed.createComponent(NestedMenuHarnessTest);
|
||
|
|
fixture.detectChanges();
|
||
|
|
loader = TestbedHarnessEnvironment.loader(fixture);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should get submenus', async () => {
|
||
|
|
const menu1 = await loader.getHarness(MatMenuHarness.with({triggerText: 'Menu 1'}));
|
||
|
|
|
||
|
|
await menu1.open();
|
||
|
|
let submenus = await menu1.getItems({hasSubmenu: true});
|
||
|
|
expect(submenus.length).toBe(2);
|
||
|
|
const menu2 = (await submenus[0].getSubmenu())!;
|
||
|
|
const menu3 = (await submenus[1].getSubmenu())!;
|
||
|
|
expect(await menu2.getTriggerText()).toBe('Menu 2');
|
||
|
|
expect(await menu3.getTriggerText()).toBe('Menu 3');
|
||
|
|
|
||
|
|
await menu2.open();
|
||
|
|
expect((await menu2.getItems({hasSubmenu: true})).length).toBe(0);
|
||
|
|
|
||
|
|
await menu3.open();
|
||
|
|
submenus = await menu3.getItems({hasSubmenu: true});
|
||
|
|
expect(submenus.length).toBe(1);
|
||
|
|
const menu4 = (await submenus[0].getSubmenu())!;
|
||
|
|
expect(await menu4.getTriggerText()).toBe('Menu 4');
|
||
|
|
|
||
|
|
await menu4.open();
|
||
|
|
expect((await menu4.getItems({hasSubmenu: true})).length).toBe(0);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should select item in top-level menu', async () => {
|
||
|
|
const menu1 = await loader.getHarness(MatMenuHarness.with({triggerText: 'Menu 1'}));
|
||
|
|
await menu1.clickItem({text: /Leaf/});
|
||
|
|
expect(fixture.componentInstance.lastClickedLeaf).toBe(1);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should throw when item is not found', async () => {
|
||
|
|
const menu1 = await loader.getHarness(MatMenuHarness.with({triggerText: 'Menu 1'}));
|
||
|
|
await expectAsync(menu1.clickItem({text: 'Fake Item'})).toBeRejectedWithError(
|
||
|
|
/Could not find item matching {"text":"Fake Item"}/,
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should select item in nested menu', async () => {
|
||
|
|
const menu1 = await loader.getHarness(MatMenuHarness.with({triggerText: 'Menu 1'}));
|
||
|
|
await menu1.clickItem({text: 'Menu 3'}, {text: 'Menu 4'}, {text: /Leaf/});
|
||
|
|
expect(fixture.componentInstance.lastClickedLeaf).toBe(3);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('should throw when intermediate item does not have submenu', async () => {
|
||
|
|
const menu1 = await loader.getHarness(MatMenuHarness.with({triggerText: 'Menu 1'}));
|
||
|
|
await expectAsync(menu1.clickItem({text: 'Leaf Item 1'}, {})).toBeRejectedWithError(
|
||
|
|
/Item matching {"text":"Leaf Item 1"} does not have a submenu/,
|
||
|
|
);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
@Component({
|
||
|
|
template: `
|
||
|
|
<button type="button" id="settings" [matMenuTriggerFor]="settingsMenu">Settings</button>
|
||
|
|
<button type="button" disabled [matMenuTriggerFor]="settingsMenu">Disabled menu</button>
|
||
|
|
|
||
|
|
<mat-menu #settingsMenu>
|
||
|
|
<menu mat-menu-item>Profile</menu>
|
||
|
|
<menu mat-menu-item>Account</menu>
|
||
|
|
</mat-menu>
|
||
|
|
`,
|
||
|
|
standalone: true,
|
||
|
|
imports: [MatMenuModule],
|
||
|
|
})
|
||
|
|
class MenuHarnessTest {}
|
||
|
|
|
||
|
|
@Component({
|
||
|
|
template: `
|
||
|
|
<button [matMenuTriggerFor]="menu1">Menu 1</button>
|
||
|
|
|
||
|
|
<mat-menu #menu1>
|
||
|
|
<button mat-menu-item [matMenuTriggerFor]="menu2">Menu 2</button>
|
||
|
|
<button mat-menu-item (click)="lastClickedLeaf = 1">Leaf Item 1</button>
|
||
|
|
<button mat-menu-item [matMenuTriggerFor]="menu3">Menu 3</button>
|
||
|
|
</mat-menu>
|
||
|
|
|
||
|
|
<mat-menu #menu2>
|
||
|
|
<button mat-menu-item (click)="lastClickedLeaf = 2">Leaf Item 2</button>
|
||
|
|
</mat-menu>
|
||
|
|
|
||
|
|
<mat-menu #menu3>
|
||
|
|
<button mat-menu-item [matMenuTriggerFor]="menu4">Menu 4</button>
|
||
|
|
</mat-menu>
|
||
|
|
|
||
|
|
<mat-menu #menu4>
|
||
|
|
<button mat-menu-item (click)="lastClickedLeaf = 3">Leaf Item 3</button>
|
||
|
|
</mat-menu>
|
||
|
|
`,
|
||
|
|
standalone: true,
|
||
|
|
imports: [MatMenuModule],
|
||
|
|
})
|
||
|
|
class NestedMenuHarnessTest {
|
||
|
|
lastClickedLeaf = 0;
|
||
|
|
}
|