-
Notifications
You must be signed in to change notification settings - Fork 6.8k
Expand file tree
/
Copy pathbutton-harness.spec.ts
More file actions
293 lines (260 loc) · 11.1 KB
/
Copy pathbutton-harness.spec.ts
File metadata and controls
293 lines (260 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
import {Component, signal, ChangeDetectionStrategy} from '@angular/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {Platform} from '@angular/cdk/platform';
import {HarnessLoader, parallel} from '@angular/cdk/testing';
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
import {MatButtonModule} from '../button-module';
import {MatIconModule} from '../../icon';
import {MatIconHarness} from '../../icon/testing';
import {MatButtonHarness} from './button-harness';
import {MatButtonAppearance} from '../button-base';
describe('MatButtonHarness', () => {
let fixture: ComponentFixture<ButtonHarnessTest>;
let loader: HarnessLoader;
beforeEach(() => {
fixture = TestBed.createComponent(ButtonHarnessTest);
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('should load all button harnesses', async () => {
const buttons = await loader.getAllHarnesses(MatButtonHarness);
expect(buttons.length).toBe(24);
});
it('should load button with exact text', async () => {
const buttons = await loader.getAllHarnesses(MatButtonHarness.with({text: 'Basic button'}));
expect(buttons.length).toBe(1);
expect(await buttons[0].getText()).toBe('Basic button');
});
it('should load button with regex label match', async () => {
const buttons = await loader.getAllHarnesses(MatButtonHarness.with({text: /basic/i}));
expect(buttons.length).toBe(2);
expect(await buttons[0].getText()).toBe('Basic button');
expect(await buttons[1].getText()).toBe('Basic anchor');
});
it('should filter by whether a button is disabled', async () => {
const enabledButtons = await loader.getAllHarnesses(MatButtonHarness.with({disabled: false}));
const disabledButtons = await loader.getAllHarnesses(MatButtonHarness.with({disabled: true}));
expect(enabledButtons.length).toBe(22);
expect(disabledButtons.length).toBe(2);
});
it('should get disabled state', async () => {
// Grab each combination of [enabled, disabled] x [button, anchor]
const [disabledFilledButton, enabledFilledAnchor] = await loader.getAllHarnesses(
MatButtonHarness.with({text: /filled/i}),
);
const [enabledElevatedButton, disabledElevatedAnchor] = await loader.getAllHarnesses(
MatButtonHarness.with({text: /elevated/i}),
);
expect(await enabledFilledAnchor.isDisabled()).toBe(false);
expect(await disabledFilledButton.isDisabled()).toBe(true);
expect(await enabledElevatedButton.isDisabled()).toBe(false);
expect(await disabledElevatedAnchor.isDisabled()).toBe(true);
});
it('should load button with type attribute', async () => {
const buttons = await loader.getAllHarnesses(MatButtonHarness.with({buttonType: 'submit'}));
expect(buttons.length).toBe(1);
expect(await buttons[0].getText()).toBe('Submit button');
expect(await buttons[0].getType()).toBe('submit');
});
it('should get button text', async () => {
const [firstButton, secondButton] = await loader.getAllHarnesses(MatButtonHarness);
expect(await firstButton.getText()).toBe('Basic button');
expect(await secondButton.getText()).toBe('Filled button');
});
it('should focus and blur a button', async () => {
const button = await loader.getHarness(MatButtonHarness.with({text: 'Basic button'}));
expect(await button.isFocused()).toBe(false);
await button.focus();
expect(await button.isFocused()).toBe(true);
await button.blur();
expect(await button.isFocused()).toBe(false);
});
it('should click a button', async () => {
const button = await loader.getHarness(MatButtonHarness.with({text: 'Basic button'}));
await button.click();
expect(fixture.componentInstance.clicked()).toBe(true);
});
it('should not click a disabled button', async () => {
// Older versions of Edge have a bug where `disabled` buttons are still clickable if
// they contain child elements. Also new versions of Firefox (starting v65) do not
// cancel dispatched click events on disabled buttons. We skip this check on Edge and Firefox.
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1582570 and:
// https://stackoverflow.com/questions/32377026/disabled-button-is-clickable-on-edge-browser
if (TestBed.inject(Platform).FIREFOX) {
return;
}
const button = await loader.getHarness(MatButtonHarness.with({text: 'Filled button'}));
await button.click();
expect(fixture.componentInstance.clicked()).toBe(false);
});
it('should be able to handle nested harnesses', async () => {
const homeBtn = await loader.getHarness(MatButtonHarness.with({selector: '#home-icon'}));
const favBtn = await loader.getHarness(MatButtonHarness.with({selector: '#favorite-icon'}));
const homeIcon = await homeBtn.getHarness(MatIconHarness);
const favIcon = await favBtn.getHarness(MatIconHarness);
expect(await homeIcon.getName()).toBe('home');
expect(await favIcon.getName()).toBe('favorite');
});
it('should be able to filter buttons containing a named icon', async () => {
const favBtn = await loader.getHarness(MatButtonHarness.with({iconName: 'favorite'}));
expect(await (await favBtn.host()).getAttribute('id')).toBe('favorite-icon');
expect(await (await favBtn.getHarness(MatIconHarness)).getName()).toBe('favorite');
});
it('should be able to ge the type variant of the button', async () => {
const buttons = await loader.getAllHarnesses(MatButtonHarness);
const variants = await parallel(() => buttons.map(button => button.getVariant()));
expect(variants).toEqual([
'basic',
'basic',
'basic',
'basic',
'basic',
'icon',
'icon',
'icon',
'icon',
'fab',
'mini-fab',
'basic',
'basic',
'icon',
'basic',
'basic',
'basic',
'basic',
'basic',
'icon',
'fab',
'fab',
'mini-fab',
'mini-fab',
]);
});
it('should be able to get the appearance of the button', async () => {
const buttons = await loader.getAllHarnesses(MatButtonHarness);
const appearances = await parallel(() => buttons.map(button => button.getAppearance()));
expect(appearances).toEqual([
'text',
'filled',
'elevated',
'outlined',
'tonal',
null,
null,
'filled',
'tonal',
null,
null,
'text',
'text',
null,
'text',
'filled',
'elevated',
'outlined',
'tonal',
null,
null,
null,
null,
null,
]);
});
it('should be able to filter buttons based on their variant', async () => {
const button = await loader.getHarness(MatButtonHarness.with({variant: 'fab'}));
expect(await button.getText()).toBe('Fab button');
});
it('should be able to filter buttons based on their appearance', async () => {
const buttons = await loader.getAllHarnesses(MatButtonHarness.with({appearance: 'filled'}));
const texts = await parallel(() => buttons.map(button => button.getText()));
expect(texts).toEqual(['Filled button', 'add', 'Filled anchor']);
});
it('should get the appearance of a button with a dynamic appearance', async () => {
const button = await loader.getHarness(
MatButtonHarness.with({selector: '#dynamic-appearance'}),
);
expect(await button.getAppearance()).toBe('tonal');
fixture.componentInstance.dynamicAppearance.set('filled');
expect(await button.getAppearance()).toBe('filled');
});
it('should be able to tell if a button is showing a progress indicator', async () => {
const buttonWithIndicator = await loader.getHarness(
MatButtonHarness.with({selector: '#with-progress-indicator'}),
);
const iconButtonWithIndicator = await loader.getHarness(
MatButtonHarness.with({selector: '#icon-with-progress-indicator'}),
);
const fabAnchorWithIndicator = await loader.getHarness(
MatButtonHarness.with({selector: '#anchor-fab-with-progress-indicator'}),
);
const miniFabAnchorWithIndicator = await loader.getHarness(
MatButtonHarness.with({selector: '#anchor-mini-fab-with-progress-indicator'}),
);
const regularButton = await loader.getHarness(MatButtonHarness.with({selector: '#basic'}));
expect(await buttonWithIndicator.isShowingProgress()).toBe(true);
expect(await iconButtonWithIndicator.isShowingProgress()).toBe(true);
expect(await fabAnchorWithIndicator.isShowingProgress()).toBe(true);
expect(await miniFabAnchorWithIndicator.isShowingProgress()).toBe(true);
expect(await regularButton.isShowingProgress()).toBe(false);
});
});
@Component({
// Include one of each type of button selector to ensure that they're all captured by
// the harness's selector.
template: `
<button id="basic" type="button" matButton (click)="clicked.set(true)">
Basic button
</button>
<button id="flat" type="button" matButton="filled" disabled (click)="clicked.set(true)">
Filled button
</button>
<button id="raised" type="button" matButton="elevated">Elevated button</button>
<button id="stroked" type="button" matButton="outlined">Outlined button</button>
<button id="tonal" type="button" matButton="tonal">Tonal button</button>
<button id="home-icon" type="button" matIconButton>
<mat-icon>home</mat-icon>
</button>
<button id="favorite-icon" type="button" matIconButton>
<mat-icon>favorite</mat-icon>
</button>
<button id="filled-icon" type="button" matIconButton="filled">
<mat-icon>add</mat-icon>
</button>
<button id="tonal-icon" type="button" matIconButton="tonal">
<mat-icon>bookmark</mat-icon>
</button>
<button id="fab" type="button" matFab>Fab button</button>
<button id="mini-fab" type="button" matMiniFab>Mini Fab button</button>
<button id="submit" type="submit" matButton>Submit button</button>
<button id="with-progress-indicator" type="button" matButton showProgress>
Button with progress indicator
<div progressIndicator></div>
</button>
<button id="icon-with-progress-indicator" type="button" matIconButton showProgress>
<mat-icon>home</mat-icon>
<div progressIndicator></div>
</button>
<a id="anchor-basic" matButton>Basic anchor</a>
<a id="anchor-flat" matButton="filled">Filled anchor</a>
<a id="anchor-raised" matButton="elevated" disabled>Elevated anchor</a>
<a id="anchor-stroked" matButton="outlined">Stroked anchor</a>
<a id="dynamic-appearance" [matButton]="dynamicAppearance()">Stroked anchor</a>
<a id="anchor-icon" matIconButton>Icon anchor</a>
<a id="anchor-fab" matFab>Fab anchor</a>
<a id="anchor-fab-with-progress-indicator" matFab showProgress>
Fab anchor with progress indicator
<div progressIndicator></div>
</a>
<a id="anchor-mini-fab" matMiniFab showProgress>Mini Fab anchor</a>
<a id="anchor-mini-fab-with-progress-indicator" matMiniFab showProgress>
Mini Fab anchor with progress indicator
<div progressIndicator></div>
</a>
`,
imports: [MatButtonModule, MatIconModule],
changeDetection: ChangeDetectionStrategy.Eager,
})
class ButtonHarnessTest {
clicked = signal(false);
dynamicAppearance = signal<MatButtonAppearance>('tonal');
}