@angular/material 21.0.0-next.8 → 21.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/core/tokens/_classes.scss +1 -1
  2. package/core/tokens/m2/_md-sys-color.scss +17 -17
  3. package/fesm2022/_animation-chunk.mjs +10 -16
  4. package/fesm2022/_animation-chunk.mjs.map +1 -1
  5. package/fesm2022/_date-formats-chunk.mjs +68 -164
  6. package/fesm2022/_date-formats-chunk.mjs.map +1 -1
  7. package/fesm2022/_date-range-input-harness-chunk.mjs +284 -463
  8. package/fesm2022/_date-range-input-harness-chunk.mjs.map +1 -1
  9. package/fesm2022/_error-options-chunk.mjs +56 -19
  10. package/fesm2022/_error-options-chunk.mjs.map +1 -1
  11. package/fesm2022/_error-state-chunk.mjs +24 -31
  12. package/fesm2022/_error-state-chunk.mjs.map +1 -1
  13. package/fesm2022/_form-field-chunk.mjs +1224 -1017
  14. package/fesm2022/_form-field-chunk.mjs.map +1 -1
  15. package/fesm2022/_icon-button-chunk.mjs +243 -187
  16. package/fesm2022/_icon-button-chunk.mjs.map +1 -1
  17. package/fesm2022/_icon-registry-chunk.mjs +350 -575
  18. package/fesm2022/_icon-registry-chunk.mjs.map +1 -1
  19. package/fesm2022/_input-harness-chunk.mjs +56 -107
  20. package/fesm2022/_input-harness-chunk.mjs.map +1 -1
  21. package/fesm2022/_input-value-accessor-chunk.mjs +0 -6
  22. package/fesm2022/_input-value-accessor-chunk.mjs.map +1 -1
  23. package/fesm2022/_internal-form-field-chunk.mjs +59 -19
  24. package/fesm2022/_internal-form-field-chunk.mjs.map +1 -1
  25. package/fesm2022/_line-chunk.mjs +83 -43
  26. package/fesm2022/_line-chunk.mjs.map +1 -1
  27. package/fesm2022/_option-chunk.mjs +348 -311
  28. package/fesm2022/_option-chunk.mjs.map +1 -1
  29. package/fesm2022/_option-harness-chunk.mjs +23 -39
  30. package/fesm2022/_option-harness-chunk.mjs.map +1 -1
  31. package/fesm2022/_option-module-chunk.mjs +36 -10
  32. package/fesm2022/_option-module-chunk.mjs.map +1 -1
  33. package/fesm2022/_pseudo-checkbox-chunk.mjs +79 -44
  34. package/fesm2022/_pseudo-checkbox-chunk.mjs.map +1 -1
  35. package/fesm2022/_pseudo-checkbox-module-chunk.mjs +36 -10
  36. package/fesm2022/_pseudo-checkbox-module-chunk.mjs.map +1 -1
  37. package/fesm2022/_public-api-chunk.mjs +71 -134
  38. package/fesm2022/_public-api-chunk.mjs.map +1 -1
  39. package/fesm2022/_ripple-chunk.mjs +504 -600
  40. package/fesm2022/_ripple-chunk.mjs.map +1 -1
  41. package/fesm2022/_ripple-loader-chunk.mjs +120 -138
  42. package/fesm2022/_ripple-loader-chunk.mjs.map +1 -1
  43. package/fesm2022/_ripple-module-chunk.mjs +36 -10
  44. package/fesm2022/_ripple-module-chunk.mjs.map +1 -1
  45. package/fesm2022/_structural-styles-chunk.mjs +37 -10
  46. package/fesm2022/_structural-styles-chunk.mjs.map +1 -1
  47. package/fesm2022/_tooltip-chunk.mjs +810 -888
  48. package/fesm2022/_tooltip-chunk.mjs.map +1 -1
  49. package/fesm2022/autocomplete-testing.mjs +62 -86
  50. package/fesm2022/autocomplete-testing.mjs.map +1 -1
  51. package/fesm2022/autocomplete.mjs +965 -1126
  52. package/fesm2022/autocomplete.mjs.map +1 -1
  53. package/fesm2022/badge-testing.mjs +38 -54
  54. package/fesm2022/badge-testing.mjs.map +1 -1
  55. package/fesm2022/badge.mjs +321 -272
  56. package/fesm2022/badge.mjs.map +1 -1
  57. package/fesm2022/bottom-sheet-testing.mjs +10 -24
  58. package/fesm2022/bottom-sheet-testing.mjs.map +1 -1
  59. package/fesm2022/bottom-sheet.mjs +349 -344
  60. package/fesm2022/bottom-sheet.mjs.map +1 -1
  61. package/fesm2022/button-testing.mjs +60 -94
  62. package/fesm2022/button-testing.mjs.map +1 -1
  63. package/fesm2022/button-toggle-testing.mjs +76 -125
  64. package/fesm2022/button-toggle-testing.mjs.map +1 -1
  65. package/fesm2022/button-toggle.mjs +752 -662
  66. package/fesm2022/button-toggle.mjs.map +1 -1
  67. package/fesm2022/button.mjs +263 -158
  68. package/fesm2022/button.mjs.map +1 -1
  69. package/fesm2022/card-testing.mjs +19 -33
  70. package/fesm2022/card-testing.mjs.map +1 -1
  71. package/fesm2022/card.mjs +576 -272
  72. package/fesm2022/card.mjs.map +1 -1
  73. package/fesm2022/checkbox-testing.mjs +71 -123
  74. package/fesm2022/checkbox-testing.mjs.map +1 -1
  75. package/fesm2022/checkbox.mjs +515 -477
  76. package/fesm2022/checkbox.mjs.map +1 -1
  77. package/fesm2022/chips-testing.mjs +201 -350
  78. package/fesm2022/chips-testing.mjs.map +1 -1
  79. package/fesm2022/chips.mjs +2552 -2289
  80. package/fesm2022/chips.mjs.map +1 -1
  81. package/fesm2022/core-testing.mjs +14 -28
  82. package/fesm2022/core-testing.mjs.map +1 -1
  83. package/fesm2022/core.mjs +357 -328
  84. package/fesm2022/core.mjs.map +1 -1
  85. package/fesm2022/datepicker-testing.mjs +15 -25
  86. package/fesm2022/datepicker-testing.mjs.map +1 -1
  87. package/fesm2022/datepicker.mjs +4826 -4563
  88. package/fesm2022/datepicker.mjs.map +1 -1
  89. package/fesm2022/dialog-testing.mjs +93 -129
  90. package/fesm2022/dialog-testing.mjs.map +1 -1
  91. package/fesm2022/dialog.mjs +810 -829
  92. package/fesm2022/dialog.mjs.map +1 -1
  93. package/fesm2022/divider-testing.mjs +10 -11
  94. package/fesm2022/divider-testing.mjs.map +1 -1
  95. package/fesm2022/divider.mjs +119 -43
  96. package/fesm2022/divider.mjs.map +1 -1
  97. package/fesm2022/expansion-testing.mjs +74 -130
  98. package/fesm2022/expansion-testing.mjs.map +1 -1
  99. package/fesm2022/expansion.mjs +703 -515
  100. package/fesm2022/expansion.mjs.map +1 -1
  101. package/fesm2022/form-field-testing-control.mjs +16 -33
  102. package/fesm2022/form-field-testing-control.mjs.map +1 -1
  103. package/fesm2022/form-field-testing.mjs +118 -179
  104. package/fesm2022/form-field-testing.mjs.map +1 -1
  105. package/fesm2022/form-field.mjs +36 -10
  106. package/fesm2022/form-field.mjs.map +1 -1
  107. package/fesm2022/grid-list-testing.mjs +65 -113
  108. package/fesm2022/grid-list-testing.mjs.map +1 -1
  109. package/fesm2022/grid-list.mjs +559 -494
  110. package/fesm2022/grid-list.mjs.map +1 -1
  111. package/fesm2022/icon-testing.mjs +148 -127
  112. package/fesm2022/icon-testing.mjs.map +1 -1
  113. package/fesm2022/icon.mjs +325 -351
  114. package/fesm2022/icon.mjs.map +1 -1
  115. package/fesm2022/input-testing.mjs +59 -99
  116. package/fesm2022/input-testing.mjs.map +1 -1
  117. package/fesm2022/input.mjs +457 -520
  118. package/fesm2022/input.mjs.map +1 -1
  119. package/fesm2022/list-testing.mjs +251 -434
  120. package/fesm2022/list-testing.mjs.map +1 -1
  121. package/fesm2022/list.mjs +1522 -1204
  122. package/fesm2022/list.mjs.map +1 -1
  123. package/fesm2022/material.mjs +0 -5
  124. package/fesm2022/material.mjs.map +1 -1
  125. package/fesm2022/menu-testing.mjs +159 -228
  126. package/fesm2022/menu-testing.mjs.map +1 -1
  127. package/fesm2022/menu.mjs +1338 -1343
  128. package/fesm2022/menu.mjs.map +1 -1
  129. package/fesm2022/paginator-testing.mjs +55 -79
  130. package/fesm2022/paginator-testing.mjs.map +1 -1
  131. package/fesm2022/paginator.mjs +381 -309
  132. package/fesm2022/paginator.mjs.map +1 -1
  133. package/fesm2022/progress-bar-testing.mjs +12 -21
  134. package/fesm2022/progress-bar-testing.mjs.map +1 -1
  135. package/fesm2022/progress-bar.mjs +224 -169
  136. package/fesm2022/progress-bar.mjs.map +1 -1
  137. package/fesm2022/progress-spinner-testing.mjs +13 -23
  138. package/fesm2022/progress-spinner-testing.mjs.map +1 -1
  139. package/fesm2022/progress-spinner.mjs +235 -160
  140. package/fesm2022/progress-spinner.mjs.map +1 -1
  141. package/fesm2022/radio-testing.mjs +133 -208
  142. package/fesm2022/radio-testing.mjs.map +1 -1
  143. package/fesm2022/radio.mjs +712 -679
  144. package/fesm2022/radio.mjs.map +1 -1
  145. package/fesm2022/select-testing.mjs +83 -117
  146. package/fesm2022/select-testing.mjs.map +1 -1
  147. package/fesm2022/select.mjs +1116 -1246
  148. package/fesm2022/select.mjs.map +1 -1
  149. package/fesm2022/sidenav-testing.mjs +54 -120
  150. package/fesm2022/sidenav-testing.mjs.map +1 -1
  151. package/fesm2022/sidenav.mjs +1078 -995
  152. package/fesm2022/sidenav.mjs.map +1 -1
  153. package/fesm2022/slide-toggle-testing.mjs +57 -92
  154. package/fesm2022/slide-toggle-testing.mjs.map +1 -1
  155. package/fesm2022/slide-toggle.mjs +369 -279
  156. package/fesm2022/slide-toggle.mjs.map +1 -1
  157. package/fesm2022/slider-testing.mjs +90 -138
  158. package/fesm2022/slider-testing.mjs.map +1 -1
  159. package/fesm2022/slider.mjs +1651 -1716
  160. package/fesm2022/slider.mjs.map +1 -1
  161. package/fesm2022/snack-bar-testing.mjs +40 -87
  162. package/fesm2022/snack-bar-testing.mjs.map +1 -1
  163. package/fesm2022/snack-bar.mjs +763 -714
  164. package/fesm2022/snack-bar.mjs.map +1 -1
  165. package/fesm2022/sort-testing.mjs +45 -66
  166. package/fesm2022/sort-testing.mjs.map +1 -1
  167. package/fesm2022/sort.mjs +419 -344
  168. package/fesm2022/sort.mjs.map +1 -1
  169. package/fesm2022/stepper-testing.mjs +78 -154
  170. package/fesm2022/stepper-testing.mjs.map +1 -1
  171. package/fesm2022/stepper.mjs +790 -498
  172. package/fesm2022/stepper.mjs.map +1 -1
  173. package/fesm2022/table-testing.mjs +125 -186
  174. package/fesm2022/table-testing.mjs.map +1 -1
  175. package/fesm2022/table.mjs +1026 -684
  176. package/fesm2022/table.mjs.map +1 -1
  177. package/fesm2022/tabs-testing.mjs +125 -197
  178. package/fesm2022/tabs-testing.mjs.map +1 -1
  179. package/fesm2022/tabs.mjs +2351 -2028
  180. package/fesm2022/tabs.mjs.map +1 -1
  181. package/fesm2022/timepicker-testing.mjs +113 -172
  182. package/fesm2022/timepicker-testing.mjs.map +1 -1
  183. package/fesm2022/timepicker.mjs +1019 -826
  184. package/fesm2022/timepicker.mjs.map +1 -1
  185. package/fesm2022/toolbar-testing.mjs +16 -27
  186. package/fesm2022/toolbar-testing.mjs.map +1 -1
  187. package/fesm2022/toolbar.mjs +163 -78
  188. package/fesm2022/toolbar.mjs.map +1 -1
  189. package/fesm2022/tooltip-testing.mjs +41 -52
  190. package/fesm2022/tooltip-testing.mjs.map +1 -1
  191. package/fesm2022/tooltip.mjs +36 -10
  192. package/fesm2022/tooltip.mjs.map +1 -1
  193. package/fesm2022/tree-testing.mjs +86 -162
  194. package/fesm2022/tree-testing.mjs.map +1 -1
  195. package/fesm2022/tree.mjs +638 -466
  196. package/fesm2022/tree.mjs.map +1 -1
  197. package/package.json +2 -2
  198. package/schematics/ng-add/index.js +1 -1
  199. package/types/expansion.d.ts +4 -2
  200. package/types/menu-testing.d.ts +2 -0
  201. package/types/select.d.ts +1 -1
  202. package/types/sort.d.ts +1 -1
  203. package/types/table-testing.d.ts +27 -1
  204. package/types/timepicker.d.ts +148 -128
@@ -1,500 +1,321 @@
1
1
  import { HarnessPredicate, ComponentHarness, parallel, TestKey } from '@angular/cdk/testing';
2
2
  import { MatFormFieldControlHarnessBase } from '@angular/material/form-field/testing/control';
3
3
 
4
- /** Sets up the filter predicates for a datepicker input harness. */
5
4
  function getInputPredicate(type, options) {
6
- return new HarnessPredicate(type, options)
7
- .addOption('value', options.value, (harness, value) => {
8
- return HarnessPredicate.stringMatches(harness.getValue(), value);
9
- })
10
- .addOption('placeholder', options.placeholder, (harness, placeholder) => {
11
- return HarnessPredicate.stringMatches(harness.getPlaceholder(), placeholder);
12
- })
13
- .addOption('label', options.label, (harness, label) => {
14
- return HarnessPredicate.stringMatches(harness.getLabel(), label);
15
- });
5
+ return new HarnessPredicate(type, options).addOption('value', options.value, (harness, value) => {
6
+ return HarnessPredicate.stringMatches(harness.getValue(), value);
7
+ }).addOption('placeholder', options.placeholder, (harness, placeholder) => {
8
+ return HarnessPredicate.stringMatches(harness.getPlaceholder(), placeholder);
9
+ }).addOption('label', options.label, (harness, label) => {
10
+ return HarnessPredicate.stringMatches(harness.getLabel(), label);
11
+ });
16
12
  }
17
- /** Base class for datepicker input harnesses. */
18
13
  class MatDatepickerInputHarnessBase extends MatFormFieldControlHarnessBase {
19
- /** Whether the input is disabled. */
20
- async isDisabled() {
21
- return (await this.host()).getProperty('disabled');
22
- }
23
- /** Whether the input is required. */
24
- async isRequired() {
25
- return (await this.host()).getProperty('required');
26
- }
27
- /** Gets the value of the input. */
28
- async getValue() {
29
- // The "value" property of the native input is always defined.
30
- return await (await this.host()).getProperty('value');
31
- }
32
- /**
33
- * Sets the value of the input. The value will be set by simulating
34
- * keypresses that correspond to the given value.
35
- */
36
- async setValue(newValue) {
37
- const inputEl = await this.host();
38
- await inputEl.clear();
39
- // We don't want to send keys for the value if the value is an empty
40
- // string in order to clear the value. Sending keys with an empty string
41
- // still results in unnecessary focus events.
42
- if (newValue) {
43
- await inputEl.sendKeys(newValue);
44
- }
45
- await inputEl.dispatchEvent('change');
46
- }
47
- /** Gets the placeholder of the input. */
48
- async getPlaceholder() {
49
- return await (await this.host()).getProperty('placeholder');
50
- }
51
- /**
52
- * Focuses the input and returns a promise that indicates when the
53
- * action is complete.
54
- */
55
- async focus() {
56
- return (await this.host()).focus();
57
- }
58
- /**
59
- * Blurs the input and returns a promise that indicates when the
60
- * action is complete.
61
- */
62
- async blur() {
63
- return (await this.host()).blur();
64
- }
65
- /** Whether the input is focused. */
66
- async isFocused() {
67
- return (await this.host()).isFocused();
68
- }
69
- /** Gets the formatted minimum date for the input's value. */
70
- async getMin() {
71
- return (await this.host()).getAttribute('min');
72
- }
73
- /** Gets the formatted maximum date for the input's value. */
74
- async getMax() {
75
- return (await this.host()).getAttribute('max');
76
- }
14
+ async isDisabled() {
15
+ return (await this.host()).getProperty('disabled');
16
+ }
17
+ async isRequired() {
18
+ return (await this.host()).getProperty('required');
19
+ }
20
+ async getValue() {
21
+ return await (await this.host()).getProperty('value');
22
+ }
23
+ async setValue(newValue) {
24
+ const inputEl = await this.host();
25
+ await inputEl.clear();
26
+ if (newValue) {
27
+ await inputEl.sendKeys(newValue);
28
+ }
29
+ await inputEl.dispatchEvent('change');
30
+ }
31
+ async getPlaceholder() {
32
+ return await (await this.host()).getProperty('placeholder');
33
+ }
34
+ async focus() {
35
+ return (await this.host()).focus();
36
+ }
37
+ async blur() {
38
+ return (await this.host()).blur();
39
+ }
40
+ async isFocused() {
41
+ return (await this.host()).isFocused();
42
+ }
43
+ async getMin() {
44
+ return (await this.host()).getAttribute('min');
45
+ }
46
+ async getMax() {
47
+ return (await this.host()).getAttribute('max');
48
+ }
77
49
  }
78
50
 
79
- /** Harness for interacting with a standard Material calendar cell in tests. */
80
51
  class MatCalendarCellHarness extends ComponentHarness {
81
- static hostSelector = '.mat-calendar-body-cell';
82
- /** Reference to the inner content element inside the cell. */
83
- _content = this.locatorFor('.mat-calendar-body-cell-content');
84
- /**
85
- * Gets a `HarnessPredicate` that can be used to search for a `MatCalendarCellHarness`
86
- * that meets certain criteria.
87
- * @param options Options for filtering which cell instances are considered a match.
88
- * @return a `HarnessPredicate` configured with the given options.
89
- */
90
- static with(options = {}) {
91
- return new HarnessPredicate(MatCalendarCellHarness, options)
92
- .addOption('text', options.text, (harness, text) => {
93
- return HarnessPredicate.stringMatches(harness.getText(), text);
94
- })
95
- .addOption('selected', options.selected, async (harness, selected) => {
96
- return (await harness.isSelected()) === selected;
97
- })
98
- .addOption('active', options.active, async (harness, active) => {
99
- return (await harness.isActive()) === active;
100
- })
101
- .addOption('disabled', options.disabled, async (harness, disabled) => {
102
- return (await harness.isDisabled()) === disabled;
103
- })
104
- .addOption('today', options.today, async (harness, today) => {
105
- return (await harness.isToday()) === today;
106
- })
107
- .addOption('inRange', options.inRange, async (harness, inRange) => {
108
- return (await harness.isInRange()) === inRange;
109
- })
110
- .addOption('inComparisonRange', options.inComparisonRange, async (harness, inComparisonRange) => {
111
- return (await harness.isInComparisonRange()) === inComparisonRange;
112
- })
113
- .addOption('inPreviewRange', options.inPreviewRange, async (harness, inPreviewRange) => {
114
- return (await harness.isInPreviewRange()) === inPreviewRange;
115
- });
116
- }
117
- /** Gets the text of the calendar cell. */
118
- async getText() {
119
- return (await this._content()).text();
120
- }
121
- /** Gets the aria-label of the calendar cell. */
122
- async getAriaLabel() {
123
- // We're guaranteed for the `aria-label` to be defined
124
- // since this is a private element that we control.
125
- return (await this.host()).getAttribute('aria-label');
126
- }
127
- /** Whether the cell is selected. */
128
- async isSelected() {
129
- const host = await this.host();
130
- return (await host.getAttribute('aria-pressed')) === 'true';
131
- }
132
- /** Whether the cell is disabled. */
133
- async isDisabled() {
134
- return this._hasState('disabled');
135
- }
136
- /** Whether the cell is currently activated using keyboard navigation. */
137
- async isActive() {
138
- return this._hasState('active');
139
- }
140
- /** Whether the cell represents today's date. */
141
- async isToday() {
142
- return (await this._content()).hasClass('mat-calendar-body-today');
143
- }
144
- /** Selects the calendar cell. Won't do anything if the cell is disabled. */
145
- async select() {
146
- return (await this.host()).click();
147
- }
148
- /** Hovers over the calendar cell. */
149
- async hover() {
150
- return (await this.host()).hover();
151
- }
152
- /** Moves the mouse away from the calendar cell. */
153
- async mouseAway() {
154
- return (await this.host()).mouseAway();
155
- }
156
- /** Focuses the calendar cell. */
157
- async focus() {
158
- return (await this.host()).focus();
159
- }
160
- /** Removes focus from the calendar cell. */
161
- async blur() {
162
- return (await this.host()).blur();
163
- }
164
- /** Whether the cell is the start of the main range. */
165
- async isRangeStart() {
166
- return this._hasState('range-start');
167
- }
168
- /** Whether the cell is the end of the main range. */
169
- async isRangeEnd() {
170
- return this._hasState('range-end');
171
- }
172
- /** Whether the cell is part of the main range. */
173
- async isInRange() {
174
- return this._hasState('in-range');
175
- }
176
- /** Whether the cell is the start of the comparison range. */
177
- async isComparisonRangeStart() {
178
- return this._hasState('comparison-start');
179
- }
180
- /** Whether the cell is the end of the comparison range. */
181
- async isComparisonRangeEnd() {
182
- return this._hasState('comparison-end');
183
- }
184
- /** Whether the cell is inside of the comparison range. */
185
- async isInComparisonRange() {
186
- return this._hasState('in-comparison-range');
187
- }
188
- /** Whether the cell is the start of the preview range. */
189
- async isPreviewRangeStart() {
190
- return this._hasState('preview-start');
191
- }
192
- /** Whether the cell is the end of the preview range. */
193
- async isPreviewRangeEnd() {
194
- return this._hasState('preview-end');
195
- }
196
- /** Whether the cell is inside of the preview range. */
197
- async isInPreviewRange() {
198
- return this._hasState('in-preview');
199
- }
200
- /** Returns whether the cell has a particular CSS class-based state. */
201
- async _hasState(name) {
202
- return (await this.host()).hasClass(`mat-calendar-body-${name}`);
203
- }
52
+ static hostSelector = '.mat-calendar-body-cell';
53
+ _content = this.locatorFor('.mat-calendar-body-cell-content');
54
+ static with(options = {}) {
55
+ return new HarnessPredicate(MatCalendarCellHarness, options).addOption('text', options.text, (harness, text) => {
56
+ return HarnessPredicate.stringMatches(harness.getText(), text);
57
+ }).addOption('selected', options.selected, async (harness, selected) => {
58
+ return (await harness.isSelected()) === selected;
59
+ }).addOption('active', options.active, async (harness, active) => {
60
+ return (await harness.isActive()) === active;
61
+ }).addOption('disabled', options.disabled, async (harness, disabled) => {
62
+ return (await harness.isDisabled()) === disabled;
63
+ }).addOption('today', options.today, async (harness, today) => {
64
+ return (await harness.isToday()) === today;
65
+ }).addOption('inRange', options.inRange, async (harness, inRange) => {
66
+ return (await harness.isInRange()) === inRange;
67
+ }).addOption('inComparisonRange', options.inComparisonRange, async (harness, inComparisonRange) => {
68
+ return (await harness.isInComparisonRange()) === inComparisonRange;
69
+ }).addOption('inPreviewRange', options.inPreviewRange, async (harness, inPreviewRange) => {
70
+ return (await harness.isInPreviewRange()) === inPreviewRange;
71
+ });
72
+ }
73
+ async getText() {
74
+ return (await this._content()).text();
75
+ }
76
+ async getAriaLabel() {
77
+ return (await this.host()).getAttribute('aria-label');
78
+ }
79
+ async isSelected() {
80
+ const host = await this.host();
81
+ return (await host.getAttribute('aria-pressed')) === 'true';
82
+ }
83
+ async isDisabled() {
84
+ return this._hasState('disabled');
85
+ }
86
+ async isActive() {
87
+ return this._hasState('active');
88
+ }
89
+ async isToday() {
90
+ return (await this._content()).hasClass('mat-calendar-body-today');
91
+ }
92
+ async select() {
93
+ return (await this.host()).click();
94
+ }
95
+ async hover() {
96
+ return (await this.host()).hover();
97
+ }
98
+ async mouseAway() {
99
+ return (await this.host()).mouseAway();
100
+ }
101
+ async focus() {
102
+ return (await this.host()).focus();
103
+ }
104
+ async blur() {
105
+ return (await this.host()).blur();
106
+ }
107
+ async isRangeStart() {
108
+ return this._hasState('range-start');
109
+ }
110
+ async isRangeEnd() {
111
+ return this._hasState('range-end');
112
+ }
113
+ async isInRange() {
114
+ return this._hasState('in-range');
115
+ }
116
+ async isComparisonRangeStart() {
117
+ return this._hasState('comparison-start');
118
+ }
119
+ async isComparisonRangeEnd() {
120
+ return this._hasState('comparison-end');
121
+ }
122
+ async isInComparisonRange() {
123
+ return this._hasState('in-comparison-range');
124
+ }
125
+ async isPreviewRangeStart() {
126
+ return this._hasState('preview-start');
127
+ }
128
+ async isPreviewRangeEnd() {
129
+ return this._hasState('preview-end');
130
+ }
131
+ async isInPreviewRange() {
132
+ return this._hasState('in-preview');
133
+ }
134
+ async _hasState(name) {
135
+ return (await this.host()).hasClass(`mat-calendar-body-${name}`);
136
+ }
204
137
  }
205
138
 
206
- /** Possible views of a `MatCalendarHarness`. */
207
139
  var CalendarView;
208
140
  (function (CalendarView) {
209
- CalendarView[CalendarView["MONTH"] = 0] = "MONTH";
210
- CalendarView[CalendarView["YEAR"] = 1] = "YEAR";
211
- CalendarView[CalendarView["MULTI_YEAR"] = 2] = "MULTI_YEAR";
141
+ CalendarView[CalendarView["MONTH"] = 0] = "MONTH";
142
+ CalendarView[CalendarView["YEAR"] = 1] = "YEAR";
143
+ CalendarView[CalendarView["MULTI_YEAR"] = 2] = "MULTI_YEAR";
212
144
  })(CalendarView || (CalendarView = {}));
213
- /** Harness for interacting with a standard Material calendar in tests. */
214
145
  class MatCalendarHarness extends ComponentHarness {
215
- static hostSelector = '.mat-calendar';
216
- /** Queries for the calendar's period toggle button. */
217
- _periodButton = this.locatorFor('.mat-calendar-period-button');
218
- /**
219
- * Gets a `HarnessPredicate` that can be used to search for a `MatCalendarHarness`
220
- * that meets certain criteria.
221
- * @param options Options for filtering which calendar instances are considered a match.
222
- * @return a `HarnessPredicate` configured with the given options.
223
- */
224
- static with(options = {}) {
225
- return new HarnessPredicate(MatCalendarHarness, options);
226
- }
227
- /**
228
- * Gets a list of cells inside the calendar.
229
- * @param filter Optionally filters which cells are included.
230
- */
231
- async getCells(filter = {}) {
232
- return this.locatorForAll(MatCalendarCellHarness.with(filter))();
233
- }
234
- /** Gets the current view that is being shown inside the calendar. */
235
- async getCurrentView() {
236
- if (await this.locatorForOptional('mat-multi-year-view')()) {
237
- return CalendarView.MULTI_YEAR;
238
- }
239
- if (await this.locatorForOptional('mat-year-view')()) {
240
- return CalendarView.YEAR;
241
- }
242
- return CalendarView.MONTH;
243
- }
244
- /** Gets the label of the current calendar view. */
245
- async getCurrentViewLabel() {
246
- return (await this._periodButton()).text();
247
- }
248
- /** Changes the calendar view by clicking on the view toggle button. */
249
- async changeView() {
250
- return (await this._periodButton()).click();
251
- }
252
- /** Goes to the next page of the current view (e.g. next month when inside the month view). */
253
- async next() {
254
- return (await this.locatorFor('.mat-calendar-next-button')()).click();
255
- }
256
- /**
257
- * Goes to the previous page of the current view
258
- * (e.g. previous month when inside the month view).
259
- */
260
- async previous() {
261
- return (await this.locatorFor('.mat-calendar-previous-button')()).click();
262
- }
263
- /**
264
- * Selects a cell in the current calendar view.
265
- * @param filter An optional filter to apply to the cells. The first cell matching the filter
266
- * will be selected.
267
- */
268
- async selectCell(filter = {}) {
269
- const cells = await this.getCells(filter);
270
- if (!cells.length) {
271
- throw Error(`Cannot find calendar cell matching filter ${JSON.stringify(filter)}`);
272
- }
273
- await cells[0].select();
274
- }
146
+ static hostSelector = '.mat-calendar';
147
+ _periodButton = this.locatorFor('.mat-calendar-period-button');
148
+ static with(options = {}) {
149
+ return new HarnessPredicate(MatCalendarHarness, options);
150
+ }
151
+ async getCells(filter = {}) {
152
+ return this.locatorForAll(MatCalendarCellHarness.with(filter))();
153
+ }
154
+ async getCurrentView() {
155
+ if (await this.locatorForOptional('mat-multi-year-view')()) {
156
+ return CalendarView.MULTI_YEAR;
157
+ }
158
+ if (await this.locatorForOptional('mat-year-view')()) {
159
+ return CalendarView.YEAR;
160
+ }
161
+ return CalendarView.MONTH;
162
+ }
163
+ async getCurrentViewLabel() {
164
+ return (await this._periodButton()).text();
165
+ }
166
+ async changeView() {
167
+ return (await this._periodButton()).click();
168
+ }
169
+ async next() {
170
+ return (await this.locatorFor('.mat-calendar-next-button')()).click();
171
+ }
172
+ async previous() {
173
+ return (await this.locatorFor('.mat-calendar-previous-button')()).click();
174
+ }
175
+ async selectCell(filter = {}) {
176
+ const cells = await this.getCells(filter);
177
+ if (!cells.length) {
178
+ throw Error(`Cannot find calendar cell matching filter ${JSON.stringify(filter)}`);
179
+ }
180
+ await cells[0].select();
181
+ }
275
182
  }
276
183
 
277
- /** Base class for harnesses that can trigger a calendar. */
278
184
  class DatepickerTriggerHarnessBase extends ComponentHarness {
279
- /** Opens the calendar if the trigger is enabled and it has a calendar. */
280
- async openCalendar() {
281
- const [isDisabled, hasCalendar] = await parallel(() => [this.isDisabled(), this.hasCalendar()]);
282
- if (!isDisabled && hasCalendar) {
283
- return this._openCalendar();
284
- }
285
- }
286
- /** Closes the calendar if it is open. */
287
- async closeCalendar() {
288
- if (await this.isCalendarOpen()) {
289
- await closeCalendar(getCalendarId(this.host()), this.documentRootLocatorFactory());
290
- // This is necessary so that we wait for the closing animation to finish in touch UI mode.
291
- await this.forceStabilize();
292
- }
293
- }
294
- /** Gets whether there is a calendar associated with the trigger. */
295
- async hasCalendar() {
296
- return (await getCalendarId(this.host())) != null;
297
- }
298
- /**
299
- * Gets the `MatCalendarHarness` that is associated with the trigger.
300
- * @param filter Optionally filters which calendar is included.
301
- */
302
- async getCalendar(filter = {}) {
303
- return getCalendar(filter, this.host(), this.documentRootLocatorFactory());
304
- }
185
+ async openCalendar() {
186
+ const [isDisabled, hasCalendar] = await parallel(() => [this.isDisabled(), this.hasCalendar()]);
187
+ if (!isDisabled && hasCalendar) {
188
+ return this._openCalendar();
189
+ }
190
+ }
191
+ async closeCalendar() {
192
+ if (await this.isCalendarOpen()) {
193
+ await closeCalendar(getCalendarId(this.host()), this.documentRootLocatorFactory());
194
+ await this.forceStabilize();
195
+ }
196
+ }
197
+ async hasCalendar() {
198
+ return (await getCalendarId(this.host())) != null;
199
+ }
200
+ async getCalendar(filter = {}) {
201
+ return getCalendar(filter, this.host(), this.documentRootLocatorFactory());
202
+ }
305
203
  }
306
- /** Gets the ID of the calendar that a particular test element can trigger. */
307
204
  async function getCalendarId(host) {
308
- return (await host).getAttribute('data-mat-calendar');
205
+ return (await host).getAttribute('data-mat-calendar');
309
206
  }
310
- /** Closes the calendar with a specific ID. */
311
207
  async function closeCalendar(calendarId, documentLocator) {
312
- // We close the calendar by clicking on the backdrop, even though all datepicker variants
313
- // have the ability to close by pressing escape. The backdrop is preferrable, because the
314
- // escape key has multiple functions inside a range picker (either cancel the current range
315
- // or close the calendar). Since we don't have access to set the ID on the backdrop in all
316
- // cases, we set a unique class instead which is the same as the calendar's ID and suffixed
317
- // with `-backdrop`.
318
- const backdropSelector = `.${await calendarId}-backdrop`;
319
- return (await documentLocator.locatorFor(backdropSelector)()).click();
208
+ const backdropSelector = `.${await calendarId}-backdrop`;
209
+ return (await documentLocator.locatorFor(backdropSelector)()).click();
320
210
  }
321
- /** Gets the test harness for a calendar associated with a particular host. */
322
211
  async function getCalendar(filter, host, documentLocator) {
323
- const calendarId = await getCalendarId(host);
324
- if (!calendarId) {
325
- throw Error(`Element is not associated with a calendar`);
326
- }
327
- return documentLocator.locatorFor(MatCalendarHarness.with({
328
- ...filter,
329
- selector: `#${calendarId}`,
330
- }))();
212
+ const calendarId = await getCalendarId(host);
213
+ if (!calendarId) {
214
+ throw Error(`Element is not associated with a calendar`);
215
+ }
216
+ return documentLocator.locatorFor(MatCalendarHarness.with({
217
+ ...filter,
218
+ selector: `#${calendarId}`
219
+ }))();
331
220
  }
332
221
 
333
- /** Harness for interacting with a standard Material datepicker inputs in tests. */
334
222
  class MatDatepickerInputHarness extends MatDatepickerInputHarnessBase {
335
- static hostSelector = '.mat-datepicker-input';
336
- /**
337
- * Gets a `HarnessPredicate` that can be used to search for a `MatDatepickerInputHarness`
338
- * that meets certain criteria.
339
- * @param options Options for filtering which input instances are considered a match.
340
- * @return a `HarnessPredicate` configured with the given options.
341
- */
342
- static with(options = {}) {
343
- return getInputPredicate(MatDatepickerInputHarness, options);
344
- }
345
- /** Gets whether the calendar associated with the input is open. */
346
- async isCalendarOpen() {
347
- // `aria-owns` is set only if there's an open datepicker so we can use it as an indicator.
348
- const host = await this.host();
349
- return (await host.getAttribute('aria-owns')) != null;
350
- }
351
- /** Opens the calendar associated with the input. */
352
- async openCalendar() {
353
- const [isDisabled, hasCalendar] = await parallel(() => [this.isDisabled(), this.hasCalendar()]);
354
- if (!isDisabled && hasCalendar) {
355
- // Alt + down arrow is the combination for opening the calendar with the keyboard.
356
- const host = await this.host();
357
- return host.sendKeys({ alt: true }, TestKey.DOWN_ARROW);
358
- }
359
- }
360
- /** Closes the calendar associated with the input. */
361
- async closeCalendar() {
362
- if (await this.isCalendarOpen()) {
363
- await closeCalendar(getCalendarId(this.host()), this.documentRootLocatorFactory());
364
- // This is necessary so that we wait for the closing animation to finish in touch UI mode.
365
- await this.forceStabilize();
366
- }
367
- }
368
- /** Whether a calendar is associated with the input. */
369
- async hasCalendar() {
370
- return (await getCalendarId(this.host())) != null;
371
- }
372
- /**
373
- * Gets the `MatCalendarHarness` that is associated with the trigger.
374
- * @param filter Optionally filters which calendar is included.
375
- */
376
- async getCalendar(filter = {}) {
377
- return getCalendar(filter, this.host(), this.documentRootLocatorFactory());
378
- }
223
+ static hostSelector = '.mat-datepicker-input';
224
+ static with(options = {}) {
225
+ return getInputPredicate(MatDatepickerInputHarness, options);
226
+ }
227
+ async isCalendarOpen() {
228
+ const host = await this.host();
229
+ return (await host.getAttribute('aria-owns')) != null;
230
+ }
231
+ async openCalendar() {
232
+ const [isDisabled, hasCalendar] = await parallel(() => [this.isDisabled(), this.hasCalendar()]);
233
+ if (!isDisabled && hasCalendar) {
234
+ const host = await this.host();
235
+ return host.sendKeys({
236
+ alt: true
237
+ }, TestKey.DOWN_ARROW);
238
+ }
239
+ }
240
+ async closeCalendar() {
241
+ if (await this.isCalendarOpen()) {
242
+ await closeCalendar(getCalendarId(this.host()), this.documentRootLocatorFactory());
243
+ await this.forceStabilize();
244
+ }
245
+ }
246
+ async hasCalendar() {
247
+ return (await getCalendarId(this.host())) != null;
248
+ }
249
+ async getCalendar(filter = {}) {
250
+ return getCalendar(filter, this.host(), this.documentRootLocatorFactory());
251
+ }
379
252
  }
380
253
 
381
- /** Harness for interacting with a standard Material date range start input in tests. */
382
254
  class MatStartDateHarness extends MatDatepickerInputHarnessBase {
383
- static hostSelector = '.mat-start-date';
384
- /**
385
- * Gets a `HarnessPredicate` that can be used to search for a `MatStartDateHarness`
386
- * that meets certain criteria.
387
- * @param options Options for filtering which input instances are considered a match.
388
- * @return a `HarnessPredicate` configured with the given options.
389
- */
390
- static with(options = {}) {
391
- return getInputPredicate(MatStartDateHarness, options);
392
- }
255
+ static hostSelector = '.mat-start-date';
256
+ static with(options = {}) {
257
+ return getInputPredicate(MatStartDateHarness, options);
258
+ }
393
259
  }
394
- /** Harness for interacting with a standard Material date range end input in tests. */
395
260
  class MatEndDateHarness extends MatDatepickerInputHarnessBase {
396
- static hostSelector = '.mat-end-date';
397
- /**
398
- * Gets a `HarnessPredicate` that can be used to search for a `MatEndDateHarness`
399
- * that meets certain criteria.
400
- * @param options Options for filtering which input instances are considered a match.
401
- * @return a `HarnessPredicate` configured with the given options.
402
- */
403
- static with(options = {}) {
404
- return getInputPredicate(MatEndDateHarness, options);
405
- }
261
+ static hostSelector = '.mat-end-date';
262
+ static with(options = {}) {
263
+ return getInputPredicate(MatEndDateHarness, options);
264
+ }
406
265
  }
407
- /** Harness for interacting with a standard Material date range input in tests. */
408
266
  class MatDateRangeInputHarness extends DatepickerTriggerHarnessBase {
409
- static hostSelector = '.mat-date-range-input';
410
- /**
411
- * Gets a `HarnessPredicate` that can be used to search for a `MatDateRangeInputHarness`
412
- * that meets certain criteria.
413
- * @param options Options for filtering which input instances are considered a match.
414
- * @return a `HarnessPredicate` configured with the given options.
415
- */
416
- static with(options = {}) {
417
- return new HarnessPredicate(MatDateRangeInputHarness, options)
418
- .addOption('value', options.value, (harness, value) => HarnessPredicate.stringMatches(harness.getValue(), value))
419
- .addOption('label', options.label, (harness, label) => {
420
- return HarnessPredicate.stringMatches(harness.getLabel(), label);
421
- });
422
- }
423
- /** Gets the combined value of the start and end inputs, including the separator. */
424
- async getValue() {
425
- const [start, end, separator] = await parallel(() => [
426
- this.getStartInput().then(input => input.getValue()),
427
- this.getEndInput().then(input => input.getValue()),
428
- this.getSeparator(),
429
- ]);
430
- return start + `${end ? ` ${separator} ${end}` : ''}`;
431
- }
432
- /** Gets the inner start date input inside the range input. */
433
- async getStartInput() {
434
- // Don't pass in filters here since the start input is required and there can only be one.
435
- return this.locatorFor(MatStartDateHarness)();
436
- }
437
- /** Gets the inner start date input inside the range input. */
438
- async getEndInput() {
439
- // Don't pass in filters here since the end input is required and there can only be one.
440
- return this.locatorFor(MatEndDateHarness)();
441
- }
442
- /**
443
- * Gets the label for the range input, if it exists. This might be provided by a label element or
444
- * by the `aria-label` attribute.
445
- */
446
- async getLabel() {
447
- // Directly copied from MatFormFieldControlHarnessBase. This class already has a parent so it
448
- // cannot extend MatFormFieldControlHarnessBase for the functionality.
449
- const documentRootLocator = this.documentRootLocatorFactory();
450
- const labelId = await (await this.host()).getAttribute('aria-labelledby');
451
- const labelText = await (await this.host()).getAttribute('aria-label');
452
- const hostId = await (await this.host()).getAttribute('id');
453
- if (labelId) {
454
- // First, try to find the label by following [aria-labelledby]
455
- const labelEl = await documentRootLocator.locatorForOptional(`[id="${labelId}"]`)();
456
- return labelEl ? labelEl.text() : null;
457
- }
458
- else if (labelText) {
459
- // If that doesn't work, return [aria-label] if it exists
460
- return labelText;
461
- }
462
- else if (hostId) {
463
- // Finally, search the DOM for a label that points to the host element
464
- const labelEl = await documentRootLocator.locatorForOptional(`[for="${hostId}"]`)();
465
- return labelEl ? labelEl.text() : null;
466
- }
467
- return null;
468
- }
469
- /** Gets the separator text between the values of the two inputs. */
470
- async getSeparator() {
471
- return (await this.locatorFor('.mat-date-range-input-separator')()).text();
472
- }
473
- /** Gets whether the range input is disabled. */
474
- async isDisabled() {
475
- // We consider the input as disabled if both of the sub-inputs are disabled.
476
- const [startDisabled, endDisabled] = await parallel(() => [
477
- this.getStartInput().then(input => input.isDisabled()),
478
- this.getEndInput().then(input => input.isDisabled()),
479
- ]);
480
- return startDisabled && endDisabled;
481
- }
482
- /** Gets whether the range input is required. */
483
- async isRequired() {
484
- return (await this.host()).hasClass('mat-date-range-input-required');
485
- }
486
- /** Opens the calendar associated with the input. */
487
- async isCalendarOpen() {
488
- // `aria-owns` is set on both inputs only if there's an
489
- // open range picker so we can use it as an indicator.
490
- const startHost = await (await this.getStartInput()).host();
491
- return (await startHost.getAttribute('aria-owns')) != null;
492
- }
493
- async _openCalendar() {
494
- // Alt + down arrow is the combination for opening the calendar with the keyboard.
495
- const startHost = await (await this.getStartInput()).host();
496
- return startHost.sendKeys({ alt: true }, TestKey.DOWN_ARROW);
497
- }
267
+ static hostSelector = '.mat-date-range-input';
268
+ static with(options = {}) {
269
+ return new HarnessPredicate(MatDateRangeInputHarness, options).addOption('value', options.value, (harness, value) => HarnessPredicate.stringMatches(harness.getValue(), value)).addOption('label', options.label, (harness, label) => {
270
+ return HarnessPredicate.stringMatches(harness.getLabel(), label);
271
+ });
272
+ }
273
+ async getValue() {
274
+ const [start, end, separator] = await parallel(() => [this.getStartInput().then(input => input.getValue()), this.getEndInput().then(input => input.getValue()), this.getSeparator()]);
275
+ return start + `${end ? ` ${separator} ${end}` : ''}`;
276
+ }
277
+ async getStartInput() {
278
+ return this.locatorFor(MatStartDateHarness)();
279
+ }
280
+ async getEndInput() {
281
+ return this.locatorFor(MatEndDateHarness)();
282
+ }
283
+ async getLabel() {
284
+ const documentRootLocator = this.documentRootLocatorFactory();
285
+ const labelId = await (await this.host()).getAttribute('aria-labelledby');
286
+ const labelText = await (await this.host()).getAttribute('aria-label');
287
+ const hostId = await (await this.host()).getAttribute('id');
288
+ if (labelId) {
289
+ const labelEl = await documentRootLocator.locatorForOptional(`[id="${labelId}"]`)();
290
+ return labelEl ? labelEl.text() : null;
291
+ } else if (labelText) {
292
+ return labelText;
293
+ } else if (hostId) {
294
+ const labelEl = await documentRootLocator.locatorForOptional(`[for="${hostId}"]`)();
295
+ return labelEl ? labelEl.text() : null;
296
+ }
297
+ return null;
298
+ }
299
+ async getSeparator() {
300
+ return (await this.locatorFor('.mat-date-range-input-separator')()).text();
301
+ }
302
+ async isDisabled() {
303
+ const [startDisabled, endDisabled] = await parallel(() => [this.getStartInput().then(input => input.isDisabled()), this.getEndInput().then(input => input.isDisabled())]);
304
+ return startDisabled && endDisabled;
305
+ }
306
+ async isRequired() {
307
+ return (await this.host()).hasClass('mat-date-range-input-required');
308
+ }
309
+ async isCalendarOpen() {
310
+ const startHost = await (await this.getStartInput()).host();
311
+ return (await startHost.getAttribute('aria-owns')) != null;
312
+ }
313
+ async _openCalendar() {
314
+ const startHost = await (await this.getStartInput()).host();
315
+ return startHost.sendKeys({
316
+ alt: true
317
+ }, TestKey.DOWN_ARROW);
318
+ }
498
319
  }
499
320
 
500
321
  export { CalendarView, DatepickerTriggerHarnessBase, MatCalendarCellHarness, MatCalendarHarness, MatDateRangeInputHarness, MatDatepickerInputHarness, MatEndDateHarness, MatStartDateHarness };