Skip to content

Commit 0b608f1

Browse files
author
ddaribo
committed
feat(stepper): create spec file, add basic tests
1 parent 9710a77 commit 0b608f1

File tree

1 file changed

+320
-0
lines changed

1 file changed

+320
-0
lines changed
Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
import { Component, ViewChild } from '@angular/core';
2+
import { fakeAsync, ComponentFixture, TestBed, waitForAsync, tick } from '@angular/core/testing';
3+
import { configureTestSuite } from '../test-utils/configure-suite';
4+
import { IgxStepperComponent, IgxStepperModule } from './igx-stepper.component';
5+
import { By } from '@angular/platform-browser';
6+
import { UIInteractions } from '../test-utils/ui-interactions.spec';
7+
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
8+
import { IStepToggledEventArgs, IStepTogglingEventArgs } from './common';
9+
import { pipe, Subject } from 'rxjs';
10+
import { takeUntil } from 'rxjs/operators';
11+
12+
const STEPPER_CLASS = 'igx-stepper';
13+
const STEPPER_HEADER = 'igx-stepper__header';
14+
const STEP_TAG = 'IGX-STEP';
15+
const STEP_HEADER = 'igx-stepper__step-header';
16+
17+
describe('Rendering Tests', () => {
18+
configureTestSuite();
19+
let fix: ComponentFixture<IgxStepperSampleTestComponent>;
20+
let stepper: IgxStepperComponent;
21+
22+
beforeAll(
23+
waitForAsync(() => {
24+
TestBed.configureTestingModule({
25+
declarations: [
26+
IgxStepperSampleTestComponent
27+
],
28+
imports: [
29+
NoopAnimationsModule,
30+
IgxStepperModule
31+
],
32+
providers: []
33+
}).compileComponents();
34+
})
35+
);
36+
beforeEach(() => {
37+
fix = TestBed.createComponent(IgxStepperSampleTestComponent);
38+
fix.detectChanges();
39+
stepper = fix.componentInstance.stepper;
40+
});
41+
42+
describe('General', () => {
43+
it('should render a stepper containing a sequence of steps', () => {
44+
const stepperElement: HTMLElement = fix.debugElement.queryAll(By.css(`${STEPPER_CLASS}`))[0].nativeElement;
45+
const stepperHeader: HTMLElement = stepperElement.querySelector(`.${STEPPER_HEADER}`);
46+
const steps = stepperHeader.children;
47+
expect(steps.length).toBe(5);
48+
for (let i = 0; i < steps.length; i++) {
49+
expect(steps[i].tagName === STEP_TAG).toBeTruthy();
50+
}
51+
});
52+
53+
it('should skip steps when skip is set to true', fakeAsync(() => { //fails
54+
expect(stepper.steps[0].active).toBeTruthy();
55+
56+
stepper.steps[1].skip = true;
57+
fix.detectChanges();
58+
tick();
59+
60+
stepper.next();
61+
fix.detectChanges();
62+
tick(3000);
63+
64+
expect(stepper.steps[0].active).toBeFalsy();
65+
expect(stepper.steps[2].isAccessible).toBeTruthy("expect 3rd step to be accessible");
66+
expect(stepper.steps[2].active).toBeTruthy("expect 3rd step to be active");
67+
}));
68+
69+
fit('should allow activating a step when skip is set to true', fakeAsync(() => {
70+
let step2Header: HTMLElement = stepper.steps[2].nativeElement.querySelector(`.${STEP_HEADER}`);
71+
72+
expect(stepper.steps[0].active).toBeTruthy();
73+
expect(stepper.steps[1].active).toBeFalsy();
74+
expect(stepper.steps[2].active).toBeFalsy();
75+
76+
stepper.steps[1].skip = true;
77+
stepper.steps[2].skip = true;
78+
fix.detectChanges();
79+
tick();
80+
81+
expect(stepper.steps[1].skip).toBeTruthy();
82+
83+
stepper.navigateTo(1);
84+
fix.detectChanges();
85+
tick();
86+
87+
expect(stepper.steps[1].active).toBeTruthy();
88+
89+
UIInteractions.simulateClickEvent(step2Header);
90+
fix.detectChanges();
91+
92+
expect(stepper.steps[1].active).toBeFalsy();
93+
expect(stepper.steps[2].active).toBeTruthy();
94+
}));
95+
96+
it('should not allow activating a step when disabled is set to true', fakeAsync(() => { //fails
97+
expect(stepper.steps[0].active).toBeTruthy();
98+
99+
stepper.steps[1].disabled = true;
100+
fix.detectChanges();
101+
tick();
102+
103+
stepper.next();
104+
fix.detectChanges();
105+
tick();
106+
107+
expect(stepper.steps[1].active).toBeFalsy();
108+
expect(stepper.steps[2].isAccessible).toBeTruthy();
109+
expect(stepper.steps[2].active).toBeTruthy();
110+
}));
111+
112+
fit('should not allow moving forward to next step in linear mode if the previous step is invalid', fakeAsync(() => {
113+
let step1Header: HTMLElement = stepper.steps[1].nativeElement.querySelector(`.${STEP_HEADER}`);
114+
115+
stepper.linear = true;
116+
stepper.steps[0].isValid = false;
117+
fix.detectChanges();
118+
tick();
119+
120+
stepper.next();
121+
fix.detectChanges();
122+
tick();
123+
124+
expect(stepper.steps[1].active).toBeFalsy();
125+
expect(stepper.steps[0].active).toBeTruthy();
126+
127+
UIInteractions.simulateClickEvent(step1Header);
128+
fix.detectChanges();
129+
130+
expect(stepper.steps[1].active).toBeFalsy(); //fails
131+
expect(stepper.steps[0].active).toBeTruthy();
132+
}));
133+
134+
it('should emit ing and ed events when a step is activated', fakeAsync(() => {
135+
const changingSpy = spyOn(stepper.activeStepChanging, 'emit').and.callThrough();
136+
const changedSpy = spyOn(stepper.activeStepChanged, 'emit').and.callThrough();
137+
138+
expect(changingSpy).not.toHaveBeenCalled();
139+
expect(changedSpy).not.toHaveBeenCalled();
140+
141+
let argsIng: IStepTogglingEventArgs = {
142+
activeStep: stepper.steps[1],
143+
previousActiveStep: stepper.steps[0],
144+
owner: stepper,
145+
cancel: false
146+
};
147+
let argsEd: IStepToggledEventArgs = {
148+
activeStep: stepper.steps[1],
149+
owner: stepper,
150+
};
151+
152+
stepper.navigateTo(1);
153+
fix.detectChanges();
154+
tick();
155+
156+
expect(stepper.steps[1].active).toBeTruthy();
157+
expect(changingSpy).toHaveBeenCalledTimes(1);
158+
expect(changingSpy).toHaveBeenCalledWith(argsIng);
159+
expect(changedSpy).toHaveBeenCalledTimes(1);
160+
expect(changedSpy).toHaveBeenCalledWith(argsEd);
161+
}));
162+
163+
it('should be able to cancel the activeStepChanging event', fakeAsync(() => {
164+
const changingSpy = spyOn(stepper.activeStepChanging, 'emit').and.callThrough();
165+
166+
expect(changingSpy).not.toHaveBeenCalled();
167+
168+
let argsIng: IStepTogglingEventArgs = {
169+
activeStep: stepper.steps[1],
170+
previousActiveStep: stepper.steps[0],
171+
owner: stepper,
172+
cancel: true
173+
};
174+
175+
const unsub$ = new Subject<void>();
176+
stepper.activeStepChanging.pipe(takeUntil(unsub$)).subscribe(e => {
177+
e.cancel = true;
178+
});
179+
180+
stepper.navigateTo(1);
181+
fix.detectChanges();
182+
tick();
183+
184+
expect(stepper.steps[1].active).toBeFalsy();
185+
expect(changingSpy).toHaveBeenCalledTimes(1);
186+
expect(changingSpy).toHaveBeenCalledWith(argsIng);
187+
188+
unsub$.next();
189+
unsub$.complete();
190+
}));
191+
192+
it('a step should emit activeChanged event when its active property changes', fakeAsync(() => {
193+
const fourthActiveChangeSpy = spyOn(stepper.steps[3].activeChange, 'emit').and.callThrough();
194+
const fifthActiveChangeSpy = spyOn(stepper.steps[4].activeChange, 'emit').and.callThrough();
195+
196+
expect(fourthActiveChangeSpy).not.toHaveBeenCalled();
197+
expect(fifthActiveChangeSpy).not.toHaveBeenCalled();
198+
199+
stepper.navigateTo(3);
200+
fix.detectChanges();
201+
tick();
202+
203+
expect(stepper.steps[3].active).toBeTruthy();
204+
expect(stepper.steps[3].activeChange.emit).toHaveBeenCalledTimes(1);
205+
expect(stepper.steps[3].activeChange.emit).toHaveBeenCalledWith(true);
206+
expect(fifthActiveChangeSpy).not.toHaveBeenCalled();
207+
208+
fourthActiveChangeSpy.calls.reset();
209+
210+
stepper.navigateTo(4);
211+
fix.detectChanges();
212+
tick();
213+
214+
expect(stepper.steps[4].active).toBeTruthy();
215+
expect(stepper.steps[3].active).toBeFalsy();
216+
expect(fifthActiveChangeSpy).toHaveBeenCalledWith(true);
217+
expect(fourthActiveChangeSpy).toHaveBeenCalledWith(false);
218+
expect(fourthActiveChangeSpy).toHaveBeenCalledTimes(1);
219+
expect(fifthActiveChangeSpy).toHaveBeenCalledTimes(1);
220+
}));
221+
});
222+
223+
describe('Keyboard navigation', () => {
224+
it('should navigate to first step on Home key press', fakeAsync(()=>{
225+
//stepper.nativeElement.dispatchEvent(new Event('pointerdown'));
226+
tick();
227+
let step3Header: HTMLElement = stepper.steps[3].nativeElement.querySelector(`.${STEP_HEADER}`);
228+
expect(stepper.steps[3].active).toBeFalsy();
229+
230+
UIInteractions.simulateClickEvent(step3Header); // works
231+
//UIInteractions.simulateClickEvent(stepper.steps[3].nativeElement); //does not work
232+
233+
fix.detectChanges();
234+
tick();
235+
expect(stepper.steps[3].active).toBeTruthy();
236+
//(step3Header as HTMLElement).dispatchEvent(new MouseEvent('pointerdown')); //nope
237+
238+
let focusSpy = spyOn(step3Header, 'focus');
239+
240+
step3Header.focus();
241+
fix.detectChanges();
242+
tick();
243+
expect(focusSpy).toHaveBeenCalled();
244+
fix.detectChanges();
245+
tick();
246+
//expect(step3Header as Element).toEqual(document.activeElement); //always body
247+
248+
let step0Header: HTMLElement = stepper.steps[0].nativeElement.querySelector(`.${STEP_HEADER}`);
249+
let focus0Spy = spyOn(step0Header, 'focus');
250+
251+
UIInteractions.triggerKeyDownEvtUponElem('Home', step3Header);
252+
fix.detectChanges();
253+
254+
//expect(focus0Spy).toHaveBeenCalled(); //nope
255+
}));
256+
});
257+
});
258+
259+
@Component({
260+
template: `
261+
<igx-stepper #stepper [orientation]="'Horizontal'" [verticalAnimationType]="verticalAnimationType"
262+
[horizontalAnimationType]="horizontalAnimationType" [animationDuration]="animationDuration">
263+
<igx-step #step1 [active]="true">
264+
<span igxStepIcon>1</span>
265+
<span igxStepTitle>Step No 1</span>
266+
<span igxStepSubTitle>Step SubTitle</span>
267+
<div class="sample-body">
268+
<p>Test step</p>
269+
</div>
270+
</igx-step>
271+
272+
<igx-step #step2>
273+
<span igxStepIcon>2</span>
274+
<span igxStepTitle>Step No 2</span>
275+
<span igxStepSubTitle>Step SubTitle</span>
276+
<div class="sample-body">
277+
<p>Test step 2</p>
278+
</div>
279+
</igx-step>
280+
281+
<igx-step #step3>
282+
<span igxStepIcon>3</span>
283+
<span igxStepTitle>Step No 3</span>
284+
<span igxStepSubTitle>Step SubTitle</span>
285+
<div class="sample-body">
286+
<p>Test step 3</p>
287+
</div>
288+
</igx-step>
289+
290+
<igx-step #step4>
291+
<span igxStepIcon>4</span>
292+
<span igxStepTitle>Step No 4</span>
293+
<span igxStepSubTitle>Step SubTitle</span>
294+
<div class="sample-body">
295+
<p>Test step 4</p>
296+
</div>
297+
</igx-step>
298+
299+
<igx-step #step5 >
300+
<span igxStepIcon>5</span>
301+
<span igxStepTitle>Step No 5</span>
302+
<span igxStepSubTitle>Step SubTitle</span>
303+
<div class="sample-body">
304+
<p>Test step 5</p>
305+
</div>
306+
</igx-step>
307+
</igx-stepper>
308+
<br>
309+
`
310+
})
311+
export class IgxStepperSampleTestComponent {
312+
@ViewChild(IgxStepperComponent) public stepper: IgxStepperComponent;
313+
314+
public horizontalAnimationType = 'slide';
315+
public verticalAnimationType = 'grow';
316+
public animationDuration = 300;
317+
318+
}
319+
320+

0 commit comments

Comments
 (0)