angularcheckboxangular-materialplaywrightplaywright-typescript

Playwright: how to interact with Angular Material checkbox


I have an Angular component that contains an Angular Material checkbox:

<mat-checkbox id="my-checkbox">My Checkbox</mat-checkbox> 

My goal is to test the containing application, using Playwright.

Via a Playwright locator, I am able to successfully reference the mat-checkbox. I have attempted to use the locator's check and uncheck functions to explicitly set the checkbox state, but this fails, because mat-checkbox is not an HTML input element.

const checkbox = page.locator('id=my-checkbox');    // OK
await checkbox.check();                             // throws
await checkbox.uncheck();                           // throws

I also tried referencing mat-checkbox's contained <input> element, but this also fails, apparently because the input element is not visible (it is only used internally by Angular Material to implement checkbox functionality).

Using the locator's click function, I am able to toggle the state of the checkbox:

const checkbox = page.locator('id=my-checkbox');    // OK
await checkbox.click();                             // toggles checkbox state

However, I am unsure how to retrieve the current state of the checkbox. The locator's isChecked function fails, in the same manner, for both the mat-checkbox and its contained input element.

This is my first experience using Playwright with Angular Material and I imagine there may be other Material components that similarly encapsulate functionality in a way that prevents easy testing.

Is there a recommended best practice for solving this issue?


Solution

  • I've run in to this with angular as well. The issue I found is that angular creates the <mat-checkbox> object and then puts an <input type="checkbox> inside of it.

    So on the rendered page it looks something like this:

    <mat-checkbox id="yourid">
        <input type="checkbox">
    </mat-checkbox
    

    If you put the id on the mat-checkbox, it won't register as a checkbox.

    You can get around this by using Playwright's nested locator features:

    page.Locator("#yourmatcheckboxid").getByRole("checkbox")
    

    Specifically, this looks for your mat-checkbox object, then within that object it looks for another object with a role of checkbox