Skip to content

Commit 6e70cc7

Browse files
authored
feat(material/snackbar): add isDismissed harness method (#18766)
1 parent 8ec44a1 commit 6e70cc7

File tree

5 files changed

+34
-2
lines changed

5 files changed

+34
-2
lines changed

src/material/snack-bar/snack-bar-container.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ export class MatSnackBarContainer extends BasePortalOutlet implements OnDestroy
152152
// where multiple snack bars are opened in quick succession (e.g. two consecutive calls to
153153
// `MatSnackBar.open`).
154154
this._animationState = 'hidden';
155+
156+
// Mark this element with an 'exit' attribute to indicate that the snackbar has
157+
// been dismissed and will soon be removed from the DOM. This is used by the snackbar
158+
// test harness.
159+
this._elementRef.nativeElement.setAttribute('mat-exit', '');
160+
155161
return this._onExit;
156162
}
157163

src/material/snack-bar/snack-bar.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ describe('MatSnackBar', () => {
177177
snackBarRef.afterDismissed().subscribe({complete: dismissCompleteSpy});
178178

179179
snackBarRef.dismiss();
180+
const messageElement = overlayContainerElement.querySelector('snack-bar-container')!;
181+
expect (messageElement.hasAttribute('mat-exit'))
182+
.toBe(true, 'Expected the snackbar container to have the "exit" attribute upon dismiss');
183+
180184
viewContainerFixture.detectChanges(); // Run through animations for dismissal
181185
flush();
182186

src/material/snack-bar/testing/shared.spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,13 @@ export function runHarnessTests(
128128
let actionCount = 0;
129129
snackBarRef.onAction().subscribe(() => actionCount++);
130130

131+
expect(await snackBar.isDismissed())
132+
.toBe(false, 'The snackbar should be present in the DOM before dismiss');
133+
131134
await snackBar.dismissWithAction();
132135
expect(actionCount).toBe(1);
136+
expect(await snackBar.isDismissed())
137+
.toBe(true, 'The snackbar should be absent from the DOM after dismiss');
133138

134139
fixture.componentInstance.openSimple('No action');
135140
snackBar = await loader.getHarness(snackBarHarness);

src/material/snack-bar/testing/snack-bar-harness.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,29 @@ export class MatSnackBarHarness extends ComponentHarness {
7474
return (await this._simpleSnackBarMessage()).text();
7575
}
7676

77+
/** Gets whether the snack-bar has been dismissed. */
78+
async isDismissed(): Promise<boolean> {
79+
// We consider the snackbar dismissed if it's not in the DOM. We can assert that the
80+
// element isn't in the DOM by seeing that its width and height are zero.
81+
82+
const host = await this.host();
83+
const [exit, dimensions] = await Promise.all([
84+
// The snackbar container is marked with the "exit" attribute after it has been dismissed
85+
// but before the animation has finished (after which it's removed from the DOM).
86+
host.getAttribute('mat-exit'),
87+
host.getDimensions(),
88+
]);
89+
90+
return exit != null || (!!dimensions && dimensions.height === 0 && dimensions.width === 0);
91+
}
92+
7793
/**
7894
* Asserts that the current snack-bar does not use custom content. Promise rejects if
7995
* custom content is used.
8096
*/
8197
private async _assertSimpleSnackBar(): Promise<void> {
8298
if (!await this._isSimpleSnackBar()) {
83-
throw new Error('Method cannot be used for snack-bar with custom content.');
99+
throw Error('Method cannot be used for snack-bar with custom content.');
84100
}
85101
}
86102

@@ -91,7 +107,7 @@ export class MatSnackBarHarness extends ComponentHarness {
91107
private async _assertSimpleSnackBarWithAction(): Promise<void> {
92108
await this._assertSimpleSnackBar();
93109
if (!await this.hasAction()) {
94-
throw new Error('Method cannot be used for standard snack-bar without action.');
110+
throw Error('Method cannot be used for standard snack-bar without action.');
95111
}
96112
}
97113

tools/public_api_guard/material/snack-bar/testing.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export declare class MatSnackBarHarness extends ComponentHarness {
44
getMessage(): Promise<string>;
55
getRole(): Promise<'alert' | 'status' | null>;
66
hasAction(): Promise<boolean>;
7+
isDismissed(): Promise<boolean>;
78
static hostSelector: string;
89
static with(options?: SnackBarHarnessFilters): HarnessPredicate<MatSnackBarHarness>;
910
}

0 commit comments

Comments
 (0)