6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
9
- import { coerceBooleanProperty } from '@angular/cdk/coercion' ;
10
- import { ComponentHarness , HarnessPredicate } from '@angular/cdk/testing' ;
11
- import { RadioButtonHarnessFilters , RadioGroupHarnessFilters } from './radio-harness-filters' ;
9
+ import { HarnessPredicate } from '@angular/cdk/testing' ;
10
+ import {
11
+ RadioButtonHarnessFilters ,
12
+ RadioGroupHarnessFilters ,
13
+ _MatRadioGroupHarnessBase ,
14
+ _MatRadioButtonHarnessBase ,
15
+ } from '@angular/material/radio/testing' ;
12
16
13
17
/** Harness for interacting with an MDC-based mat-radio-group in tests. */
14
- export class MatRadioGroupHarness extends ComponentHarness {
18
+ export class MatRadioGroupHarness extends _MatRadioGroupHarnessBase <
19
+ typeof MatRadioButtonHarness ,
20
+ MatRadioButtonHarness ,
21
+ RadioButtonHarnessFilters
22
+ > {
15
23
/** The selector for the host element of a `MatRadioGroup` instance. */
16
24
static hostSelector = '.mat-mdc-radio-group' ;
25
+ protected _buttonClass = MatRadioButtonHarness ;
17
26
18
27
/**
19
28
* Gets a `HarnessPredicate` that can be used to search for a `MatRadioGroupHarness` that meets
20
29
* certain criteria.
21
30
* @param options Options for filtering which radio group instances are considered a match.
22
31
* @return a `HarnessPredicate` configured with the given options.
23
32
*/
24
- static with ( options : RadioGroupHarnessFilters = { } ) : HarnessPredicate < MatRadioGroupHarness > {
25
- return new HarnessPredicate ( MatRadioGroupHarness , options )
33
+ static with ( options : RadioGroupHarnessFilters = { } ) :
34
+ HarnessPredicate < MatRadioGroupHarness > {
35
+ return new HarnessPredicate < MatRadioGroupHarness > ( MatRadioGroupHarness , options )
26
36
. addOption ( 'name' , options . name , this . _checkRadioGroupName ) ;
27
37
}
28
-
29
- /** Gets the name of the radio-group. */
30
- async getName ( ) : Promise < string | null > {
31
- const hostName = await this . _getGroupNameFromHost ( ) ;
32
- // It's not possible to always determine the "name" of a radio-group by reading
33
- // the attribute. This is because the radio-group does not set the "name" as an
34
- // element attribute if the "name" value is set through a binding.
35
- if ( hostName !== null ) {
36
- return hostName ;
37
- }
38
- // In case we couldn't determine the "name" of a radio-group by reading the
39
- // "name" attribute, we try to determine the "name" of the group by going
40
- // through all radio buttons.
41
- const radioNames = await this . _getNamesFromRadioButtons ( ) ;
42
- if ( ! radioNames . length ) {
43
- return null ;
44
- }
45
- if ( ! this . _checkRadioNamesInGroupEqual ( radioNames ) ) {
46
- throw Error ( 'Radio buttons in radio-group have mismatching names.' ) ;
47
- }
48
- return radioNames [ 0 ] ! ;
49
- }
50
-
51
- /** Gets the id of the radio-group. */
52
- async getId ( ) : Promise < string | null > {
53
- return ( await this . host ( ) ) . getProperty ( 'id' ) ;
54
- }
55
-
56
- /** Gets the checked radio-button in a radio-group. */
57
- async getCheckedRadioButton ( ) : Promise < MatRadioButtonHarness | null > {
58
- for ( let radioButton of await this . getRadioButtons ( ) ) {
59
- if ( await radioButton . isChecked ( ) ) {
60
- return radioButton ;
61
- }
62
- }
63
- return null ;
64
- }
65
-
66
- /** Gets the checked value of the radio-group. */
67
- async getCheckedValue ( ) : Promise < string | null > {
68
- const checkedRadio = await this . getCheckedRadioButton ( ) ;
69
- if ( ! checkedRadio ) {
70
- return null ;
71
- }
72
- return checkedRadio . getValue ( ) ;
73
- }
74
-
75
- /**
76
- * Gets a list of radio buttons which are part of the radio-group.
77
- * @param filter Optionally filters which radio buttons are included.
78
- */
79
- async getRadioButtons ( filter : RadioButtonHarnessFilters = { } ) : Promise < MatRadioButtonHarness [ ] > {
80
- return this . locatorForAll ( MatRadioButtonHarness . with ( filter ) ) ( ) ;
81
- }
82
-
83
- /**
84
- * Checks a radio button in this group.
85
- * @param filter An optional filter to apply to the child radio buttons. The first tab matching
86
- * the filter will be selected.
87
- */
88
- async checkRadioButton ( filter : RadioButtonHarnessFilters = { } ) : Promise < void > {
89
- const radioButtons = await this . getRadioButtons ( filter ) ;
90
- if ( ! radioButtons . length ) {
91
- throw Error ( `Could not find radio button matching ${ JSON . stringify ( filter ) } ` ) ;
92
- }
93
- return radioButtons [ 0 ] . check ( ) ;
94
- }
95
-
96
- /** Gets the name attribute of the host element. */
97
- private async _getGroupNameFromHost ( ) {
98
- return ( await this . host ( ) ) . getAttribute ( 'name' ) ;
99
- }
100
-
101
- /** Gets a list of the name attributes of all child radio buttons. */
102
- private async _getNamesFromRadioButtons ( ) : Promise < string [ ] > {
103
- const groupNames : string [ ] = [ ] ;
104
- for ( let radio of await this . getRadioButtons ( ) ) {
105
- const radioName = await radio . getName ( ) ;
106
- if ( radioName !== null ) {
107
- groupNames . push ( radioName ) ;
108
- }
109
- }
110
- return groupNames ;
111
- }
112
-
113
- /** Checks if the specified radio names are all equal. */
114
- private _checkRadioNamesInGroupEqual ( radioNames : string [ ] ) : boolean {
115
- let groupName : string | null = null ;
116
- for ( let radioName of radioNames ) {
117
- if ( groupName === null ) {
118
- groupName = radioName ;
119
- } else if ( groupName !== radioName ) {
120
- return false ;
121
- }
122
- }
123
- return true ;
124
- }
125
-
126
- /**
127
- * Checks if a radio-group harness has the given name. Throws if a radio-group with
128
- * matching name could be found but has mismatching radio-button names.
129
- */
130
- private static async _checkRadioGroupName ( harness : MatRadioGroupHarness , name : string ) {
131
- // Check if there is a radio-group which has the "name" attribute set
132
- // to the expected group name. It's not possible to always determine
133
- // the "name" of a radio-group by reading the attribute. This is because
134
- // the radio-group does not set the "name" as an element attribute if the
135
- // "name" value is set through a binding.
136
- if ( await harness . _getGroupNameFromHost ( ) === name ) {
137
- return true ;
138
- }
139
- // Check if there is a group with radio-buttons that all have the same
140
- // expected name. This implies that the group has the given name. It's
141
- // not possible to always determine the name of a radio-group through
142
- // the attribute because there is
143
- const radioNames = await harness . _getNamesFromRadioButtons ( ) ;
144
- if ( radioNames . indexOf ( name ) === - 1 ) {
145
- return false ;
146
- }
147
- if ( ! harness . _checkRadioNamesInGroupEqual ( radioNames ) ) {
148
- throw Error (
149
- `The locator found a radio-group with name "${ name } ", but some ` +
150
- `radio-button's within the group have mismatching names, which is invalid.` ) ;
151
- }
152
- return true ;
153
- }
154
38
}
155
39
156
40
/** Harness for interacting with an MDC-based mat-radio-button in tests. */
157
- export class MatRadioButtonHarness extends ComponentHarness {
41
+ export class MatRadioButtonHarness extends _MatRadioButtonHarnessBase {
158
42
/** The selector for the host element of a `MatRadioButton` instance. */
159
43
static hostSelector = '.mat-mdc-radio-button' ;
160
44
@@ -164,83 +48,15 @@ export class MatRadioButtonHarness extends ComponentHarness {
164
48
* @param options Options for filtering which radio button instances are considered a match.
165
49
* @return a `HarnessPredicate` configured with the given options.
166
50
*/
167
- static with ( options : RadioButtonHarnessFilters = { } ) : HarnessPredicate < MatRadioButtonHarness > {
168
- return new HarnessPredicate ( MatRadioButtonHarness , options )
169
- . addOption (
170
- 'label' , options . label ,
171
- ( harness , label ) => HarnessPredicate . stringMatches ( harness . getLabelText ( ) , label ) )
172
- . addOption (
173
- 'name' , options . name , async ( harness , name ) => ( await harness . getName ( ) ) === name ) ;
51
+ static with ( options : RadioButtonHarnessFilters = { } ) :
52
+ HarnessPredicate < MatRadioButtonHarness > {
53
+ return new HarnessPredicate < MatRadioButtonHarness > ( MatRadioButtonHarness , options )
54
+ . addOption ( 'label' , options . label ,
55
+ ( harness , label ) => HarnessPredicate . stringMatches ( harness . getLabelText ( ) , label ) )
56
+ . addOption ( 'name' , options . name ,
57
+ async ( harness , name ) => ( await harness . getName ( ) ) === name ) ;
174
58
}
175
59
176
- private _label = this . locatorFor ( 'label' ) ;
177
- private _input = this . locatorFor ( 'input' ) ;
178
-
179
- /** Whether the radio-button is checked. */
180
- async isChecked ( ) : Promise < boolean > {
181
- const checked = ( await this . _input ( ) ) . getProperty ( 'checked' ) ;
182
- return coerceBooleanProperty ( await checked ) ;
183
- }
184
-
185
- /** Whether the radio-button is disabled. */
186
- async isDisabled ( ) : Promise < boolean > {
187
- const disabled = ( await this . _input ( ) ) . getAttribute ( 'disabled' ) ;
188
- return coerceBooleanProperty ( await disabled ) ;
189
- }
190
-
191
- /** Whether the radio-button is required. */
192
- async isRequired ( ) : Promise < boolean > {
193
- const required = ( await this . _input ( ) ) . getAttribute ( 'required' ) ;
194
- return coerceBooleanProperty ( await required ) ;
195
- }
196
-
197
- /** Gets the radio-button's name. */
198
- async getName ( ) : Promise < string | null > {
199
- return ( await this . _input ( ) ) . getAttribute ( 'name' ) ;
200
- }
201
-
202
- /** Gets the radio-button's id. */
203
- async getId ( ) : Promise < string | null > {
204
- return ( await this . host ( ) ) . getProperty ( 'id' ) ;
205
- }
206
-
207
- /**
208
- * Gets the value of the radio-button. The radio-button value will be converted to a string.
209
- *
210
- * Note: This means that for radio-button's with an object as a value `[object Object]` is
211
- * intentionally returned.
212
- */
213
- async getValue ( ) : Promise < string | null > {
214
- return ( await this . _input ( ) ) . getProperty ( 'value' ) ;
215
- }
216
-
217
- /** Gets the radio-button's label text. */
218
- async getLabelText ( ) : Promise < string > {
219
- return ( await this . _label ( ) ) . text ( ) ;
220
- }
221
-
222
- /** Focuses the radio-button. */
223
- async focus ( ) : Promise < void > {
224
- return ( await this . _input ( ) ) . focus ( ) ;
225
- }
226
-
227
- /** Blurs the radio-button. */
228
- async blur ( ) : Promise < void > {
229
- return ( await this . _input ( ) ) . blur ( ) ;
230
- }
231
-
232
- /** Whether the radio-button is focused. */
233
- async isFocused ( ) : Promise < boolean > {
234
- return ( await this . _input ( ) ) . isFocused ( ) ;
235
- }
236
-
237
- /**
238
- * Puts the radio-button in a checked state by clicking it if it is currently unchecked,
239
- * or doing nothing if it is already checked.
240
- */
241
- async check ( ) : Promise < void > {
242
- if ( ! ( await this . isChecked ( ) ) ) {
243
- return ( await this . _label ( ) ) . click ( ) ;
244
- }
245
- }
60
+ protected _textLabel = this . locatorFor ( 'label' ) ;
61
+ protected _clickLabel = this . _textLabel ;
246
62
}
0 commit comments