Skip to content

Commit 3dc5af4

Browse files
authored
feat(material/dialog): add support for content sections in harness (#23357)
* feat(material/dialog): add support for content sections in harness * feat(material/dialog): add support for content sections in harness
1 parent 57273f3 commit 3dc5af4

File tree

5 files changed

+86
-6
lines changed

5 files changed

+86
-6
lines changed

src/material-experimental/mdc-dialog/testing/dialog-harness.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ import {
1212
MatDialogHarness as NonMdcDialogHarness
1313
} from '@angular/material/dialog/testing';
1414

15+
/** Selectors for different sections of the mat-dialog that can contain user content. */
16+
export const enum MatDialogSection {
17+
TITLE = '.mat-mdc-dialog-title',
18+
CONTENT = '.mat-mdc-dialog-content',
19+
ACTIONS = '.mat-mdc-dialog-actions'
20+
}
21+
1522
/** Harness for interacting with a standard `MatDialog` in tests. */
1623
export class MatDialogHarness extends NonMdcDialogHarness {
1724
/** The selector for the host element of a `MatDialog` instance. */
@@ -26,4 +33,8 @@ export class MatDialogHarness extends NonMdcDialogHarness {
2633
static override with(options: DialogHarnessFilters = {}): HarnessPredicate<MatDialogHarness> {
2734
return new HarnessPredicate(MatDialogHarness, options);
2835
}
36+
37+
protected override _title = this.locatorForOptional(MatDialogSection.TITLE);
38+
protected override _content = this.locatorForOptional(MatDialogSection.CONTENT);
39+
protected override _actions = this.locatorForOptional(MatDialogSection.ACTIONS);
2940
}

src/material-experimental/mdc-dialog/testing/public-api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
*/
88

99
export {DialogHarnessFilters} from '@angular/material/dialog/testing';
10-
export {MatDialogHarness} from './dialog-harness';
10+
export {MatDialogHarness, MatDialogSection} from './dialog-harness';

src/material/dialog/testing/dialog-harness.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,26 @@ import {ContentContainerComponentHarness, HarnessPredicate, TestKey} from '@angu
1010
import {DialogRole} from '@angular/material/dialog';
1111
import {DialogHarnessFilters} from './dialog-harness-filters';
1212

13+
/** Selectors for different sections of the mat-dialog that can contain user content. */
14+
export const enum MatDialogSection {
15+
TITLE = '.mat-dialog-title',
16+
CONTENT = '.mat-dialog-content',
17+
ACTIONS = '.mat-dialog-actions'
18+
}
19+
20+
// @breaking-change 14.0.0 change generic type to MatDialogSection.
1321
/** Harness for interacting with a standard `MatDialog` in tests. */
14-
export class MatDialogHarness extends ContentContainerComponentHarness<string> {
22+
export class MatDialogHarness extends ContentContainerComponentHarness<MatDialogSection | string> {
1523
// Developers can provide a custom component or template for the
1624
// dialog. The canonical dialog parent is the "MatDialogContainer".
1725
/** The selector for the host element of a `MatDialog` instance. */
1826
static hostSelector = '.mat-dialog-container';
1927

28+
protected _title = this.locatorForOptional(MatDialogSection.TITLE);
29+
protected _content = this.locatorForOptional(MatDialogSection.CONTENT);
30+
protected _actions = this.locatorForOptional(MatDialogSection.ACTIONS);
31+
32+
2033
/**
2134
* Gets a `HarnessPredicate` that can be used to search for a `MatDialogHarness` that meets
2235
* certain criteria.
@@ -63,4 +76,24 @@ export class MatDialogHarness extends ContentContainerComponentHarness<string> {
6376
async close(): Promise<void> {
6477
await (await this.host()).sendKeys(TestKey.ESCAPE);
6578
}
79+
80+
/** Gets te dialog's text. */
81+
async getText() {
82+
return (await this.host()).text();
83+
}
84+
85+
/** Gets the dialog's title text. This only works if the dialog is using mat-dialog-title. */
86+
async getTitleText() {
87+
return (await this._title())?.text() ?? '';
88+
}
89+
90+
/** Gets the dialog's content text. This only works if the dialog is using mat-dialog-content. */
91+
async getContentText() {
92+
return (await this._content())?.text() ?? '';
93+
}
94+
95+
/** Gets the dialog's actions text. This only works if the dialog is using mat-dialog-actions. */
96+
async getActionsText() {
97+
return (await this._actions())?.text() ?? '';
98+
}
6699
}

src/material/dialog/testing/shared.spec.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export function runHarnessTests(
9595
fixture.componentInstance.open();
9696
fixture.componentInstance.open({ariaLabelledBy: 'dialog-label'});
9797
const dialogs = await loader.getAllHarnesses(dialogHarness);
98-
expect(await dialogs[0].getAriaLabelledby()).toBe(null);
98+
expect(await dialogs[0].getAriaLabelledby()).toMatch(/-dialog-title-\d+/);
9999
expect(await dialogs[1].getAriaLabelledby()).toBe('dialog-label');
100100
});
101101

@@ -124,12 +124,26 @@ export function runHarnessTests(
124124
expect(dialogs.length).toBe(1);
125125
});
126126

127+
it('should get the text content of each section', async () => {
128+
fixture.componentInstance.open();
129+
const dialog = await loader.getHarness(dialogHarness);
130+
expect(await dialog.getText()).toBe(`I'm the dialog titleI'm the dialog contentCancelOk`);
131+
expect(await dialog.getTitleText()).toBe(`I'm the dialog title`);
132+
expect(await dialog.getContentText()).toBe(`I'm the dialog content`);
133+
expect(await dialog.getActionsText()).toBe(`CancelOk`);
134+
});
135+
127136
@Component({
128137
template: `
129138
<ng-template>
130-
Hello from the dialog!
139+
<div matDialogTitle>I'm the dialog title</div>
140+
<div matDialogContent>I'm the dialog content</div>
141+
<div matDialogActions>
142+
<button>Cancel</button>
143+
<button>Ok</button>
144+
</div>
131145
</ng-template>
132-
`
146+
`
133147
})
134148
class DialogHarnessTest {
135149
@ViewChild(TemplateRef) dialogTmpl: TemplateRef<any>;

tools/public_api_guard/material/dialog-testing.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,49 @@
44
55
```ts
66

7+
import { AsyncFactoryFn } from '@angular/cdk/testing';
78
import { BaseHarnessFilters } from '@angular/cdk/testing';
89
import { ContentContainerComponentHarness } from '@angular/cdk/testing';
910
import { DialogRole } from '@angular/material/dialog';
1011
import { HarnessPredicate } from '@angular/cdk/testing';
12+
import { TestElement } from '@angular/cdk/testing';
1113

1214
// @public
1315
export interface DialogHarnessFilters extends BaseHarnessFilters {
1416
}
1517

1618
// @public
17-
export class MatDialogHarness extends ContentContainerComponentHarness<string> {
19+
export class MatDialogHarness extends ContentContainerComponentHarness<MatDialogSection | string> {
20+
// (undocumented)
21+
protected _actions: AsyncFactoryFn<TestElement | null>;
1822
close(): Promise<void>;
23+
// (undocumented)
24+
protected _content: AsyncFactoryFn<TestElement | null>;
25+
getActionsText(): Promise<string>;
1926
getAriaDescribedby(): Promise<string | null>;
2027
getAriaLabel(): Promise<string | null>;
2128
getAriaLabelledby(): Promise<string | null>;
29+
getContentText(): Promise<string>;
2230
getId(): Promise<string | null>;
2331
getRole(): Promise<DialogRole | null>;
32+
getText(): Promise<string>;
33+
getTitleText(): Promise<string>;
2434
static hostSelector: string;
35+
// (undocumented)
36+
protected _title: AsyncFactoryFn<TestElement | null>;
2537
static with(options?: DialogHarnessFilters): HarnessPredicate<MatDialogHarness>;
2638
}
2739

40+
// @public
41+
export const enum MatDialogSection {
42+
// (undocumented)
43+
ACTIONS = ".mat-dialog-actions",
44+
// (undocumented)
45+
CONTENT = ".mat-dialog-content",
46+
// (undocumented)
47+
TITLE = ".mat-dialog-title"
48+
}
49+
2850
// (No @packageDocumentation comment for this package)
2951

3052
```

0 commit comments

Comments
 (0)