testing.mjs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. import { ContentContainerComponentHarness, HarnessPredicate, ComponentHarness, parallel } from '@angular/cdk/testing';
  2. /** Harness for interacting with an Angular Material tab in tests. */
  3. class MatTabHarness extends ContentContainerComponentHarness {
  4. /** The selector for the host element of a `MatTab` instance. */
  5. static hostSelector = '.mat-mdc-tab';
  6. /**
  7. * Gets a `HarnessPredicate` that can be used to search for a tab with specific attributes.
  8. * @param options Options for filtering which tab instances are considered a match.
  9. * @return a `HarnessPredicate` configured with the given options.
  10. */
  11. static with(options = {}) {
  12. return new HarnessPredicate(this, options)
  13. .addOption('label', options.label, (harness, label) => HarnessPredicate.stringMatches(harness.getLabel(), label))
  14. .addOption('selected', options.selected, async (harness, selected) => (await harness.isSelected()) == selected);
  15. }
  16. /** Gets the label of the tab. */
  17. async getLabel() {
  18. return (await this.host()).text();
  19. }
  20. /** Gets the aria-label of the tab. */
  21. async getAriaLabel() {
  22. return (await this.host()).getAttribute('aria-label');
  23. }
  24. /** Gets the value of the "aria-labelledby" attribute. */
  25. async getAriaLabelledby() {
  26. return (await this.host()).getAttribute('aria-labelledby');
  27. }
  28. /** Whether the tab is selected. */
  29. async isSelected() {
  30. const hostEl = await this.host();
  31. return (await hostEl.getAttribute('aria-selected')) === 'true';
  32. }
  33. /** Whether the tab is disabled. */
  34. async isDisabled() {
  35. const hostEl = await this.host();
  36. return (await hostEl.getAttribute('aria-disabled')) === 'true';
  37. }
  38. /** Selects the given tab by clicking on the label. Tab cannot be selected if disabled. */
  39. async select() {
  40. await (await this.host()).click('center');
  41. }
  42. /** Gets the text content of the tab. */
  43. async getTextContent() {
  44. const contentId = await this._getContentId();
  45. const contentEl = await this.documentRootLocatorFactory().locatorFor(`#${contentId}`)();
  46. return contentEl.text();
  47. }
  48. async getRootHarnessLoader() {
  49. const contentId = await this._getContentId();
  50. return this.documentRootLocatorFactory().harnessLoaderFor(`#${contentId}`);
  51. }
  52. /** Gets the element id for the content of the current tab. */
  53. async _getContentId() {
  54. const hostEl = await this.host();
  55. // Tabs never have an empty "aria-controls" attribute.
  56. return (await hostEl.getAttribute('aria-controls'));
  57. }
  58. }
  59. /** Harness for interacting with a mat-tab-group in tests. */
  60. class MatTabGroupHarness extends ComponentHarness {
  61. /** The selector for the host element of a `MatTabGroup` instance. */
  62. static hostSelector = '.mat-mdc-tab-group';
  63. /**
  64. * Gets a `HarnessPredicate` that can be used to search for a tab group with specific attributes.
  65. * @param options Options for filtering which tab group instances are considered a match.
  66. * @return a `HarnessPredicate` configured with the given options.
  67. */
  68. static with(options = {}) {
  69. return new HarnessPredicate(this, options).addOption('selectedTabLabel', options.selectedTabLabel, async (harness, label) => {
  70. const selectedTab = await harness.getSelectedTab();
  71. return HarnessPredicate.stringMatches(await selectedTab.getLabel(), label);
  72. });
  73. }
  74. /**
  75. * Gets the list of tabs in the tab group.
  76. * @param filter Optionally filters which tabs are included.
  77. */
  78. async getTabs(filter = {}) {
  79. return this.locatorForAll(MatTabHarness.with(filter))();
  80. }
  81. /** Gets the selected tab of the tab group. */
  82. async getSelectedTab() {
  83. const tabs = await this.getTabs();
  84. const isSelected = await parallel(() => tabs.map(t => t.isSelected()));
  85. for (let i = 0; i < tabs.length; i++) {
  86. if (isSelected[i]) {
  87. return tabs[i];
  88. }
  89. }
  90. throw new Error('No selected tab could be found.');
  91. }
  92. /**
  93. * Selects a tab in this tab group.
  94. * @param filter An optional filter to apply to the child tabs. The first tab matching the filter
  95. * will be selected.
  96. */
  97. async selectTab(filter = {}) {
  98. const tabs = await this.getTabs(filter);
  99. if (!tabs.length) {
  100. throw Error(`Cannot find mat-tab matching filter ${JSON.stringify(filter)}`);
  101. }
  102. await tabs[0].select();
  103. }
  104. }
  105. /** Harness for interacting with a Angular Material tab link in tests. */
  106. class MatTabLinkHarness extends ComponentHarness {
  107. /** The selector for the host element of a `MatTabLink` instance. */
  108. static hostSelector = '.mat-mdc-tab-link';
  109. /**
  110. * Gets a `HarnessPredicate` that can be used to search for a tab link with specific attributes.
  111. * @param options Options for filtering which tab link instances are considered a match.
  112. * @return a `HarnessPredicate` configured with the given options.
  113. */
  114. static with(options = {}) {
  115. return new HarnessPredicate(this, options).addOption('label', options.label, (harness, label) => HarnessPredicate.stringMatches(harness.getLabel(), label));
  116. }
  117. /** Gets the label of the link. */
  118. async getLabel() {
  119. return (await this.host()).text();
  120. }
  121. /** Whether the link is active. */
  122. async isActive() {
  123. const host = await this.host();
  124. return host.hasClass('mdc-tab--active');
  125. }
  126. /** Whether the link is disabled. */
  127. async isDisabled() {
  128. const host = await this.host();
  129. return host.hasClass('mat-mdc-tab-disabled');
  130. }
  131. /** Clicks on the link. */
  132. async click() {
  133. await (await this.host()).click();
  134. }
  135. }
  136. /** Harness for interacting with a standard mat-tab-nav-panel in tests. */
  137. class MatTabNavPanelHarness extends ContentContainerComponentHarness {
  138. /** The selector for the host element of a `MatTabNavPanel` instance. */
  139. static hostSelector = '.mat-mdc-tab-nav-panel';
  140. /**
  141. * Gets a `HarnessPredicate` that can be used to search for a tab nav panel with specific
  142. * attributes.
  143. * @param options Options for filtering which tab nav panel instances are considered a match.
  144. * @return a `HarnessPredicate` configured with the given options.
  145. */
  146. static with(options = {}) {
  147. return new HarnessPredicate(this, options);
  148. }
  149. /** Gets the tab panel text content. */
  150. async getTextContent() {
  151. return (await this.host()).text();
  152. }
  153. }
  154. /** Harness for interacting with a mat-tab-nav-bar in tests. */
  155. class MatTabNavBarHarness extends ComponentHarness {
  156. /** The selector for the host element of a `MatTabNavBar` instance. */
  157. static hostSelector = '.mat-mdc-tab-nav-bar';
  158. /**
  159. * Gets a `HarnessPredicate` that can be used to search for a tab nav bar with specific
  160. * attributes.
  161. * @param options Options for filtering which tab nav bar instances are considered a match.
  162. * @return a `HarnessPredicate` configured with the given options.
  163. */
  164. static with(options = {}) {
  165. return new HarnessPredicate(this, options);
  166. }
  167. /**
  168. * Gets the list of links in the nav bar.
  169. * @param filter Optionally filters which links are included.
  170. */
  171. async getLinks(filter = {}) {
  172. return this.locatorForAll(MatTabLinkHarness.with(filter))();
  173. }
  174. /** Gets the active link in the nav bar. */
  175. async getActiveLink() {
  176. const links = await this.getLinks();
  177. const isActive = await parallel(() => links.map(t => t.isActive()));
  178. for (let i = 0; i < links.length; i++) {
  179. if (isActive[i]) {
  180. return links[i];
  181. }
  182. }
  183. throw new Error('No active link could be found.');
  184. }
  185. /**
  186. * Clicks a link inside the nav bar.
  187. * @param filter An optional filter to apply to the child link. The first link matching the filter
  188. * will be clicked.
  189. */
  190. async clickLink(filter = {}) {
  191. const tabs = await this.getLinks(filter);
  192. if (!tabs.length) {
  193. throw Error(`Cannot find mat-tab-link matching filter ${JSON.stringify(filter)}`);
  194. }
  195. await tabs[0].click();
  196. }
  197. /** Gets the panel associated with the nav bar. */
  198. async getPanel() {
  199. const link = await this.getActiveLink();
  200. const host = await link.host();
  201. const panelId = await host.getAttribute('aria-controls');
  202. if (!panelId) {
  203. throw Error('No panel is controlled by the nav bar.');
  204. }
  205. const filter = { selector: `#${panelId}` };
  206. return await this.documentRootLocatorFactory().locatorFor(MatTabNavPanelHarness.with(filter))();
  207. }
  208. }
  209. export { MatTabGroupHarness, MatTabHarness, MatTabLinkHarness, MatTabNavBarHarness };
  210. //# sourceMappingURL=testing.mjs.map