UNPKG

7.72 kBJavaScriptView Raw
1import { ContentContainerComponentHarness, TestKey, HarnessPredicate } from '@angular/cdk/testing';
2import { coerceBooleanProperty } from '@angular/cdk/coercion';
3
4/**
5 * @license
6 * Copyright Google LLC All Rights Reserved.
7 *
8 * Use of this source code is governed by an MIT-style license that can be
9 * found in the LICENSE file at https://angular.io/license
10 */
11class _MatMenuHarnessBase extends ContentContainerComponentHarness {
12 constructor() {
13 super(...arguments);
14 this._documentRootLocator = this.documentRootLocatorFactory();
15 }
16 // TODO: potentially extend MatButtonHarness
17 /** Whether the menu is disabled. */
18 async isDisabled() {
19 const disabled = (await this.host()).getAttribute('disabled');
20 return coerceBooleanProperty(await disabled);
21 }
22 /** Whether the menu is open. */
23 async isOpen() {
24 return !!(await this._getMenuPanel());
25 }
26 /** Gets the text of the menu's trigger element. */
27 async getTriggerText() {
28 return (await this.host()).text();
29 }
30 /** Focuses the menu. */
31 async focus() {
32 return (await this.host()).focus();
33 }
34 /** Blurs the menu. */
35 async blur() {
36 return (await this.host()).blur();
37 }
38 /** Whether the menu is focused. */
39 async isFocused() {
40 return (await this.host()).isFocused();
41 }
42 /** Opens the menu. */
43 async open() {
44 if (!(await this.isOpen())) {
45 return (await this.host()).click();
46 }
47 }
48 /** Closes the menu. */
49 async close() {
50 const panel = await this._getMenuPanel();
51 if (panel) {
52 return panel.sendKeys(TestKey.ESCAPE);
53 }
54 }
55 /**
56 * Gets a list of `MatMenuItemHarness` representing the items in the menu.
57 * @param filters Optionally filters which menu items are included.
58 */
59 async getItems(filters) {
60 const panelId = await this._getPanelId();
61 if (panelId) {
62 return this._documentRootLocator.locatorForAll(this._itemClass.with({
63 ...(filters || {}),
64 ancestor: `#${panelId}`,
65 }))();
66 }
67 return [];
68 }
69 /**
70 * Clicks an item in the menu, and optionally continues clicking items in subsequent sub-menus.
71 * @param itemFilter A filter used to represent which item in the menu should be clicked. The
72 * first matching menu item will be clicked.
73 * @param subItemFilters A list of filters representing the items to click in any subsequent
74 * sub-menus. The first item in the sub-menu matching the corresponding filter in
75 * `subItemFilters` will be clicked.
76 */
77 async clickItem(itemFilter, ...subItemFilters) {
78 await this.open();
79 const items = await this.getItems(itemFilter);
80 if (!items.length) {
81 throw Error(`Could not find item matching ${JSON.stringify(itemFilter)}`);
82 }
83 if (!subItemFilters.length) {
84 return await items[0].click();
85 }
86 const menu = await items[0].getSubmenu();
87 if (!menu) {
88 throw Error(`Item matching ${JSON.stringify(itemFilter)} does not have a submenu`);
89 }
90 return menu.clickItem(...subItemFilters);
91 }
92 async getRootHarnessLoader() {
93 const panelId = await this._getPanelId();
94 return this.documentRootLocatorFactory().harnessLoaderFor(`#${panelId}`);
95 }
96 /** Gets the menu panel associated with this menu. */
97 async _getMenuPanel() {
98 const panelId = await this._getPanelId();
99 return panelId ? this._documentRootLocator.locatorForOptional(`#${panelId}`)() : null;
100 }
101 /** Gets the id of the menu panel associated with this menu. */
102 async _getPanelId() {
103 const panelId = await (await this.host()).getAttribute('aria-controls');
104 return panelId || null;
105 }
106}
107class _MatMenuItemHarnessBase extends ContentContainerComponentHarness {
108 /** Whether the menu is disabled. */
109 async isDisabled() {
110 const disabled = (await this.host()).getAttribute('disabled');
111 return coerceBooleanProperty(await disabled);
112 }
113 /** Gets the text of the menu item. */
114 async getText() {
115 return (await this.host()).text();
116 }
117 /** Focuses the menu item. */
118 async focus() {
119 return (await this.host()).focus();
120 }
121 /** Blurs the menu item. */
122 async blur() {
123 return (await this.host()).blur();
124 }
125 /** Whether the menu item is focused. */
126 async isFocused() {
127 return (await this.host()).isFocused();
128 }
129 /** Clicks the menu item. */
130 async click() {
131 return (await this.host()).click();
132 }
133 /** Whether this item has a submenu. */
134 async hasSubmenu() {
135 return (await this.host()).matchesSelector(this._menuClass.hostSelector);
136 }
137 /** Gets the submenu associated with this menu item, or null if none. */
138 async getSubmenu() {
139 if (await this.hasSubmenu()) {
140 return new this._menuClass(this.locatorFactory);
141 }
142 return null;
143 }
144}
145/** Harness for interacting with a standard mat-menu in tests. */
146class MatMenuHarness extends _MatMenuHarnessBase {
147 constructor() {
148 super(...arguments);
149 this._itemClass = MatMenuItemHarness;
150 }
151 /**
152 * Gets a `HarnessPredicate` that can be used to search for a `MatMenuHarness` that meets certain
153 * criteria.
154 * @param options Options for filtering which menu instances are considered a match.
155 * @return a `HarnessPredicate` configured with the given options.
156 */
157 static with(options = {}) {
158 return new HarnessPredicate(MatMenuHarness, options).addOption('triggerText', options.triggerText, (harness, text) => HarnessPredicate.stringMatches(harness.getTriggerText(), text));
159 }
160}
161/** The selector for the host element of a `MatMenu` instance. */
162MatMenuHarness.hostSelector = '.mat-menu-trigger';
163/** Harness for interacting with a standard mat-menu-item in tests. */
164class MatMenuItemHarness extends _MatMenuItemHarnessBase {
165 constructor() {
166 super(...arguments);
167 this._menuClass = MatMenuHarness;
168 }
169 /**
170 * Gets a `HarnessPredicate` that can be used to search for a `MatMenuItemHarness` that meets
171 * certain criteria.
172 * @param options Options for filtering which menu item instances are considered a match.
173 * @return a `HarnessPredicate` configured with the given options.
174 */
175 static with(options = {}) {
176 return new HarnessPredicate(MatMenuItemHarness, options)
177 .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))
178 .addOption('hasSubmenu', options.hasSubmenu, async (harness, hasSubmenu) => (await harness.hasSubmenu()) === hasSubmenu);
179 }
180}
181/** The selector for the host element of a `MatMenuItem` instance. */
182MatMenuItemHarness.hostSelector = '.mat-menu-item';
183
184/**
185 * @license
186 * Copyright Google LLC All Rights Reserved.
187 *
188 * Use of this source code is governed by an MIT-style license that can be
189 * found in the LICENSE file at https://angular.io/license
190 */
191
192/**
193 * @license
194 * Copyright Google LLC All Rights Reserved.
195 *
196 * Use of this source code is governed by an MIT-style license that can be
197 * found in the LICENSE file at https://angular.io/license
198 */
199
200/**
201 * @license
202 * Copyright Google LLC All Rights Reserved.
203 *
204 * Use of this source code is governed by an MIT-style license that can be
205 * found in the LICENSE file at https://angular.io/license
206 */
207
208export { MatMenuHarness, MatMenuItemHarness, _MatMenuHarnessBase, _MatMenuItemHarnessBase };
209//# sourceMappingURL=testing.mjs.map