testing.mjs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import { ComponentHarness, HarnessPredicate, TestKey } from '@angular/cdk/testing';
  2. import { M as MatOptionHarness } from '../option-harness-BFcc-M_4.mjs';
  3. import { coerceBooleanProperty } from '@angular/cdk/coercion';
  4. class MatTimepickerHarness extends ComponentHarness {
  5. _documentRootLocator = this.documentRootLocatorFactory();
  6. static hostSelector = 'mat-timepicker';
  7. /**
  8. * Gets a `HarnessPredicate` that can be used to search for a timepicker with specific
  9. * attributes.
  10. * @param options Options for filtering which timepicker instances are considered a match.
  11. * @return a `HarnessPredicate` configured with the given options.
  12. */
  13. static with(options = {}) {
  14. return new HarnessPredicate(this, options);
  15. }
  16. /** Whether the timepicker is open. */
  17. async isOpen() {
  18. const selector = await this._getPanelSelector();
  19. const panel = await this._documentRootLocator.locatorForOptional(selector)();
  20. return panel !== null;
  21. }
  22. /** Gets the options inside the timepicker panel. */
  23. async getOptions(filters) {
  24. if (!(await this.isOpen())) {
  25. throw new Error('Unable to retrieve options for timepicker. Timepicker panel is closed.');
  26. }
  27. return this._documentRootLocator.locatorForAll(MatOptionHarness.with({
  28. ...(filters || {}),
  29. ancestor: await this._getPanelSelector(),
  30. }))();
  31. }
  32. /** Selects the first option matching the given filters. */
  33. async selectOption(filters) {
  34. const options = await this.getOptions(filters);
  35. if (!options.length) {
  36. throw Error(`Could not find a mat-option matching ${JSON.stringify(filters)}`);
  37. }
  38. await options[0].click();
  39. }
  40. /** Gets the selector that can be used to find the timepicker's panel. */
  41. async _getPanelSelector() {
  42. return `#${await (await this.host()).getAttribute('mat-timepicker-panel-id')}`;
  43. }
  44. }
  45. /** Harness for interacting with a standard Material timepicker inputs in tests. */
  46. class MatTimepickerInputHarness extends ComponentHarness {
  47. _documentRootLocator = this.documentRootLocatorFactory();
  48. static hostSelector = '.mat-timepicker-input';
  49. /**
  50. * Gets a `HarnessPredicate` that can be used to search for a `MatTimepickerInputHarness`
  51. * that meets certain criteria.
  52. * @param options Options for filtering which input instances are considered a match.
  53. * @return a `HarnessPredicate` configured with the given options.
  54. */
  55. static with(options = {}) {
  56. return new HarnessPredicate(this, options)
  57. .addOption('value', options.value, (harness, value) => {
  58. return HarnessPredicate.stringMatches(harness.getValue(), value);
  59. })
  60. .addOption('placeholder', options.placeholder, (harness, placeholder) => {
  61. return HarnessPredicate.stringMatches(harness.getPlaceholder(), placeholder);
  62. });
  63. }
  64. /** Gets whether the timepicker associated with the input is open. */
  65. async isTimepickerOpen() {
  66. const host = await this.host();
  67. return (await host.getAttribute('aria-expanded')) === 'true';
  68. }
  69. /** Opens the timepicker associated with the input and returns the timepicker instance. */
  70. async openTimepicker() {
  71. if (!(await this.isDisabled())) {
  72. const host = await this.host();
  73. await host.sendKeys(TestKey.DOWN_ARROW);
  74. }
  75. return this.getTimepicker();
  76. }
  77. /** Closes the timepicker associated with the input. */
  78. async closeTimepicker() {
  79. await this._documentRootLocator.rootElement.click();
  80. // This is necessary so that we wait for the closing animation.
  81. await this.forceStabilize();
  82. }
  83. /**
  84. * Gets the `MatTimepickerHarness` that is associated with the input.
  85. * @param filter Optionally filters which timepicker is included.
  86. */
  87. async getTimepicker(filter = {}) {
  88. const host = await this.host();
  89. const timepickerId = await host.getAttribute('mat-timepicker-id');
  90. if (!timepickerId) {
  91. throw Error('Element is not associated with a timepicker');
  92. }
  93. return this._documentRootLocator.locatorFor(MatTimepickerHarness.with({
  94. ...filter,
  95. selector: `[mat-timepicker-panel-id="${timepickerId}"]`,
  96. }))();
  97. }
  98. /** Whether the input is disabled. */
  99. async isDisabled() {
  100. return (await this.host()).getProperty('disabled');
  101. }
  102. /** Whether the input is required. */
  103. async isRequired() {
  104. return (await this.host()).getProperty('required');
  105. }
  106. /** Gets the value of the input. */
  107. async getValue() {
  108. // The "value" property of the native input is always defined.
  109. return await (await this.host()).getProperty('value');
  110. }
  111. /**
  112. * Sets the value of the input. The value will be set by simulating
  113. * keypresses that correspond to the given value.
  114. */
  115. async setValue(newValue) {
  116. const inputEl = await this.host();
  117. await inputEl.clear();
  118. // We don't want to send keys for the value if the value is an empty
  119. // string in order to clear the value. Sending keys with an empty string
  120. // still results in unnecessary focus events.
  121. if (newValue) {
  122. await inputEl.sendKeys(newValue);
  123. }
  124. }
  125. /** Gets the placeholder of the input. */
  126. async getPlaceholder() {
  127. return await (await this.host()).getProperty('placeholder');
  128. }
  129. /**
  130. * Focuses the input and returns a promise that indicates when the
  131. * action is complete.
  132. */
  133. async focus() {
  134. return (await this.host()).focus();
  135. }
  136. /**
  137. * Blurs the input and returns a promise that indicates when the
  138. * action is complete.
  139. */
  140. async blur() {
  141. return (await this.host()).blur();
  142. }
  143. /** Whether the input is focused. */
  144. async isFocused() {
  145. return (await this.host()).isFocused();
  146. }
  147. }
  148. /** Harness for interacting with a standard Material timepicker toggle in tests. */
  149. class MatTimepickerToggleHarness extends ComponentHarness {
  150. static hostSelector = '.mat-timepicker-toggle';
  151. /** The clickable button inside the toggle. */
  152. _button = this.locatorFor('button');
  153. /**
  154. * Gets a `HarnessPredicate` that can be used to search for a `MatTimepickerToggleHarness` that
  155. * meets certain criteria.
  156. * @param options Options for filtering which timepicker toggle instances are considered a match.
  157. * @return a `HarnessPredicate` configured with the given options.
  158. */
  159. static with(options = {}) {
  160. return new HarnessPredicate(MatTimepickerToggleHarness, options);
  161. }
  162. /** Opens the timepicker associated with the toggle. */
  163. async openTimepicker() {
  164. const isOpen = await this.isTimepickerOpen();
  165. if (!isOpen) {
  166. const button = await this._button();
  167. await button.click();
  168. }
  169. }
  170. /** Gets whether the timepicker associated with the toggle is open. */
  171. async isTimepickerOpen() {
  172. const button = await this._button();
  173. const ariaExpanded = await button.getAttribute('aria-expanded');
  174. return ariaExpanded === 'true';
  175. }
  176. /** Whether the toggle is disabled. */
  177. async isDisabled() {
  178. const button = await this._button();
  179. return coerceBooleanProperty(await button.getAttribute('disabled'));
  180. }
  181. }
  182. export { MatTimepickerHarness, MatTimepickerInputHarness, MatTimepickerToggleHarness };
  183. //# sourceMappingURL=testing.mjs.map