Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(components/modals): confirm test harness #510

Merged
merged 10 commits into from
Sep 16, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export class SkyDataEntryGridDemoComponent {
columnDefs: this.columnDefs,
onGridReady: (gridReadyEvent) => this.onGridReady(gridReadyEvent),
};

this.gridOptions = this.agGridService.getGridOptions({
gridOptions: this.gridOptions,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<button
aria-haspopup="dialog"
class="sky-btn sky-btn-default sky-margin-inline-default"
class="sky-btn sky-btn-default sky-margin-inline-default ok-confirm-btn"
type="button"
(click)="openOKConfirm()"
>
Expand All @@ -9,7 +9,7 @@

<button
aria-haspopup="dialog"
class="sky-btn sky-btn-default sky-margin-inline-default"
class="sky-btn sky-btn-default sky-margin-inline-default two-action-confirm-btn"
type="button"
(click)="openTwoActionConfirm()"
>
Expand All @@ -34,11 +34,11 @@
Confirm with delete button
</button>

<p *ngIf="selectedAction && selectedText">
<p *ngIf="selectedAction && selectedText" class="displayed-text">
You selected the "{{ selectedText }}" button, which has an action of "{{
selectedAction
}}."
</p>
<p *ngIf="selectedAction && !selectedText">
<p *ngIf="selectedAction && !selectedText" class="displayed-text">
You selected the "{{ selectedAction }}" action.
</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { SkyConfirmHarness } from '@skyux/modals/testing';

import { ConfirmDemoComponent } from './confirm-demo.component';
import { ConfirmDemoModule } from './confirm-demo.module';

describe('Confirm demo', () => {
async function setupTest(confirmBtnClass: string) {
const fixture = TestBed.createComponent(ConfirmDemoComponent);
const openBtn = fixture.nativeElement.querySelector(confirmBtnClass);

openBtn.click();

const rootLoader = TestbedHarnessEnvironment.documentRootLoader(fixture);

const confirmHarness = await rootLoader.getHarness(SkyConfirmHarness);
return { confirmHarness, fixture };
}

beforeEach(() => {
TestBed.configureTestingModule({
imports: [ConfirmDemoModule, RouterTestingModule],
});
});

it('should show the correct text when OK is clicked on an OK confirm', async () => {
const { confirmHarness, fixture } = await setupTest('.ok-confirm-btn');

await confirmHarness.clickOkButton();

const displayedTextEl: HTMLElement =
fixture.nativeElement.querySelector('.displayed-text');

expect(displayedTextEl.innerText).toEqual('You selected the "ok" action.');
await expectAsync(confirmHarness.getMessageText()).toBeResolvedTo(
'Cannot delete invoice because it has vendor, credit memo, or purchase order activity.'
);
});

it('should show the correct text when "Finalize" is clicked on a custom confirm', async () => {
const { confirmHarness, fixture } = await setupTest(
'.two-action-confirm-btn'
);

await confirmHarness.clickCustomButton({ text: 'Finalize' });

const displayedTextEl: HTMLElement =
fixture.nativeElement.querySelector('.displayed-text');

expect(displayedTextEl.innerText).toEqual(
'You selected the "Finalize" button, which has an action of "save."'
);
await expectAsync(confirmHarness.getMessageText()).toBeResolvedTo(
'Finalize report cards?'
);
await expectAsync(confirmHarness.getBodyText()).toBeResolvedTo(
'Grades cannot be changed once the report cards are finalized.'
);
});
});
1 change: 1 addition & 0 deletions libs/components/modals/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
},
"homepage": "https://github.com/blackbaud/skyux#readme",
"peerDependencies": {
"@angular/cdk": "^13.3.2",
"@angular/common": "^13.3.2",
"@angular/core": "^13.3.2",
"@angular/router": "^13.3.2",
Expand Down
1 change: 1 addition & 0 deletions libs/components/modals/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
export * from './lib/modules/confirm/confirm-button';
export * from './lib/modules/confirm/confirm-button-action';
export * from './lib/modules/confirm/confirm-button-config';
export * from './lib/modules/confirm/confirm-button-style-type';
export * from './lib/modules/confirm/confirm-closed-event-args';
export * from './lib/modules/confirm/confirm-config';
export * from './lib/modules/confirm/confirm-instance';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type SkyConfirmButtonStyleType =
| 'primary'
| 'default'
| 'link'
| 'danger';
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { SkyConfirmButtonAction } from './confirm-button-action';
import { SkyConfirmButtonStyleType } from './confirm-button-style-type';

/**
* The view model for button configuration that the confirm component uses.
* @internal
*/
export interface SkyConfirmButton {
action: SkyConfirmButtonAction;
styleType: string;
// TODO: Remove 'string' in a breaking change.
styleType: SkyConfirmButtonStyleType | string;
text: string;
autofocus?: boolean;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="sky-confirm">
<div class="sky-confirm" [ngClass]="{ 'sky-confirm-type-ok': isOkType }">
<sky-modal ariaRole="alertdialog">
<sky-modal-content class="sky-confirm-content">
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export class SkyConfirmComponent {
public message: string;
public body: string | undefined;
public preserveWhiteSpace = false;
public isOkType = false;

#config: SkyConfirmConfig;
#modal: SkyModalInstance;
Expand Down Expand Up @@ -52,6 +53,7 @@ export class SkyConfirmComponent {
this.message = config.message;
this.body = config.body;
this.preserveWhiteSpace = !!config.preserveWhiteSpace;
this.isOkType = config.type === SkyConfirmType.OK;
}

public close(button: SkyConfirmButton) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { BaseHarnessFilters } from '@angular/cdk/testing';

/**
* A set of criteria that can be used to filter a list of SkyConfirmButtonHarness instances.
*/
export interface SkyConfirmButtonHarnessFilters
extends Omit<BaseHarnessFilters, 'selector'> {
/**
* Only find instances whose content matches the given value.
*/
text?: string | RegExp;

/**
* Only find instances whose style matches the given value.
*/
styleType?: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
import { SkyConfirmButtonStyleType } from '@skyux/modals';

import { SkyConfirmButtonHarnessFilters } from './confirm-button-harness-filters';

/**
* Harness for interacting with a confirm component in tests.
* @internal
*/
export class SkyConfirmButtonHarness extends ComponentHarness {
public static hostSelector = '.sky-confirm-buttons .sky-btn';

/**
* Gets a `HarnessPredicate` that can be used to search for a
* `SkyConfirmButtonHarness` that meets certain criteria.
*/
public static with(
filters: SkyConfirmButtonHarnessFilters
): HarnessPredicate<SkyConfirmButtonHarness> {
return new HarnessPredicate(SkyConfirmButtonHarness, filters)
.addOption('text', filters.text, async (harness, text) =>
HarnessPredicate.stringMatches(await harness.getText(), text)
)
.addOption('styleType', filters.styleType, async (harness, styleType) =>
HarnessPredicate.stringMatches(await harness.getStyleType(), styleType)
);
}

/**
* Clicks the confirm button.
*/
public async click(): Promise<void> {
return (await this.host()).click();
}

/**
* Gets the button style of the confirm button.
*/
public async getStyleType(): Promise<SkyConfirmButtonStyleType> {
Blackbaud-ErikaMcVey marked this conversation as resolved.
Show resolved Hide resolved
const hostEl = await this.host();

if (await hostEl.hasClass('sky-btn-primary')) {
return 'primary';
} else if (await hostEl.hasClass('sky-btn-link')) {
return 'link';
} else if (await hostEl.hasClass('sky-btn-danger')) {
return 'danger';
}
return 'default';
}

/**
* Gets the text content of the confirm button.
*/
public async getText(): Promise<string> {
return (await this.host()).text();
}
}
Loading