Skip to content

Commit

Permalink
feat(components/popovers): add support for custom trigger buttons to …
Browse files Browse the repository at this point in the history
…dropdown harness
  • Loading branch information
Blackbaud-PaulCrowder committed Feb 10, 2025
1 parent 7aa4225 commit 89631e3
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ import { SkyDropdownHarness } from './dropdown-harness';
<sky-dropdown-menu [ariaRole]="menuRole"></sky-dropdown-menu>
</sky-dropdown>
<sky-dropdown
data-sky-id="custom-trigger"
[disabled]="disabledFlag"
[label]="ariaLabel"
[title]="tooltipTitle"
>
<button type="button" skyDropdownTrigger></button>
<sky-dropdown-menu [ariaRole]="menuRole"></sky-dropdown-menu>
</sky-dropdown>
<sky-dropdown data-sky-id="other-dropdown" [buttonStyle]="'primary'">
<sky-dropdown-menu [ariaRole]="'otherDropdownMenu'"></sky-dropdown-menu>
</sky-dropdown>
Expand All @@ -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<TestDropdownComponent>;
loader: HarnessLoader;
Expand All @@ -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 {
Expand All @@ -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', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 89631e3

Please sign in to comment.