diff --git a/src/material/button/testing/button-harness.spec.ts b/src/material/button/testing/button-harness.spec.ts index 7f3ccda51ef8..496add10ba91 100644 --- a/src/material/button/testing/button-harness.spec.ts +++ b/src/material/button/testing/button-harness.spec.ts @@ -1,4 +1,4 @@ -import {Component} from '@angular/core'; +import {Component, signal} from '@angular/core'; import {ComponentFixture, TestBed} from '@angular/core/testing'; import {Platform} from '@angular/cdk/platform'; import {HarnessLoader, parallel} from '@angular/cdk/testing'; @@ -7,22 +7,21 @@ import {MatButtonModule} from '../module'; import {MatIconModule} from '../../icon'; import {MatIconHarness} from '../../icon/testing'; import {MatButtonHarness} from './button-harness'; +import {MatButtonAppearance} from '../button-base'; describe('MatButtonHarness', () => { let fixture: ComponentFixture; let loader: HarnessLoader; - let platform: Platform; beforeEach(() => { fixture = TestBed.createComponent(ButtonHarnessTest); fixture.detectChanges(); loader = TestbedHarnessEnvironment.loader(fixture); - platform = TestBed.inject(Platform); }); it('should load all button harnesses', async () => { const buttons = await loader.getAllHarnesses(MatButtonHarness); - expect(buttons.length).toBe(16); + expect(buttons.length).toBe(17); }); it('should load button with exact text', async () => { @@ -41,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(14); + expect(enabledButtons.length).toBe(15); expect(disabledButtons.length).toBe(2); }); @@ -79,7 +78,7 @@ describe('MatButtonHarness', () => { const button = await loader.getHarness(MatButtonHarness.with({text: 'Basic button'})); await button.click(); - expect(fixture.componentInstance.clicked).toBe(true); + expect(fixture.componentInstance.clicked()).toBe(true); }); it('should not click a disabled button', async () => { @@ -88,14 +87,14 @@ describe('MatButtonHarness', () => { // cancel dispatched click events on disabled buttons. We skip this check on Edge and Firefox. // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1582570 and: // https://stackoverflow.com/questions/32377026/disabled-button-is-clickable-on-edge-browser - if (platform.FIREFOX) { + if (TestBed.inject(Platform).FIREFOX) { return; } const button = await loader.getHarness(MatButtonHarness.with({text: 'Filled button'})); await button.click(); - expect(fixture.componentInstance.clicked).toBe(false); + expect(fixture.componentInstance.clicked()).toBe(false); }); it('should be able to handle nested harnesses', async () => { @@ -127,6 +126,7 @@ describe('MatButtonHarness', () => { 'basic', 'basic', 'basic', + 'basic', 'icon', 'fab', 'mini-fab', @@ -151,6 +151,7 @@ describe('MatButtonHarness', () => { 'filled', 'elevated', 'outlined', + 'tonal', null, null, null, @@ -166,16 +167,25 @@ describe('MatButtonHarness', () => { const button = await loader.getHarness(MatButtonHarness.with({appearance: 'filled'})); expect(await button.getText()).toBe('Filled button'); }); + + it('should get the appearance of a button with a dynamic appearance', async () => { + const button = await loader.getHarness( + MatButtonHarness.with({selector: '#dynamic-appearance'}), + ); + expect(await button.getAppearance()).toBe('tonal'); + fixture.componentInstance.dynamicAppearance.set('filled'); + expect(await button.getAppearance()).toBe('filled'); + }); }); @Component({ // Include one of each type of button selector to ensure that they're all captured by // the harness's selector. template: ` - - @@ -194,6 +204,7 @@ describe('MatButtonHarness', () => { Filled anchor Elevated anchor Stroked anchor + Stroked anchor Icon anchor Fab anchor Mini Fab anchor @@ -201,6 +212,6 @@ describe('MatButtonHarness', () => { imports: [MatButtonModule, MatIconModule], }) class ButtonHarnessTest { - disabled = true; - clicked = false; + clicked = signal(false); + dynamicAppearance = signal('tonal'); } diff --git a/src/material/button/testing/button-harness.ts b/src/material/button/testing/button-harness.ts index e99545d493bb..65bc7fc0040f 100644 --- a/src/material/button/testing/button-harness.ts +++ b/src/material/button/testing/button-harness.ts @@ -16,10 +16,14 @@ import {ButtonAppearance, ButtonHarnessFilters, ButtonVariant} from './button-ha /** Harness for interacting with a mat-button in tests. */ export class MatButtonHarness extends ContentContainerComponentHarness { - // TODO(jelbourn) use a single class, like `.mat-button-base` - static hostSelector = `[matButton], [mat-button], [matIconButton], [matFab], [matMiniFab], - [mat-raised-button], [mat-flat-button], [mat-icon-button], [mat-stroked-button], [mat-fab], - [mat-mini-fab]`; + // Note: `.mat-mdc-button-base` should be enough for all buttons, however some apps are using + // the harness without actually having an applied button. Keep the attributes for backwards + // compatibility. + + /** Selector for the harness. */ + static hostSelector = `.mat-mdc-button-base, [matButton], [mat-button], [matIconButton], + [matFab], [matMiniFab], [mat-raised-button], [mat-flat-button], [mat-icon-button], + [mat-stroked-button], [mat-fab], [mat-mini-fab]`; /** * Gets a `HarnessPredicate` that can be used to search for a button with specific attributes.