Search code examples
javascriptplaywright

How to select/count disabled/enabled elements in Playwright?


I want to check how many (if it's like in config) I have disabled elements.

In Cypress it'd be like that:

cy.visit('https://example.cypress.io/commands/actions');

const disabledElementsLength = 0;
const enabledElementsLength = 9;

cy.get('button').not(':disabled').should((elem) => {
  expect(elem).to.have.length(enabledElementsLength);
});

cy.get(`button`).filter(':disabled').should((elems) => {
  expect(elems).to.have.length(disabledElementsLength);
});

but I can't make it work for myself in Playwright

I have page with

import { selectors, expect, request } from '@playwright/test';

export class MyPage {
   readonly element: Locator;
   constructor(public readonly page: Page) {
      selectors.setTestIdAttribute('data-test-id');
      this.element = this.page.locator(`[data-test-id^="specific-element"]`);
   }
}

I thought of just filter over... but seems like it doesn't have method filter available to this array of elements

async selectDisabledElements() {
    return this.element.evaluate((elements) =>
      elements.filter((button: any) => element.disabled),
    );
  }

Solution

  • You might try using :disabled directly on your CSS selectors, and using :not to invert the condition:

    import {expect, test} from "@playwright/test"; // ^1.38.0
    
    const html = `<!DOCTYPE html><html>
    <body>
    <button disabled>A</button>
    <button>B</button>
    <button disabled>C</button>
    <button disabled>D</button>
    <button>E</button>
    </body>
    </html>`;
    
    test.beforeEach(({page}) => page.setContent(html));
    
    test("3 disabled buttons", async ({page}) => {
      await expect(page.locator("button:disabled")).toHaveCount(3);
    });
    
    test("2 enabled buttons", async ({page}) => {
      await expect(page.locator("button:not(:disabled)")).toHaveCount(2);
    });
    

    With test ids, you can either use [data-test-id="foo"] in the above code, or getByTestId as in the following example:

    import {expect, selectors, test} from "@playwright/test";
    
    const html = `<!DOCTYPE html><html>
    <body>
    <button data-test-id="foo" disabled>A</button>
    <button data-test-id="foo">B</button>
    <button data-test-id="foo" disabled>C</button>
    <button data-test-id="foo" disabled>D</button>
    <button data-test-id="foo">E</button>
    </body>
    </html>`;
    
    test.beforeEach(({page}) => {
      selectors.setTestIdAttribute("data-test-id");
      return page.setContent(html);
    });
    
    test("3 disabled buttons", async ({page}) => {
      const loc = page
        .getByTestId("foo")
        .locator(":scope:disabled");
      await expect(loc).toHaveText(["A", "C", "D"]);
    });
    
    test("2 enabled buttons", async ({page}) => {
      const loc = page
        .getByTestId("foo")
        .locator(":scope:not(:disabled)");
      await expect(loc).toHaveText(["B", "E"]);
    });