Skip to content

feat(material/testing): Add 'type' attribute filter and getter to Mat… #31657

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

Merged
merged 3 commits into from
Aug 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions goldens/material/button/testing/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ export type ButtonAppearance = 'text' | 'filled' | 'elevated' | 'outlined' | 'to
// @public
export interface ButtonHarnessFilters extends BaseHarnessFilters {
appearance?: ButtonAppearance;
buttonType?: ButtonType;
disabled?: boolean;
text?: string | RegExp;
variant?: ButtonVariant;
}

// @public
export type ButtonType = 'button' | 'submit' | 'reset';

// @public
export type ButtonVariant = 'basic' | 'icon' | 'fab' | 'mini-fab';

Expand All @@ -32,6 +36,7 @@ export class MatButtonHarness extends ContentContainerComponentHarness {
focus(): Promise<void>;
getAppearance(): Promise<ButtonAppearance | null>;
getText(): Promise<string>;
getType(): Promise<ButtonType | null>;
getVariant(): Promise<ButtonVariant>;
static hostSelector: string;
isDisabled(): Promise<boolean>;
Expand Down
6 changes: 6 additions & 0 deletions src/material/button/testing/button-harness-filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export type ButtonVariant = 'basic' | 'icon' | 'fab' | 'mini-fab';
/** Possible button appearances. */
export type ButtonAppearance = 'text' | 'filled' | 'elevated' | 'outlined' | 'tonal';

/** Possible button types. */
export type ButtonType = 'button' | 'submit' | 'reset';

/** A set of criteria that can be used to filter a list of button harness instances. */
export interface ButtonHarnessFilters extends BaseHarnessFilters {
/** Only find instances whose text matches the given value. */
Expand All @@ -27,4 +30,7 @@ export interface ButtonHarnessFilters extends BaseHarnessFilters {

/** Only find instances which match the given disabled state. */
disabled?: boolean;

/** Only find instances with the specified type. */
buttonType?: ButtonType;
}
14 changes: 12 additions & 2 deletions src/material/button/testing/button-harness.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('MatButtonHarness', () => {

it('should load all button harnesses', async () => {
const buttons = await loader.getAllHarnesses(MatButtonHarness);
expect(buttons.length).toBe(17);
expect(buttons.length).toBe(18);
});

it('should load button with exact text', async () => {
Expand All @@ -40,7 +40,7 @@ describe('MatButtonHarness', () => {
it('should filter by whether a button is disabled', async () => {
const enabledButtons = await loader.getAllHarnesses(MatButtonHarness.with({disabled: false}));
const disabledButtons = await loader.getAllHarnesses(MatButtonHarness.with({disabled: true}));
expect(enabledButtons.length).toBe(15);
expect(enabledButtons.length).toBe(16);
expect(disabledButtons.length).toBe(2);
});

Expand All @@ -59,6 +59,13 @@ describe('MatButtonHarness', () => {
expect(await disabledElevatedAnchor.isDisabled()).toBe(true);
});

it('should load button with type attribute', async () => {
const buttons = await loader.getAllHarnesses(MatButtonHarness.with({buttonType: 'submit'}));
expect(buttons.length).toBe(1);
expect(await buttons[0].getText()).toBe('Submit button');
expect(await buttons[0].getType()).toBe('submit');
});

it('should get button text', async () => {
const [firstButton, secondButton] = await loader.getAllHarnesses(MatButtonHarness);
expect(await firstButton.getText()).toBe('Basic button');
Expand Down Expand Up @@ -127,6 +134,7 @@ describe('MatButtonHarness', () => {
'basic',
'basic',
'basic',
'basic',
'icon',
'fab',
'mini-fab',
Expand All @@ -148,6 +156,7 @@ describe('MatButtonHarness', () => {
null,
null,
'text',
'text',
'filled',
'elevated',
'outlined',
Expand Down Expand Up @@ -199,6 +208,7 @@ describe('MatButtonHarness', () => {
</button>
<button id="fab" type="button" matFab>Fab button</button>
<button id="mini-fab" type="button" matMiniFab>Mini Fab button</button>
<button id="submit" type="submit" matButton>Submit button</button>

<a id="anchor-basic" matButton>Basic anchor</a>
<a id="anchor-flat" matButton="filled">Filled anchor</a>
Expand Down
24 changes: 22 additions & 2 deletions src/material/button/testing/button-harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import {
ContentContainerComponentHarness,
HarnessPredicate,
} from '@angular/cdk/testing';
import {ButtonAppearance, ButtonHarnessFilters, ButtonVariant} from './button-harness-filters';
import {
ButtonAppearance,
ButtonHarnessFilters,
ButtonType,
ButtonVariant,
} from './button-harness-filters';

/** Harness for interacting with a mat-button in tests. */
export class MatButtonHarness extends ContentContainerComponentHarness {
Expand Down Expand Up @@ -50,7 +55,10 @@ export class MatButtonHarness extends ContentContainerComponentHarness {
)
.addOption('disabled', options.disabled, async (harness, disabled) => {
return (await harness.isDisabled()) === disabled;
});
})
.addOption('buttonType', options.buttonType, (harness, buttonType) =>
HarnessPredicate.stringMatches(harness.getType(), buttonType),
);
}

/**
Expand Down Expand Up @@ -150,4 +158,16 @@ export class MatButtonHarness extends ContentContainerComponentHarness {

return null;
}

/**
* Gets the type of the button. Supported values are 'button', 'submit', and 'reset'.
*/
async getType(): Promise<ButtonType | null> {
const host = await this.host();
const buttonType = await host.getAttribute('type');
if (buttonType === 'button' || buttonType === 'submit' || buttonType === 'reset') {
return buttonType;
}
return null;
}
}
Loading