igniteui-angular-sovn
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
414 lines (343 loc) • 18.9 kB
text/typescript
import { useAnimation } from '@angular/animations';
import { NgIf } from '@angular/common';
import { Component, ViewChild } from '@angular/core';
import { waitForAsync, TestBed, fakeAsync, ComponentFixture, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { slideInLeft, slideOutRight } from '../animations/slide';
import { IgxExpansionPanelBodyComponent, IgxExpansionPanelComponent, IgxExpansionPanelHeaderComponent, IgxExpansionPanelTitleDirective } from '../expansion-panel/public_api';
import { configureTestSuite } from '../test-utils/configure-suite';
import { UIInteractions } from '../test-utils/ui-interactions.spec';
import { IAccordionCancelableEventArgs, IAccordionEventArgs, IgxAccordionComponent } from './accordion.component';
const ACCORDION_CLASS = 'igx-accordion';
const PANEL_TAG = 'IGX-EXPANSION-PANEL';
const ACCORDION_TAG = 'IGX-ACCORDION';
describe('Rendering Tests', () => {
configureTestSuite();
let fix: ComponentFixture<IgxAccordionSampleTestComponent>;
let accordion: IgxAccordionComponent;
beforeAll(
waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
NoopAnimationsModule,
IgxAccordionSampleTestComponent
]
}).compileComponents();
})
);
beforeEach(() => {
fix = TestBed.createComponent(IgxAccordionSampleTestComponent);
fix.detectChanges();
accordion = fix.componentInstance.accordion;
});
describe('General', () => {
it('Should render accordion with expansion panels', () => {
const accordionElement: HTMLElement = fix.debugElement.queryAll(By.css(`.${ACCORDION_CLASS}`))[0].nativeElement;
const childPanels = accordionElement.children;
expect(childPanels.length).toBe(4);
expect(accordion.panels.length).toEqual(4);
for (let i = 0; i < childPanels.length; i++) {
expect(childPanels.item(i).tagName === PANEL_TAG).toBeTruthy();
}
});
it('Should allow overriding animationSettings that are used for expansion panels toggle', () => {
const animationSettingsCustom = {
closeAnimation: useAnimation(slideOutRight, { params: { duration: '100ms', toPosition: 'translateX(25px)' } }),
openAnimation: useAnimation(slideInLeft, { params: { duration: '500ms', fromPosition: 'translateX(-15px)' } })
};
const animationSettingsCustomPanel = {
closeAnimation: useAnimation(slideOutRight, { params: { duration: '200ms', toPosition: 'translateX(25px)' } }),
openAnimation: useAnimation(slideInLeft, { params: { duration: '500ms', fromPosition: 'translateX(-15px)' } })
};
accordion.panels[0].animationSettings = animationSettingsCustomPanel;
accordion.animationSettings = animationSettingsCustom;
for (let i = 0; i < 3; i++) {
expect(accordion.panels[i].animationSettings.closeAnimation.options.params.duration).toEqual('100ms');
}
});
it('Should be able to render nested accordions', () => {
const panelBody = accordion.panels[0].body?.element.nativeElement;
expect(panelBody.children[0].tagName === ACCORDION_TAG).toBeTruthy();
});
it(`Should be able to expand only one panel when singleBranchExpanded is set to true
and expandAll/collapseAll should not update the current expansion state `, fakeAsync(() => {
spyOn(accordion.panelExpanded, 'emit').and.callThrough();
spyOn(accordion.panelCollapsed, 'emit').and.callThrough();
accordion.singleBranchExpand = true;
fix.detectChanges();
accordion.expandAll();
tick();
fix.detectChanges();
expect(accordion.panels.filter(panel => !panel.collapsed).length).toEqual(1);
expect(accordion.panels[3].collapsed).toBeFalse();
expect(accordion.panelExpanded.emit).toHaveBeenCalledTimes(0);
accordion.panels[0].expand();
tick();
fix.detectChanges();
expect(accordion.panels.filter(panel => !panel.collapsed).length).toEqual(2);
expect(accordion.panels[0].collapsed).toBeFalse();
expect(accordion.panels[1].collapsed).toBeTrue();
expect(accordion.panels[2].collapsed).toBeTrue();
expect(accordion.panels[3].collapsed).toBeFalse();
accordion.collapseAll();
tick();
fix.detectChanges();
expect(accordion.panelCollapsed.emit).toHaveBeenCalledTimes(3);
accordion.panels[0].expand();
accordion.panels[1].expand();
tick();
fix.detectChanges();
expect(accordion.panels.filter(panel => !panel.collapsed).length).toEqual(1);
expect(accordion.panels[0].collapsed).toBeTrue();
expect(accordion.panels[1].collapsed).toBeFalse();
expect(accordion.panels[2].collapsed).toBeTrue();
expect(accordion.panels[3].collapsed).toBeTrue();
}));
it('Should be able to expand multiple panels when singleBranchExpanded is set to false', fakeAsync(() => {
accordion.singleBranchExpand = false;
fix.detectChanges();
accordion.panels[0].expand();
tick();
fix.detectChanges();
expect(accordion.panels.filter(panel => !panel.collapsed).length).toEqual(3);
expect(accordion.panels[0].collapsed).toBeFalse();
expect(accordion.panels[1].collapsed).toBeTrue();
expect(accordion.panels[2].collapsed).toBeFalse();
expect(accordion.panels[3].collapsed).toBeFalse();
accordion.panels[1].expand();
tick();
fix.detectChanges();
expect(accordion.panels.filter(panel => !panel.collapsed).length).toEqual(4);
expect(accordion.panels[0].collapsed).toBeFalse();
expect(accordion.panels[1].collapsed).toBeFalse();
expect(accordion.panels[2].collapsed).toBeFalse();
expect(accordion.panels[3].collapsed).toBeFalse();
}));
it(`Should update the current expansion state when expandAll/collapseAll is invoked and
singleBranchExpaned is set to false`, fakeAsync(() => {
spyOn(accordion.panelExpanded, 'emit').and.callThrough();
spyOn(accordion.panelCollapsed, 'emit').and.callThrough();
accordion.singleBranchExpand = false;
accordion.panels[3].collapse();
tick();
fix.detectChanges();
accordion.expandAll();
tick();
fix.detectChanges();
expect(accordion.panels.filter(panel => panel.collapsed).length).toEqual(0);
expect(accordion.panelExpanded.emit).toHaveBeenCalledTimes(3);
accordion.collapseAll();
tick();
fix.detectChanges();
expect(accordion.panels.filter(panel => panel.collapsed).length).toEqual(4);
expect(accordion.panelCollapsed.emit).toHaveBeenCalledTimes(5);
}));
it(`Should collapse all expanded and not disabled panels except for the last one when setting singleBranchExpand to true`, () => {
expect(accordion.panels[0].collapsed).toBeTrue();
expect(accordion.panels[1].collapsed).toBeTrue();
expect(accordion.panels[2].collapsed).toBeFalse();
expect(accordion.panels[3].collapsed).toBeFalse();
accordion.panels[1].collapsed = false;
fix.detectChanges();
expect(accordion.panels[0].collapsed).toBeTrue();
expect(accordion.panels[1].collapsed).toBeFalse();
expect(accordion.panels[2].collapsed).toBeFalse();
expect(accordion.panels[3].collapsed).toBeFalse();
accordion.singleBranchExpand = true;
fix.detectChanges();
expect(accordion.panels[0].collapsed).toBeTrue();
expect(accordion.panels[1].collapsed).toBeTrue();
expect(accordion.panels[2].collapsed).toBeFalse();
expect(accordion.panels[3].collapsed).toBeFalse();
});
it('Should emit ing and ed events when expand panel state is toggled', fakeAsync(() => {
spyOn(accordion.panelExpanded, 'emit').and.callThrough();
spyOn(accordion.panelExpanding, 'emit').and.callThrough();
spyOn(accordion.panelCollapsed, 'emit').and.callThrough();
spyOn(accordion.panelCollapsing, 'emit').and.callThrough();
spyOn(accordion.panels[0].contentCollapsing, 'emit').and.callThrough();
spyOn(accordion.panels[0].contentCollapsed, 'emit').and.callThrough();
spyOn(accordion.panels[0].contentExpanding, 'emit').and.callThrough();
spyOn(accordion.panels[0].contentExpanded, 'emit').and.callThrough();
accordion.singleBranchExpand = false;
fix.detectChanges();
let argsEd: IAccordionEventArgs;
let argsIng: IAccordionCancelableEventArgs;
const subsExpanded = accordion.panels[0].contentExpanded.subscribe(expArgs => {
argsEd = { event: expArgs.event, owner: accordion, panel: expArgs.owner };
});
const subsExpanding = accordion.panels[0].contentExpanding.subscribe(expArgs => {
argsIng = { event: expArgs.event, cancel: expArgs.cancel, owner: accordion, panel: expArgs.owner };
});
accordion.panels[0].expand();
tick();
fix.detectChanges();
expect(accordion.panelExpanding.emit).toHaveBeenCalledTimes(1);
expect(accordion.panelExpanding.emit).toHaveBeenCalledWith(argsIng);
expect(accordion.panelExpanded.emit).toHaveBeenCalledTimes(1);
expect(accordion.panelExpanded.emit).toHaveBeenCalledWith(argsEd);
subsExpanded.unsubscribe();
subsExpanding.unsubscribe();
const subsCollapsed = accordion.panels[0].contentCollapsed.subscribe(expArgs => {
argsEd = { event: expArgs.event, owner: accordion, panel: expArgs.owner };
});
const subsCollapsing = accordion.panels[0].contentCollapsing.subscribe(expArgs => {
argsIng = { event: expArgs.event, cancel: expArgs.cancel, owner: accordion, panel: expArgs.owner };
});
accordion.panels[0].collapse();
tick();
fix.detectChanges();
expect(accordion.panelCollapsing.emit).toHaveBeenCalledTimes(1);
expect(accordion.panelCollapsing.emit).toHaveBeenCalledWith(argsIng);
expect(accordion.panelCollapsed.emit).toHaveBeenCalledTimes(1);
expect(accordion.panelCollapsed.emit).toHaveBeenCalledWith(argsEd);
subsCollapsed.unsubscribe();
subsCollapsing.unsubscribe();
}));
it('Should focus the first/last panel on Home/End key press', () => {
accordion.panels[2].header.disabled = true;
fix.detectChanges();
accordion.panels[1].header.elementRef.nativeElement.dispatchEvent(new Event('pointerdown'));
fix.detectChanges();
UIInteractions.triggerKeyDownEvtUponElem('home', accordion.panels[1].header.innerElement);
fix.detectChanges();
expect(accordion.panels[0].header.innerElement).toBe(document.activeElement);
UIInteractions.triggerKeyDownEvtUponElem('end', accordion.panels[0].header.innerElement);
fix.detectChanges();
expect(accordion.panels[1].header.innerElement).toBe(document.activeElement);
});
it('Should focus the correct panel on ArrowDown/ArrowUp key pressed', () => {
accordion.panels[1].header.disabled = true;
fix.detectChanges();
accordion.panels[0].header.elementRef.nativeElement.children[0].dispatchEvent(new Event('pointerdown'));
fix.detectChanges();
// ArrowDown
UIInteractions.triggerKeyDownEvtUponElem('arrowdown', accordion.panels[0].header.innerElement);
fix.detectChanges();
expect(accordion.panels[2].header.innerElement).toBe(document.activeElement);
// ArrowUp
UIInteractions.triggerKeyDownEvtUponElem('arrowup', accordion.panels[2].header.innerElement);
fix.detectChanges();
expect(accordion.panels[0].header.innerElement).toBe(document.activeElement);
});
it(`Should expand/collapse all panels on SHIFT + ALT + ArrowDown/ArrowUp key pressed
when singleBranchExpanded is false`, fakeAsync(() => {
accordion.singleBranchExpand = false;
fix.detectChanges();
accordion.panels[1].header.disabled = true;
fix.detectChanges();
accordion.panels[0].header.elementRef.nativeElement.dispatchEvent(new Event('pointerdown'));
fix.detectChanges();
// SHIFT + ALT + ArrowDown
UIInteractions.triggerKeyDownEvtUponElem('arrowdown',
accordion.panels[0].header.innerElement, true, true, true, false);
tick();
fix.detectChanges();
expect(accordion.panels.filter(p => !p.collapsed && !p.header.disabled).length).toEqual(2);
expect(accordion.panels.filter(p => !p.collapsed).length).toEqual(3);
// SHIFT + ALT + ArrowUp
UIInteractions.triggerKeyDownEvtUponElem('arrowup',
accordion.panels[0].header.innerElement, true, true, true, false);
tick();
fix.detectChanges();
expect(accordion.panels.filter(p => p.collapsed && !p.header.disabled).length).toEqual(2);
expect(accordion.panels.filter(p => p.collapsed).length).toEqual(3);
}));
it(`Should do nothing/collapse the only panel on SHIFT + ALT + ArrowDown/ArrowUp key pressed
when singleBranchExpanded is true`, fakeAsync(() => {
accordion.singleBranchExpand = true;
fix.detectChanges();
accordion.panels[0].header.elementRef.nativeElement.dispatchEvent(new Event('pointerdown'));
fix.detectChanges();
// SHIFT + ALT + ArrowDown
UIInteractions.triggerKeyDownEvtUponElem('arrowdown',
accordion.panels[0].header.innerElement, true, true, true, false);
tick();
fix.detectChanges();
expect(accordion.panels.filter(p => !p.collapsed).length).toEqual(2);
// SHIFT + ALT + ArrowUp
UIInteractions.triggerKeyDownEvtUponElem('arrowup',
accordion.panels[0].header.innerElement, true, true, true, false);
tick();
fix.detectChanges();
expect(accordion.panels.filter(p => p.collapsed).length).toEqual(3);
}));
});
});
({
template: `
<igx-accordion>
<igx-expansion-panel id="html5" [collapsed]="true">
<igx-expansion-panel-header [disabled]="false">
<igx-expansion-panel-title>HTML5</igx-expansion-panel-title>
</igx-expansion-panel-header>
<igx-expansion-panel-body>
<igx-accordion>
<igx-expansion-panel>
<igx-expansion-panel-header [disabled]="false">
<igx-expansion-panel-title>First</igx-expansion-panel-title>
</igx-expansion-panel-header>
<igx-expansion-panel-body>
<div>
Content1
</div>
</igx-expansion-panel-body>
</igx-expansion-panel>
<igx-expansion-panel>
<igx-expansion-panel-header [disabled]="false">
<igx-expansion-panel-title>Second</igx-expansion-panel-title>
</igx-expansion-panel-header>
<igx-expansion-panel-body>
<div>
Content2
</div>
</igx-expansion-panel-body>
</igx-expansion-panel>
</igx-accordion>
</igx-expansion-panel-body>
</igx-expansion-panel>
<igx-expansion-panel id="css" [collapsed]="true">
<igx-expansion-panel-header [disabled]="false">
<igx-expansion-panel-title>CSS3</igx-expansion-panel-title>
</igx-expansion-panel-header>
<igx-expansion-panel-body>
<div>
Cascading Style Sheets (CSS) is a style sheet language used for
describing the presentation of a document written in a markup language
like HTML
</div>
</igx-expansion-panel-body>
</igx-expansion-panel>
<igx-expansion-panel id="scss" [collapsed]="false">
<igx-expansion-panel-header [disabled]="false">
<igx-expansion-panel-title>SASS/SCSS</igx-expansion-panel-title>
</igx-expansion-panel-header>
<igx-expansion-panel-body>
<div>
Sass is a preprocessor scripting language that is interpreted or
compiled into Cascading Style Sheets (CSS).
</div>
</igx-expansion-panel-body>
</igx-expansion-panel>
<igx-expansion-panel id="js" [collapsed]="false">
<igx-expansion-panel-header [disabled]="true">
<igx-expansion-panel-title>Javascript</igx-expansion-panel-title>
</igx-expansion-panel-header>
<igx-expansion-panel-body>
<div>
JavaScript is the world's most popular programming language.
JavaScript is the programming language of the Web.
</div>
</igx-expansion-panel-body>
</igx-expansion-panel>
<div *ngIf="divChild"></div>
</igx-accordion>
`,
standalone: true,
imports: [IgxAccordionComponent, IgxExpansionPanelComponent, IgxExpansionPanelHeaderComponent, IgxExpansionPanelBodyComponent, IgxExpansionPanelTitleDirective, NgIf]
})
export class IgxAccordionSampleTestComponent {
(IgxAccordionComponent) public accordion: IgxAccordionComponent;
public divChild = true;
}