From 89631e35d0368c40256a6d33b03f9a7c956d7956 Mon Sep 17 00:00:00 2001 From: Paul Crowder Date: Mon, 10 Feb 2025 12:45:35 -0500 Subject: [PATCH] feat(components/popovers): add support for custom trigger buttons to dropdown harness --- .../modules/dropdown/dropdown-harness.spec.ts | 250 ++++++++++-------- .../src/modules/dropdown/dropdown-harness.ts | 7 +- 2 files changed, 140 insertions(+), 117 deletions(-) diff --git a/libs/components/popovers/testing/src/modules/dropdown/dropdown-harness.spec.ts b/libs/components/popovers/testing/src/modules/dropdown/dropdown-harness.spec.ts index 4399cab2a7..6c88c1c854 100644 --- a/libs/components/popovers/testing/src/modules/dropdown/dropdown-harness.spec.ts +++ b/libs/components/popovers/testing/src/modules/dropdown/dropdown-harness.spec.ts @@ -20,6 +20,16 @@ import { SkyDropdownHarness } from './dropdown-harness'; + + + + + @@ -37,11 +47,7 @@ class TestDropdownComponent { // #endregion Test component describe('Dropdown test harness', () => { - async function setupTest( - options: { - dataSkyId?: string; - } = {}, - ): Promise<{ + async function setupTest(dataSkyId?: string): Promise<{ dropdownHarness: SkyDropdownHarness; fixture: ComponentFixture; loader: HarnessLoader; @@ -56,10 +62,10 @@ describe('Dropdown test harness', () => { let dropdownHarness: SkyDropdownHarness; - if (options.dataSkyId) { + if (dataSkyId) { dropdownHarness = await loader.getHarness( SkyDropdownHarness.with({ - dataSkyId: options.dataSkyId, + dataSkyId: dataSkyId, }), ); } else { @@ -69,166 +75,178 @@ describe('Dropdown test harness', () => { return { dropdownHarness, fixture, loader }; } - it('should get the dropdown from its data-sky-id', async () => { - const { dropdownHarness, fixture } = await setupTest({ - dataSkyId: 'other-dropdown', + function runTriggerTests(dataSkyId?: string): void { + it('should get the default value for disabled button', async () => { + const { dropdownHarness, fixture } = await setupTest(dataSkyId); + + fixture.detectChanges(); + + await expectAsync(dropdownHarness.isDisabled()).toBeResolvedTo(false); }); - fixture.detectChanges(); + it('should get the correct value for disabled button', async () => { + const { dropdownHarness, fixture } = await setupTest(dataSkyId); - await expectAsync(dropdownHarness.getButtonStyle()).toBeResolvedTo( - 'primary', - ); - }); + fixture.componentInstance.disabledFlag = true; + fixture.detectChanges(); - it('should get the default button style', async () => { - const { dropdownHarness, fixture } = await setupTest(); + await expectAsync(dropdownHarness.isDisabled()).toBeResolvedTo(true); - fixture.detectChanges(); + fixture.componentInstance.disabledFlag = false; + fixture.detectChanges(); - await expectAsync(dropdownHarness.getButtonStyle()).toBeResolvedTo( - 'default', - ); - }); + await expectAsync(dropdownHarness.isDisabled()).toBeResolvedTo(false); + }); - it('should get the button style', async () => { - const { dropdownHarness, fixture } = await setupTest(); - const styles = ['default', 'primary', 'link']; + it('should get the aria-label', async () => { + const { dropdownHarness, fixture } = await setupTest(dataSkyId); - for (const style of styles) { - fixture.componentInstance.buttonStyle = style; + fixture.componentInstance.ariaLabel = 'aria-label'; fixture.detectChanges(); - await expectAsync(dropdownHarness.getButtonStyle()).toBeResolvedTo(style); - } - }); - - it('should get default button type', async () => { - const { dropdownHarness, fixture } = await setupTest(); + await expectAsync(dropdownHarness.getAriaLabel()).toBeResolvedTo( + 'aria-label', + ); + }); - fixture.detectChanges(); + it('should have no tooltip if undefined', async () => { + const { dropdownHarness, fixture } = await setupTest(dataSkyId); - await expectAsync(dropdownHarness.getButtonType()).toBeResolvedTo('select'); - }); + fixture.detectChanges(); - it('should get the button type', async () => { - const { dropdownHarness, fixture } = await setupTest(); + await expectAsync(dropdownHarness.getTitle()).toBeResolvedTo(null); + }); - const types = ['select', 'tab', 'context-menu']; + it('should get the tooltip title', async () => { + const { dropdownHarness, fixture } = await setupTest(); - for (const type of types) { - fixture.componentInstance.buttonType = type; + fixture.componentInstance.tooltipTitle = 'dropdown demo'; fixture.detectChanges(); - await expectAsync(dropdownHarness.getButtonType()).toBeResolvedTo(type); - } - }); + await expectAsync(dropdownHarness.getTitle()).toBeResolvedTo( + 'dropdown demo', + ); + }); - it('should get the default value for disabled button', async () => { - const { dropdownHarness, fixture } = await setupTest(); + it('should get the correct value if dropdown menu is open or not', async () => { + const { dropdownHarness, fixture } = await setupTest(dataSkyId); - fixture.detectChanges(); + fixture.detectChanges(); - await expectAsync(dropdownHarness.isDisabled()).toBeResolvedTo(false); - }); + await expectAsync(dropdownHarness.isOpen()).toBeResolvedTo(false); - it('should get the correct value for disabled button', async () => { - const { dropdownHarness, fixture } = await setupTest(); + await dropdownHarness.clickDropdownButton(); + fixture.detectChanges(); - fixture.componentInstance.disabledFlag = true; - fixture.detectChanges(); + await expectAsync(dropdownHarness.isOpen()).toBeResolvedTo(true); - await expectAsync(dropdownHarness.isDisabled()).toBeResolvedTo(true); + await dropdownHarness.clickDropdownButton(); + fixture.detectChanges(); - fixture.componentInstance.disabledFlag = false; - fixture.detectChanges(); + await expectAsync(dropdownHarness.isOpen()).toBeResolvedTo(false); + }); - await expectAsync(dropdownHarness.isDisabled()).toBeResolvedTo(false); - }); + it('should close the dropdown menu if clicking out', async () => { + const { dropdownHarness, fixture } = await setupTest(dataSkyId); - it('should have default aria-label for context menus', async () => { - const { dropdownHarness, fixture } = await setupTest(); - fixture.componentInstance.buttonType = 'context-menu'; + fixture.detectChanges(); + await dropdownHarness.clickDropdownButton(); + fixture.detectChanges(); + await (await dropdownHarness.getDropdownMenu()).clickOut(); - fixture.detectChanges(); + await expectAsync(dropdownHarness.isOpen()).toBeResolvedTo(false); + }); - await expectAsync(dropdownHarness.getAriaLabel()).toBeResolvedTo( - 'Context menu', - ); - }); + it('should get the dropdown menu harness', async () => { + const { dropdownHarness, fixture } = await setupTest(dataSkyId); - it('should get the aria-label', async () => { - const { dropdownHarness, fixture } = await setupTest(); + fixture.componentInstance.menuRole = 'dropdown-menu'; + fixture.detectChanges(); + await dropdownHarness.clickDropdownButton(); + fixture.detectChanges(); - fixture.componentInstance.ariaLabel = 'aria-label'; - fixture.detectChanges(); + const dropdownMenuHarness = await dropdownHarness.getDropdownMenu(); - await expectAsync(dropdownHarness.getAriaLabel()).toBeResolvedTo( - 'aria-label', - ); - }); + await expectAsync(dropdownMenuHarness.getAriaRole()).toBeResolvedTo( + 'dropdown-menu', + ); + }); + } - it('should have no tooltip if undefined', async () => { - const { dropdownHarness, fixture } = await setupTest(); + describe('with default trigger button', () => { + it('should get the dropdown from its data-sky-id', async () => { + const { dropdownHarness, fixture } = await setupTest('other-dropdown'); - fixture.detectChanges(); + fixture.detectChanges(); - await expectAsync(dropdownHarness.getTitle()).toBeResolvedTo(null); - }); + await expectAsync(dropdownHarness.getButtonStyle()).toBeResolvedTo( + 'primary', + ); + }); - it('should get the tooltip title', async () => { - const { dropdownHarness, fixture } = await setupTest(); + it('should get the default button style', async () => { + const { dropdownHarness, fixture } = await setupTest(); - fixture.componentInstance.tooltipTitle = 'dropdown demo'; - fixture.detectChanges(); + fixture.detectChanges(); - await expectAsync(dropdownHarness.getTitle()).toBeResolvedTo( - 'dropdown demo', - ); - }); + await expectAsync(dropdownHarness.getButtonStyle()).toBeResolvedTo( + 'default', + ); + }); - it('should get the correct value if dropdown menu is open or not', async () => { - const { dropdownHarness, fixture } = await setupTest(); + it('should get the button style', async () => { + const { dropdownHarness, fixture } = await setupTest(); + const styles = ['default', 'primary', 'link']; - fixture.detectChanges(); + for (const style of styles) { + fixture.componentInstance.buttonStyle = style; + fixture.detectChanges(); - await expectAsync(dropdownHarness.isOpen()).toBeResolvedTo(false); + await expectAsync(dropdownHarness.getButtonStyle()).toBeResolvedTo( + style, + ); + } + }); - await dropdownHarness.clickDropdownButton(); - fixture.detectChanges(); + it('should get default button type', async () => { + const { dropdownHarness, fixture } = await setupTest(); - await expectAsync(dropdownHarness.isOpen()).toBeResolvedTo(true); + fixture.detectChanges(); - await dropdownHarness.clickDropdownButton(); - fixture.detectChanges(); + await expectAsync(dropdownHarness.getButtonType()).toBeResolvedTo( + 'select', + ); + }); - await expectAsync(dropdownHarness.isOpen()).toBeResolvedTo(false); - }); + it('should get the button type', async () => { + const { dropdownHarness, fixture } = await setupTest(); - it('should close the dropdown menu if clicking out', async () => { - const { dropdownHarness, fixture } = await setupTest(); + const types = ['select', 'tab', 'context-menu']; - fixture.detectChanges(); - await dropdownHarness.clickDropdownButton(); - fixture.detectChanges(); - await (await dropdownHarness.getDropdownMenu()).clickOut(); + for (const type of types) { + fixture.componentInstance.buttonType = type; + fixture.detectChanges(); - await expectAsync(dropdownHarness.isOpen()).toBeResolvedTo(false); - }); + await expectAsync(dropdownHarness.getButtonType()).toBeResolvedTo(type); + } + }); - it('should get the dropdown menu harness', async () => { - const { dropdownHarness, fixture } = await setupTest(); + it('should have default aria-label for context menus', async () => { + const { dropdownHarness, fixture } = await setupTest(); + fixture.componentInstance.buttonType = 'context-menu'; - fixture.componentInstance.menuRole = 'dropdown-menu'; - fixture.detectChanges(); - await dropdownHarness.clickDropdownButton(); - fixture.detectChanges(); + fixture.detectChanges(); - const dropdownMenuHarness = await dropdownHarness.getDropdownMenu(); + await expectAsync(dropdownHarness.getAriaLabel()).toBeResolvedTo( + 'Context menu', + ); + }); + + runTriggerTests(); + }); - await expectAsync(dropdownMenuHarness.getAriaRole()).toBeResolvedTo( - 'dropdown-menu', - ); + describe('with custom trigger button', () => { + runTriggerTests('custom-trigger'); }); describe('Dropdown menu test harness', () => { diff --git a/libs/components/popovers/testing/src/modules/dropdown/dropdown-harness.ts b/libs/components/popovers/testing/src/modules/dropdown/dropdown-harness.ts index bca1a46b7c..152aaccadd 100644 --- a/libs/components/popovers/testing/src/modules/dropdown/dropdown-harness.ts +++ b/libs/components/popovers/testing/src/modules/dropdown/dropdown-harness.ts @@ -12,7 +12,12 @@ export class SkyDropdownHarness extends SkyComponentHarness { #documentRootLocator = this.documentRootLocatorFactory(); - #getDropdownButton = this.locatorFor('.sky-dropdown-button'); + #getDropdownButton = this.locatorFor( + // Default trigger button + '.sky-dropdown-button', + // Custom trigger button + '[skyDropdownTrigger]', + ); /** * Gets a `HarnessPredicate` that can be used to search for a