angular/components · error · Error

MatDatepickerActions does not have ${name} button

Error message

MatDatepickerActions does not have ${name} button

What it means

The MatDatepickerActions testing harness _clickAction helper throws when the locator finds no matching actions button in the datepicker. apply() and cancel() call it with locators for the confirm/cancel buttons; if the developer never rendered a mat-datepicker-actions element (or lacks the specific button), the harness cannot click anything. It signals the fixture under test does not expose the expected action button.

Source

Thrown at src/material/datepicker/testing/datepicker-actions-harness.ts:53

  ): HarnessPredicate<MatDatepickerActionsHarness> {
    return new HarnessPredicate(MatDatepickerActionsHarness, options);
  }

  /** Applies the current selection. */
  apply(): Promise<void> {
    return this._clickAction('apply', this._applyLocator);
  }

  /** Cancels the current selection. */
  cancel(): Promise<void> {
    return this._clickAction('cancel', this._cancelLocator);
  }

  private async _clickAction(name: string, locator: () => Promise<TestElement | null>) {
    const button = await locator();

    if (!button) {
      throw new Error(`MatDatepickerActions does not have ${name} button`);
    }

    await button.click();
  }
}

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Add <mat-datepicker-actions> with <button mat-button matDatepickerCancel> and <button mat-button matDatepickerApply> inside the date input's mat-datepicker in the fixture template
  2. Ensure the datepicker is opened before querying/clicking actions
  3. Verify the harness is connected to the correct datepicker harness instance
  4. Check the fixture rendered the actions synchronously (wait for harness stability)

Example fix

// before (template)
<mat-datepicker #dp></mat-datepicker>
// after
<mat-datepicker #dp>
  <mat-datepicker-actions>
    <button mat-button matDatepickerCancel>Cancel</button>
    <button mat-button matDatepickerApply>Apply</button>
  </mat-datepicker-actions>
</mat-datepicker>
Defensive patterns

Strategy: validation

Validate before calling

const actions = await datepickerHarness.getActions();
if (!actions) {
  throw new Error('Fixture template must include <mat-datepicker-actions> for this test');
}
await actions.clickActions({ applyLabel: 'Apply' });

Try / catch

try {
  await actionsHarness.clickActions('apply');
} catch (e) {
  if (String(e?.message).startsWith('MatDatepickerActions does not have')) {
    fail('Add <mat-datepicker-actions> with cancel/apply buttons to the fixture template');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling harness.clickActions('apply') or harness.cancel() (via MatDatepickerActionsHarness methods) when the opened datepicker content has no mat-datepicker-actions block, or no button matching the harness locator; actions rendered outside the queried datepicker; harness connected to the wrong datepicker instance.

Common situations: Copy-pasting harness tests from an example while the component template omits mat-datepicker-actions; forgetting to open the datepicker before querying actions; conditional rendering of actions; typos so the button isn't inside the actions container.

Related errors


AI-assisted analysis of angular/components@0411926e7d (2026-08-31). Data as JSON: /api/errors/7af8149a627e4003. Report an issue: GitHub.