import {ComponentHarness, HarnessLoader, parallel} from '@angular/cdk/testing'; import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed'; import {Component} from '@angular/core'; import {ComponentFixture, TestBed} from '@angular/core/testing'; import {MatAccordionTogglePosition, MatExpansionModule} from '@angular/material/expansion'; import {NoopAnimationsModule} from '@angular/platform-browser/animations'; import {MatAccordionHarness} from './accordion-harness'; import {MatExpansionPanelHarness} from './expansion-harness'; describe('MatExpansionHarness', () => { let fixture: ComponentFixture; let loader: HarnessLoader; beforeEach(() => { TestBed.configureTestingModule({ imports: [MatExpansionModule, NoopAnimationsModule, ExpansionHarnessTestComponent], }); fixture = TestBed.createComponent(ExpansionHarnessTestComponent); fixture.detectChanges(); loader = TestbedHarnessEnvironment.loader(fixture); }); it('should be able to load accordion', async () => { const accordions = await loader.getAllHarnesses(MatAccordionHarness); expect(accordions.length).toBe(2); }); it('should be able to load an accordion by selector', async () => { const accordions = await loader.getAllHarnesses( MatAccordionHarness.with({selector: '#accordion2'}), ); expect(accordions.length).toBe(1); }); it('should be able to load expansion panels', async () => { const panels = await loader.getAllHarnesses(MatExpansionPanelHarness); expect(panels.length).toBe(5); }); it('should be able to load expansion panel by title matching regex', async () => { const panels = await loader.getAllHarnesses(MatExpansionPanelHarness.with({title: /Panel#2/})); expect(panels.length).toBe(1); expect(await panels[0].getTitle()).toBe('Title of Panel#2'); }); it('should be able to load expansion panel by title matching exact text', async () => { const panels = await loader.getAllHarnesses( MatExpansionPanelHarness.with({title: 'Standalone Panel Title'}), ); expect(panels.length).toBe(1); expect(await panels[0].getTitle()).toBe('Standalone Panel Title'); }); it('should be able to load expansion panel without title', async () => { const panels = await loader.getAllHarnesses(MatExpansionPanelHarness.with({title: null})); expect(panels.length).toBe(1); }); it('should be able to load expansion panel by description matching regex', async () => { const panels = await loader.getAllHarnesses( MatExpansionPanelHarness.with({description: /Panel#2/}), ); expect(panels.length).toBe(1); expect(await panels[0].getDescription()).toBe('Description of Panel#2'); }); it('should be able to load expansion panel by description matching exact text', async () => { const panels = await loader.getAllHarnesses( MatExpansionPanelHarness.with({description: 'Description of Panel#1'}), ); expect(panels.length).toBe(1); expect(await panels[0].getDescription()).toBe('Description of Panel#1'); }); it('should be able to load expansion panel without description', async () => { const panels = await loader.getAllHarnesses(MatExpansionPanelHarness.with({description: null})); expect(panels.length).toBe(3); }); it('should be able to load expanded panels', async () => { const panels = await loader.getAllHarnesses(MatExpansionPanelHarness.with({expanded: true})); expect(panels.length).toBe(2); expect(await panels[0].getTitle()).toBe('Title of Panel#2'); expect(await panels[1].getTitle()).toBe('Standalone Panel Title'); }); it('should be able to load collapsed panels', async () => { const panels = await loader.getAllHarnesses(MatExpansionPanelHarness.with({expanded: false})); expect(panels.length).toBe(3); expect(await panels[0].getTitle()).toBe('Title of Panel#1'); expect(await panels[1].getTextContent()).toBe('Accordion #2 - Content'); expect(await panels[2].getTitle()).toBe('Disabled Panel Title'); }); it('should be able to load expansion panel by content matching regex', async () => { const panels = await loader.getAllHarnesses( MatExpansionPanelHarness.with({content: /Accordion #2/}), ); expect(panels.length).toBe(1); expect(await panels[0].getTextContent()).toBe('Accordion #2 - Content'); }); it('should be able to load expansion panel by content matching exact string', async () => { const panels = await loader.getAllHarnesses( MatExpansionPanelHarness.with({content: 'Content of Panel#2'}), ); expect(panels.length).toBe(1); expect(await panels[0].getTextContent()).toBe('Content of Panel#2'); }); it('should be able to load expansion panels based on disabled state', async () => { const panels = await loader.getAllHarnesses(MatExpansionPanelHarness.with({disabled: true})); expect(panels.length).toBe(1); expect(await panels[0].getTitle()).toBe('Disabled Panel Title'); }); it('should be able to get expansion state of panel', async () => { const panel = await loader.getHarness(MatExpansionPanelHarness.with({title: /Panel#1/})); expect(await panel.isExpanded()).toBe(false); fixture.componentInstance.panel1Expanded = true; fixture.changeDetectorRef.markForCheck(); expect(await panel.isExpanded()).toBe(true); }); it('should be able to get title of panel', async () => { const panel = await loader.getHarness(MatExpansionPanelHarness.with({content: /Panel#1/})); expect(await panel.getTitle()).toBe('Title of Panel#1'); fixture.componentInstance.panel1Title = 'new title'; fixture.changeDetectorRef.markForCheck(); expect(await panel.getTitle()).toBe('new title'); }); it('should be able to get description of panel', async () => { const panel = await loader.getHarness(MatExpansionPanelHarness.with({content: /Panel#1/})); expect(await panel.getDescription()).toBe('Description of Panel#1'); fixture.componentInstance.panel1Description = 'new description'; fixture.changeDetectorRef.markForCheck(); expect(await panel.getDescription()).toBe('new description'); }); it('should be able to get disabled state of panel', async () => { const panel = await loader.getHarness( MatExpansionPanelHarness.with({selector: '#disabledPanel'}), ); expect(await panel.isDisabled()).toBe(true); fixture.componentInstance.isDisabled = false; fixture.changeDetectorRef.markForCheck(); expect(await panel.isDisabled()).toBe(false); }); it('should be able to toggle expansion state of panel', async () => { const panel = await loader.getHarness(MatExpansionPanelHarness); expect(await panel.isExpanded()).toBe(false); await panel.toggle(); expect(await panel.isExpanded()).toBe(true); }); it('should be able to expand a panel', async () => { const panel = await loader.getHarness(MatExpansionPanelHarness); expect(await panel.isExpanded()).toBe(false); await panel.expand(); expect(await panel.isExpanded()).toBe(true); // checking a second time to ensure it does not modify // the state if already expanded. await panel.expand(); expect(await panel.isExpanded()).toBe(true); }); it('should be able to collapse a panel', async () => { const panel = await loader.getHarness(MatExpansionPanelHarness); expect(await panel.isExpanded()).toBe(false); await panel.expand(); expect(await panel.isExpanded()).toBe(true); await panel.collapse(); expect(await panel.isExpanded()).toBe(false); // checking a second time to ensure it does not modify // the state if already collapsed. await panel.collapse(); expect(await panel.isExpanded()).toBe(false); }); it('should be able to get text content of expansion panel', async () => { const panel = await loader.getHarness(MatExpansionPanelHarness); expect(await panel.getTextContent()).toBe('Content of Panel#1'); fixture.componentInstance.panel1Content = 'new content'; fixture.changeDetectorRef.markForCheck(); expect(await panel.getTextContent()).toBe('new content'); }); it('should be able to get harness loader for content of panel', async () => { const panel = await loader.getHarness( MatExpansionPanelHarness.with({selector: '#standalonePanel'}), ); const matchedHarnesses = await panel.getAllHarnesses(TestContentHarness); expect(matchedHarnesses.length).toBe(1); expect(await matchedHarnesses[0].getText()).toBe('Part of expansion panel'); }); it('should be able to focus expansion panel', async () => { const panel = await loader.getHarness(MatExpansionPanelHarness); expect(getActiveElementTag()).not.toBe('mat-expansion-panel-header'); await panel.focus(); expect(getActiveElementTag()).toBe('mat-expansion-panel-header'); }); it('should be able to blur expansion panel', async () => { const panel = await loader.getHarness(MatExpansionPanelHarness); await panel.focus(); expect(getActiveElementTag()).toBe('mat-expansion-panel-header'); await panel.blur(); expect(getActiveElementTag()).not.toBe('mat-expansion-panel-header'); }); it('should be able to check if expansion panel has toggle indicator', async () => { const accordion = await loader.getHarness(MatAccordionHarness); const standalonePanel = await loader.getHarness( MatExpansionPanelHarness.with({selector: '#standalonePanel'}), ); const expansionPanels = [standalonePanel, ...(await accordion.getExpansionPanels())]; let toggleIndicatorChecks = await parallel(() => { return expansionPanels.map(p => p.hasToggleIndicator()); }); expect(toggleIndicatorChecks.every(s => s)).toBe(true); fixture.componentInstance.hideToggleIndicators = true; fixture.changeDetectorRef.markForCheck(); toggleIndicatorChecks = await parallel(() => expansionPanels.map(p => p.hasToggleIndicator())); expect(toggleIndicatorChecks.every(s => !s)).toBe(true); }); it('should be able to get toggle indicator position of panels', async () => { const accordion = await loader.getHarness(MatAccordionHarness); const standalonePanel = await loader.getHarness( MatExpansionPanelHarness.with({selector: '#standalonePanel'}), ); const expansionPanels = [standalonePanel, ...(await accordion.getExpansionPanels())]; let togglePositions = await parallel(() => expansionPanels.map(p => p.getToggleIndicatorPosition()), ); expect(togglePositions.every(p => p === 'after')).toBe(true); fixture.componentInstance.toggleIndicatorsPosition = 'before'; fixture.changeDetectorRef.markForCheck(); togglePositions = await parallel(() => { return expansionPanels.map(p => p.getToggleIndicatorPosition()); }); expect(togglePositions.every(p => p === 'before')).toBe(true); }); it('should be able to get expansion panels of accordion', async () => { const accordion = await loader.getHarness(MatAccordionHarness); const panels = await accordion.getExpansionPanels(); expect(panels.length).toBe(2); expect(await panels[0].getTitle()).toBe('Title of Panel#1'); expect(await panels[1].getTitle()).toBe('Title of Panel#2'); }); it('should be able to get expansion panels of accordion with filter', async () => { const accordion = await loader.getHarness(MatAccordionHarness); const panels = await accordion.getExpansionPanels({title: /Panel#1/}); expect(panels.length).toBe(1); expect(await panels[0].getTitle()).toBe('Title of Panel#1'); }); it('should be able to check if accordion has multi panel support enabled', async () => { const accordion = await loader.getHarness(MatAccordionHarness); expect(await accordion.isMulti()).toBe(false); fixture.componentInstance.multiMode = true; fixture.changeDetectorRef.markForCheck(); expect(await accordion.isMulti()).toBe(true); }); }); function getActiveElementTag() { return document.activeElement ? document.activeElement.tagName.toLowerCase() : ''; } @Component({ template: ` {{panel1Title}} {{panel1Description}} {{panel1Content}} Title of Panel#2 Description of Panel#2 Content of Panel#2 Accordion #2 - Header

Accordion #2 - Content

Standalone Panel Title
Standalone Panel Body
Part of expansion panel
Disabled Panel Title
Outside of expansion panel
`, standalone: true, imports: [MatExpansionModule], }) class ExpansionHarnessTestComponent { panel1Expanded = false; panel1Title = 'Title of Panel#1'; panel1Description = 'Description of Panel#1'; panel1Content = 'Content of Panel#1'; hideToggleIndicators = false; toggleIndicatorsPosition: MatAccordionTogglePosition; isDisabled = true; multiMode = false; } class TestContentHarness extends ComponentHarness { static hostSelector = '.test-content-harness'; async getText() { return (await this.host()).text(); } }