diff --git a/apps/code-examples/src/app/code-examples/toast/toast/basic/demo.component.spec.ts b/apps/code-examples/src/app/code-examples/toast/toast/basic/demo.component.spec.ts new file mode 100644 index 0000000000..ed4e83ae1c --- /dev/null +++ b/apps/code-examples/src/app/code-examples/toast/toast/basic/demo.component.spec.ts @@ -0,0 +1,58 @@ +import { HarnessLoader } from '@angular/cdk/testing'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { SkyToastType } from '@skyux/toast'; +import { SkyToasterHarness } from '@skyux/toast/testing'; + +import { DemoComponent } from './demo.component'; + +describe('Basic toast demo', () => { + let fixture: ComponentFixture; + let loader: HarnessLoader; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [DemoComponent, NoopAnimationsModule], + }); + + fixture = TestBed.createComponent(DemoComponent); + loader = TestbedHarnessEnvironment.documentRootLoader(fixture); + }); + + async function setupTest(): Promise<{ + toasterHarness: SkyToasterHarness; + }> { + fixture.componentInstance.openToast(); + fixture.detectChanges(); + + const toasterHarness: SkyToasterHarness = + await loader.getHarness(SkyToasterHarness); + + return { toasterHarness }; + } + + it('should open success toasts', async () => { + const { toasterHarness } = await setupTest(); + + fixture.componentInstance.openToast(); + fixture.detectChanges(); + + await expectAsync(toasterHarness.getNumberOfToasts()).toBeResolvedTo(2); + + const toast = await toasterHarness.getToastByMessage( + 'This is a sample toast message.', + ); + + await expectAsync(toast.getType()).toBeResolvedTo(SkyToastType.Success); + }); + + it('should close all toasts', async () => { + fixture.componentInstance.openToast(); + fixture.detectChanges(); + fixture.componentInstance.closeAll(); + fixture.detectChanges(); + + await expectAsync(loader.getHarness(SkyToasterHarness)).toBeRejected(); + }); +}); diff --git a/apps/code-examples/src/app/code-examples/toast/toast/basic/demo.component.ts b/apps/code-examples/src/app/code-examples/toast/toast/basic/demo.component.ts index d17e0c3fec..7184da9fb2 100644 --- a/apps/code-examples/src/app/code-examples/toast/toast/basic/demo.component.ts +++ b/apps/code-examples/src/app/code-examples/toast/toast/basic/demo.component.ts @@ -9,13 +9,13 @@ import { SkyToastService, SkyToastType } from '@skyux/toast'; export class DemoComponent { readonly #toastSvc = inject(SkyToastService); - protected openToast(): void { + public openToast(): void { this.#toastSvc.openMessage('This is a sample toast message.', { type: SkyToastType.Success, }); } - protected closeAll(): void { + public closeAll(): void { this.#toastSvc.closeAll(); } } diff --git a/apps/code-examples/src/app/code-examples/toast/toast/custom-component/custom-toast-harness.ts b/apps/code-examples/src/app/code-examples/toast/toast/custom-component/custom-toast-harness.ts new file mode 100644 index 0000000000..ec8f77d624 --- /dev/null +++ b/apps/code-examples/src/app/code-examples/toast/toast/custom-component/custom-toast-harness.ts @@ -0,0 +1,9 @@ +import { ComponentHarness } from '@angular/cdk/testing'; + +export class CustomToastHarness extends ComponentHarness { + public static hostSelector = 'app-toast-content-demo'; + + public async getText(): Promise { + return await (await this.host()).text(); + } +} diff --git a/apps/code-examples/src/app/code-examples/toast/toast/custom-component/demo.component.spec.ts b/apps/code-examples/src/app/code-examples/toast/toast/custom-component/demo.component.spec.ts new file mode 100644 index 0000000000..571024ee22 --- /dev/null +++ b/apps/code-examples/src/app/code-examples/toast/toast/custom-component/demo.component.spec.ts @@ -0,0 +1,56 @@ +import { HarnessLoader } from '@angular/cdk/testing'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { SkyToastType } from '@skyux/toast'; +import { SkyToasterHarness } from '@skyux/toast/testing'; + +import { CustomToastHarness } from './custom-toast-harness'; +import { DemoComponent } from './demo.component'; + +describe('Custom component toast demo', () => { + let fixture: ComponentFixture; + let loader: HarnessLoader; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [DemoComponent, NoopAnimationsModule], + }); + + fixture = TestBed.createComponent(DemoComponent); + loader = TestbedHarnessEnvironment.documentRootLoader(fixture); + }); + + async function setupTest(): Promise<{ + toasterHarness: SkyToasterHarness; + }> { + fixture.componentInstance.openToast(); + fixture.detectChanges(); + + const toasterHarness: SkyToasterHarness = + await loader.getHarness(SkyToasterHarness); + + return { toasterHarness }; + } + + it('should open custom component in toast', async () => { + const { toasterHarness } = await setupTest(); + + const toasts = await toasterHarness.getToasts(); + const customHarness = await toasts[0].queryHarness(CustomToastHarness); + + await expectAsync(toasts[0].getType()).toBeResolvedTo(SkyToastType.Success); + await expectAsync(customHarness.getText()).toBeResolvedTo( + 'Custom message: This toast has embedded a custom component for its content.', + ); + }); + + it('should close all toasts', async () => { + fixture.componentInstance.openToast(); + fixture.detectChanges(); + fixture.componentInstance.closeAll(); + fixture.detectChanges(); + + await expectAsync(loader.getHarness(SkyToasterHarness)).toBeRejected(); + }); +}); diff --git a/apps/code-examples/src/app/code-examples/toast/toast/custom-component/demo.component.ts b/apps/code-examples/src/app/code-examples/toast/toast/custom-component/demo.component.ts index 0c05c038d0..c37f24db1f 100644 --- a/apps/code-examples/src/app/code-examples/toast/toast/custom-component/demo.component.ts +++ b/apps/code-examples/src/app/code-examples/toast/toast/custom-component/demo.component.ts @@ -12,7 +12,7 @@ import { CustomToastComponent } from './custom-toast.component'; export class DemoComponent { readonly #toastSvc = inject(SkyToastService); - protected openToast(): void { + public openToast(): void { const context = new CustomToastContext( 'This toast has embedded a custom component for its content.', ); @@ -31,7 +31,7 @@ export class DemoComponent { ); } - protected closeAll(): void { + public closeAll(): void { this.#toastSvc.closeAll(); } } diff --git a/libs/components/code-examples/src/lib/modules/toast/toast/basic/example.component.spec.ts b/libs/components/code-examples/src/lib/modules/toast/toast/basic/example.component.spec.ts new file mode 100644 index 0000000000..7ca168fd04 --- /dev/null +++ b/libs/components/code-examples/src/lib/modules/toast/toast/basic/example.component.spec.ts @@ -0,0 +1,58 @@ +import { HarnessLoader } from '@angular/cdk/testing'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { SkyToastType } from '@skyux/toast'; +import { SkyToasterHarness } from '@skyux/toast/testing'; + +import { ToastBasicExampleComponent } from './example.component'; + +describe('Basic toast example', () => { + let fixture: ComponentFixture; + let loader: HarnessLoader; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ToastBasicExampleComponent, NoopAnimationsModule], + }); + + fixture = TestBed.createComponent(ToastBasicExampleComponent); + loader = TestbedHarnessEnvironment.documentRootLoader(fixture); + }); + + async function setupTest(): Promise<{ + toasterHarness: SkyToasterHarness; + }> { + fixture.componentInstance.openToast(); + fixture.detectChanges(); + + const toasterHarness: SkyToasterHarness = + await loader.getHarness(SkyToasterHarness); + + return { toasterHarness }; + } + + it('should open success toasts', async () => { + const { toasterHarness } = await setupTest(); + + fixture.componentInstance.openToast(); + fixture.detectChanges(); + + await expectAsync(toasterHarness.getNumberOfToasts()).toBeResolvedTo(2); + + const toast = await toasterHarness.getToastByMessage( + 'This is a sample toast message.', + ); + + await expectAsync(toast.getType()).toBeResolvedTo(SkyToastType.Success); + }); + + it('should close all toasts', async () => { + fixture.componentInstance.openToast(); + fixture.detectChanges(); + fixture.componentInstance.closeAll(); + fixture.detectChanges(); + + await expectAsync(loader.getHarness(SkyToasterHarness)).toBeRejected(); + }); +}); diff --git a/libs/components/code-examples/src/lib/modules/toast/toast/basic/example.component.ts b/libs/components/code-examples/src/lib/modules/toast/toast/basic/example.component.ts index 56acc5bb34..8f2abf5788 100644 --- a/libs/components/code-examples/src/lib/modules/toast/toast/basic/example.component.ts +++ b/libs/components/code-examples/src/lib/modules/toast/toast/basic/example.component.ts @@ -9,13 +9,13 @@ import { SkyToastService, SkyToastType } from '@skyux/toast'; export class ToastBasicExampleComponent { readonly #toastSvc = inject(SkyToastService); - protected openToast(): void { + public openToast(): void { this.#toastSvc.openMessage('This is a sample toast message.', { type: SkyToastType.Success, }); } - protected closeAll(): void { + public closeAll(): void { this.#toastSvc.closeAll(); } } diff --git a/libs/components/code-examples/src/lib/modules/toast/toast/custom-component/custom-toast-harness.ts b/libs/components/code-examples/src/lib/modules/toast/toast/custom-component/custom-toast-harness.ts new file mode 100644 index 0000000000..187dbf28e5 --- /dev/null +++ b/libs/components/code-examples/src/lib/modules/toast/toast/custom-component/custom-toast-harness.ts @@ -0,0 +1,9 @@ +import { ComponentHarness } from '@angular/cdk/testing'; + +export class CustomToastHarness extends ComponentHarness { + public static hostSelector = 'app-toast-content-example'; + + public async getText(): Promise { + return await (await this.host()).text(); + } +} diff --git a/libs/components/code-examples/src/lib/modules/toast/toast/custom-component/example.component.spec.ts b/libs/components/code-examples/src/lib/modules/toast/toast/custom-component/example.component.spec.ts new file mode 100644 index 0000000000..7a13790287 --- /dev/null +++ b/libs/components/code-examples/src/lib/modules/toast/toast/custom-component/example.component.spec.ts @@ -0,0 +1,56 @@ +import { HarnessLoader } from '@angular/cdk/testing'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { SkyToastType } from '@skyux/toast'; +import { SkyToasterHarness } from '@skyux/toast/testing'; + +import { CustomToastHarness } from './custom-toast-harness'; +import { ToastCustomComponentExampleComponent } from './example.component'; + +describe('Custom component toast demo', () => { + let fixture: ComponentFixture; + let loader: HarnessLoader; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ToastCustomComponentExampleComponent, NoopAnimationsModule], + }); + + fixture = TestBed.createComponent(ToastCustomComponentExampleComponent); + loader = TestbedHarnessEnvironment.documentRootLoader(fixture); + }); + + async function setupTest(): Promise<{ + toasterHarness: SkyToasterHarness; + }> { + fixture.componentInstance.openToast(); + fixture.detectChanges(); + + const toasterHarness: SkyToasterHarness = + await loader.getHarness(SkyToasterHarness); + + return { toasterHarness }; + } + + it('should open custom component in toast', async () => { + const { toasterHarness } = await setupTest(); + + const toasts = await toasterHarness.getToasts(); + const customHarness = await toasts[0].queryHarness(CustomToastHarness); + + await expectAsync(toasts[0].getType()).toBeResolvedTo(SkyToastType.Success); + await expectAsync(customHarness.getText()).toBeResolvedTo( + 'Custom message: This toast has embedded a custom component for its content.', + ); + }); + + it('should close all toasts', async () => { + fixture.componentInstance.openToast(); + fixture.detectChanges(); + fixture.componentInstance.closeAll(); + fixture.detectChanges(); + + await expectAsync(loader.getHarness(SkyToasterHarness)).toBeRejected(); + }); +}); diff --git a/libs/components/code-examples/src/lib/modules/toast/toast/custom-component/example.component.ts b/libs/components/code-examples/src/lib/modules/toast/toast/custom-component/example.component.ts index a9afc90841..c7a68ef8ff 100644 --- a/libs/components/code-examples/src/lib/modules/toast/toast/custom-component/example.component.ts +++ b/libs/components/code-examples/src/lib/modules/toast/toast/custom-component/example.component.ts @@ -12,7 +12,7 @@ import { CustomToastComponent } from './custom-toast.component'; export class ToastCustomComponentExampleComponent { readonly #toastSvc = inject(SkyToastService); - protected openToast(): void { + public openToast(): void { const context = new CustomToastContext( 'This toast has embedded a custom component for its content.', ); @@ -31,7 +31,7 @@ export class ToastCustomComponentExampleComponent { ); } - protected closeAll(): void { + public closeAll(): void { this.#toastSvc.closeAll(); } } diff --git a/libs/components/core/testing/src/modules/overlay/overlay-harness-filters.ts b/libs/components/core/testing/src/modules/overlay/overlay-harness-filters.ts index 7eb7d523b9..3931abfe90 100644 --- a/libs/components/core/testing/src/modules/overlay/overlay-harness-filters.ts +++ b/libs/components/core/testing/src/modules/overlay/overlay-harness-filters.ts @@ -1,8 +1,8 @@ -import { SkyHarnessFilters } from '../../shared/harness-filters'; +import { BaseHarnessFilters } from '@angular/cdk/testing'; /** * A set of criteria that can be used to filter a list of SkyOverlayHarness instances. * @internal */ // eslint-disable-next-line @typescript-eslint/no-empty-interface, @typescript-eslint/no-empty-object-type -export interface SkyOverlayHarnessFilters extends SkyHarnessFilters {} +export interface SkyOverlayHarnessFilters extends BaseHarnessFilters {} diff --git a/libs/components/toast/package.json b/libs/components/toast/package.json index 56bc56e693..7b8659b7db 100644 --- a/libs/components/toast/package.json +++ b/libs/components/toast/package.json @@ -17,6 +17,7 @@ "homepage": "https://github.com/blackbaud/skyux#readme", "peerDependencies": { "@angular/animations": "^19.0.5", + "@angular/cdk": "^19.0.4", "@angular/common": "^19.0.5", "@angular/core": "^19.0.5", "@angular/platform-browser": "^19.0.5", diff --git a/libs/components/toast/project.json b/libs/components/toast/project.json index 072faa208f..ef174553c7 100644 --- a/libs/components/toast/project.json +++ b/libs/components/toast/project.json @@ -24,7 +24,7 @@ "dependsOn": [ "^build", { - "projects": ["testing"], + "projects": ["core", "testing"], "target": "build" } ], diff --git a/libs/components/toast/src/lib/modules/toast/types/toast-config.ts b/libs/components/toast/src/lib/modules/toast/types/toast-config.ts index 35a526a324..49a4b053e3 100644 --- a/libs/components/toast/src/lib/modules/toast/types/toast-config.ts +++ b/libs/components/toast/src/lib/modules/toast/types/toast-config.ts @@ -8,7 +8,7 @@ import { SkyToastType } from './toast-type'; */ export interface SkyToastConfig { /** - * The `SkyToastType` type that determines the color and icon for the toast. This property defaults to `SkyToastType.Info`. + * The `SkyToastType` type that determines the color and icon for the toast. This property defaults to `Info`. */ type?: SkyToastType; diff --git a/libs/components/toast/testing/src/modules/toast-harness-filters.ts b/libs/components/toast/testing/src/modules/toast-harness-filters.ts new file mode 100644 index 0000000000..942bc258d0 --- /dev/null +++ b/libs/components/toast/testing/src/modules/toast-harness-filters.ts @@ -0,0 +1,12 @@ +import { BaseHarnessFilters } from '@angular/cdk/testing'; + +/** + * A set of criteria that can be used to filter a list of `SkyToastHarness` instances. + */ +// eslint-disable-next-line @typescript-eslint/no-empty-interface, @typescript-eslint/no-empty-object-type +export interface SkyToastHarnessFilters extends BaseHarnessFilters { + /** + * Finds toasts with the matching text. + */ + message?: string; +} diff --git a/libs/components/toast/testing/src/modules/toast-harness.ts b/libs/components/toast/testing/src/modules/toast-harness.ts new file mode 100644 index 0000000000..2625567fb6 --- /dev/null +++ b/libs/components/toast/testing/src/modules/toast-harness.ts @@ -0,0 +1,72 @@ +import { HarnessPredicate } from '@angular/cdk/testing'; +import { SkyQueryableComponentHarness } from '@skyux/core/testing'; +import { SkyToastType } from '@skyux/toast'; + +import { SkyToastHarnessFilters } from './toast-harness-filters'; + +/** + * Harness for interacting with the toast component in tests. + */ +export class SkyToastHarness extends SkyQueryableComponentHarness { + /** + * @internal + */ + public static hostSelector = 'sky-toast'; + + #getToast = this.locatorFor('.sky-toast'); + + /** + * Gets a `HarnessPredicate` that can be used to search for a + * `SkyToastHarness` that meets certain criteria. + */ + public static with( + filters: SkyToastHarnessFilters, + ): HarnessPredicate { + return new HarnessPredicate(SkyToastHarness, filters).addOption( + 'message', + filters.message, + async (harness, message) => { + const harnessMessage = await harness.getMessage(); + return await HarnessPredicate.stringMatches(message, harnessMessage); + }, + ); + } + + /** + * Clicks the toast close button. + */ + public async close(): Promise { + const button = await this.locatorFor('.sky-toast-btn-close')(); + return await button.click(); + } + + /** + * Gets the toast message. + */ + public async getMessage(): Promise { + const toastBody = await this.locatorForOptional('.sky-toast-body')(); + + if (toastBody) { + return (await toastBody.text()).trim(); + } else { + throw new Error( + 'No toast message found. This method cannot be used to query toasts with custom components.', + ); + } + } + + /** + * Gets the toast type. + */ + public async getType(): Promise { + const toast = await this.#getToast(); + if (await toast.hasClass('sky-toast-danger')) { + return SkyToastType.Danger; + } else if (await toast.hasClass('sky-toast-warning')) { + return SkyToastType.Warning; + } else if (await toast.hasClass('sky-toast-success')) { + return SkyToastType.Success; + } + return SkyToastType.Info; + } +} diff --git a/libs/components/toast/testing/src/modules/toaster-harness.spec.ts b/libs/components/toast/testing/src/modules/toaster-harness.spec.ts new file mode 100644 index 0000000000..94c8309249 --- /dev/null +++ b/libs/components/toast/testing/src/modules/toaster-harness.spec.ts @@ -0,0 +1,145 @@ +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { Component, inject } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { + SkyToastInstance, + SkyToastModule, + SkyToastService, + SkyToastType, +} from '@skyux/toast'; + +import { SkyToasterHarness } from './toaster-harness'; + +@Component({ + standalone: true, + imports: [SkyToastModule], + template: ``, +}) +class TestComponent { + public toastSvc = inject(SkyToastService); + + public openToast(message: string, type: SkyToastType): void { + this.toastSvc.openMessage(message, { type: type }); + } +} + +@Component({ + standalone: true, + template: `
This is a custom component
`, +}) +class CustomComponent { + readonly #instance = inject(SkyToastInstance); + + protected close(): void { + this.#instance.close(); + } +} + +describe('Toast harness', () => { + async function setupTest(): Promise<{ + harness: SkyToasterHarness; + fixture: ComponentFixture; + }> { + await TestBed.configureTestingModule({ + imports: [TestComponent, CustomComponent, NoopAnimationsModule], + }).compileComponents(); + + const fixture = TestBed.createComponent(TestComponent); + const loader = TestbedHarnessEnvironment.documentRootLoader(fixture); + + fixture.componentInstance.openToast('toast message', SkyToastType.Info); + + const harness: SkyToasterHarness = + await loader.getHarness(SkyToasterHarness); + + return { harness, fixture }; + } + + it('should get toasts', async () => { + const { harness } = await setupTest(); + + const toasts = await harness.getToasts(); + + expect(toasts.length).toBe(1); + }); + + it('should get toast by message', async () => { + const { harness, fixture } = await setupTest(); + + fixture.componentInstance.openToast('other message', SkyToastType.Danger); + fixture.detectChanges(); + + const toast = await harness.getToastByMessage('other message'); + + await expectAsync(toast.getType()).toBeResolvedTo(SkyToastType.Danger); + }); + + describe('toast harness', () => { + it('should close the toasts', async () => { + const { harness, fixture } = await setupTest(); + + fixture.componentInstance.openToast('other message', SkyToastType.Danger); + fixture.detectChanges(); + + await expectAsync(harness.getNumberOfToasts()).toBeResolvedTo(2); + + const toasts = await harness.getToasts(); + await toasts[0].close(); + + await expectAsync(harness.getNumberOfToasts()).toBeResolvedTo(1); + }); + + it('should get the toast message', async () => { + const { harness } = await setupTest(); + + const toasts = await harness.getToasts(); + + await expectAsync(toasts[0].getMessage()).toBeResolvedTo('toast message'); + }); + + it('should get the toast type', async () => { + const { harness, fixture } = await setupTest(); + + fixture.componentInstance.openToast('danger toast', SkyToastType.Danger); + fixture.detectChanges(); + fixture.componentInstance.openToast( + 'warning toast', + SkyToastType.Warning, + ); + fixture.detectChanges(); + fixture.componentInstance.openToast( + 'success toast', + SkyToastType.Success, + ); + fixture.detectChanges(); + + const toasts = await harness.getToasts(); + + await expectAsync(toasts[0].getType()).toBeResolvedTo(SkyToastType.Info); + await expectAsync(toasts[1].getType()).toBeResolvedTo( + SkyToastType.Danger, + ); + await expectAsync(toasts[2].getType()).toBeResolvedTo( + SkyToastType.Warning, + ); + await expectAsync(toasts[3].getType()).toBeResolvedTo( + SkyToastType.Success, + ); + }); + + describe('custom toast component', () => { + it('should not get message for a custom component', async () => { + const { harness, fixture } = await setupTest(); + fixture.componentInstance.toastSvc.openComponent(CustomComponent); + fixture.detectChanges(); + + await expectAsync( + harness.getToastByMessage('This is a custom component'), + ).toBeRejectedWithError( + 'No toast message found. This method cannot be used to query toasts with custom components.', + ); + }); + }); + }); +}); diff --git a/libs/components/toast/testing/src/modules/toaster-harness.ts b/libs/components/toast/testing/src/modules/toaster-harness.ts new file mode 100644 index 0000000000..242c186bbe --- /dev/null +++ b/libs/components/toast/testing/src/modules/toaster-harness.ts @@ -0,0 +1,32 @@ +import { ComponentHarness } from '@angular/cdk/testing'; + +import { SkyToastHarness } from './toast-harness'; + +/** + * Harness for interacting with the toast container component in tests. + */ +export class SkyToasterHarness extends ComponentHarness { + /** + * @internal + */ + public static hostSelector = 'sky-toaster'; + + public async getNumberOfToasts(): Promise { + const toasts = await this.getToasts(); + return toasts.length; + } + + /** + * Gets all open toast harnesses. + */ + public async getToasts(): Promise { + return await this.locatorForAll(SkyToastHarness)(); + } + + /** + * Gets a toast harness that matches the `message`. + */ + public async getToastByMessage(message: string): Promise { + return await this.locatorFor(SkyToastHarness.with({ message: message }))(); + } +} diff --git a/libs/components/toast/testing/src/public-api.ts b/libs/components/toast/testing/src/public-api.ts index 757dc6d812..816a9602ed 100644 --- a/libs/components/toast/testing/src/public-api.ts +++ b/libs/components/toast/testing/src/public-api.ts @@ -1 +1,5 @@ export { SkyToastFixture } from './legacy/toast-fixture'; + +export { SkyToasterHarness } from './modules/toaster-harness'; +export { SkyToastHarness } from './modules/toast-harness'; +export { SkyToastHarnessFilters } from './modules/toast-harness-filters';