Skip to contentPlayForge

How do I assert a button is disabled or enabled in Playwright?

Written by Jatin Thacker, Automation Architect · Updated

Use await expect(button).toBeDisabled() and await expect(button).toBeEnabled(). Both retry, so they wait for validation code to switch the button on or off.

This answer is one piece of Chapter 11: Assertions.

  • Web-First Assertions Cookbook
  • Retry & Polling Patterns
  • Visual Regression Testing
  • Making a Failure Explain Itself

Forms often keep their submit button disabled until the input is valid. Testing that rule means checking the button's state at each step, and the state changes as the user types, so the check has to wait for the page to catch up. toBeDisabled() and toBeEnabled() are web-first assertions that do exactly that.

An element counts as disabled when it has the disabled attribute, or when aria-disabled="true" is set on an element with an interactive role, such as a button. Note the docs' warning: only native controls such as button, input, select and textarea can really be disabled. A div styled to look greyed out is not disabled as far as these assertions are concerned.

The example walks the login form's rule:

  1. On load, Sign in is disabled.
  2. After filling only Work email, it is still disabled. This step is easy to skip and is where bugs hide.
  3. After filling Password too, it is enabled.

Do not click a disabled button to prove it is disabled: Playwright's click waits for the button to become enabled, so the test hangs until it times out.

enabled.spec.js(https://practice.learnplayforge.com)
import { test, expect } from '@playwright/test'; test('Sign in stays disabled until both fields are valid', async ({ page }) => { await page.goto('/login.html?mock=static&seed=42'); const submit = page.getByRole('button', { name: 'Sign in' }); await expect(submit).toBeDisabled(); await page.getByLabel('Work email').fill('ops@meridian.test'); await expect(submit).toBeDisabled(); await page.getByLabel('Password').fill('Passw0rd!'); await expect(submit).toBeEnabled(); });
Output
1 passed (1.4s)
Test yourself
A <div> is styled grey to look disabled, but has no disabled or aria-disabled attribute. What does toBeDisabled() do on it?

Practised in the full course: the drill Disabled until valid.

See the chapter

AI can write the test now. The job is knowing whether it checks anything. That's what the course teaches, one chapter at a time.

163 lessons · 226 drills · start free

← All questions

Training a team? Talk to us.