🎭 Element State Assertions in Playwright
The Detective’s Toolkit 🔍
Imagine you’re a detective checking if things are just right in a room. Is the light ON or OFF? Is the door LOCKED or UNLOCKED? Can you SEE the painting on the wall?
That’s exactly what Element State Assertions do in Playwright! They help you check if things on a webpage are in the right condition.
🌟 Meet the expect Function
What is it?
Think of expect like asking a question: “Hey, is this thing the way I think it should be?”
// You're saying: "I expect this button to be visible!"
await expect(button).toBeVisible();
Simple Analogy
You walk into a room and expect to see a lamp. If the lamp is there, great! If not, something is wrong.
// Get the element first
const lamp = page.locator('#lamp');
// Now ask: "Is it there?"
await expect(lamp).toBeVisible();
Key Point: The expect function is your question-asker. You give it something to check, then tell it what you expect.
👁️ toBeVisible - Can You See It?
The Story
Imagine you’re playing hide and seek. You need to know: “Can I actually SEE this thing?”
A visible element means:
- It’s on the page
- It’s not hidden
- It’s not invisible
- It has actual space (not zero size)
Example
// The "Submit" button should be visible
const submitBtn = page.locator('#submit');
await expect(submitBtn).toBeVisible();
Real Life Example
Your phone shows a message notification. You expect to SEE it:
const notification = page.locator('.notification');
await expect(notification).toBeVisible();
// ✅ Pass if you can see it
// ❌ Fail if it's hidden
🙈 toBeHidden - Is It Hiding?
The Story
Now flip it around! Sometimes you WANT things to be hidden. Like when a loading spinner should disappear after the page loads.
What counts as hidden?
- Element doesn’t exist
- Element has
display: none - Element has
visibility: hidden - Element has zero size
Example
// After loading, spinner should hide
const spinner = page.locator('.loading-spinner');
await expect(spinner).toBeHidden();
Real Life Example
When you close a popup, you expect it to be HIDDEN:
// Click the close button
await page.click('.close-popup');
// Now the popup should be hidden
const popup = page.locator('.popup');
await expect(popup).toBeHidden();
// ✅ Pass if hidden
// ❌ Fail if still visible
✅ toBeEnabled - Ready to Use!
The Story
Think of a video game controller. When the game starts, all buttons are enabled - you can press them!
An enabled element means:
- You can click it
- You can type in it
- It’s ready for action!
Example
// The "Play" button should be enabled
const playBtn = page.locator('#play-button');
await expect(playBtn).toBeEnabled();
Real Life Example
After you fill in your username and password, the Login button becomes enabled:
// Fill the form
await page.fill('#username', 'player1');
await page.fill('#password', 'secret123');
// Now login button should be enabled
const loginBtn = page.locator('#login');
await expect(loginBtn).toBeEnabled();
🚫 toBeDisabled - Not Ready Yet!
The Story
Remember that “Next” button that’s gray and won’t work until you answer a question? That’s a disabled element!
A disabled element:
- Has
disabledattribute - Can’t be clicked
- Often looks gray or faded
Example
// Submit button disabled until form is valid
const submitBtn = page.locator('#submit');
await expect(submitBtn).toBeDisabled();
Real Life Example
An empty shopping cart should have a disabled checkout button:
// Cart is empty
const checkoutBtn = page.locator('#checkout');
await expect(checkoutBtn).toBeDisabled();
// Add an item
await page.click('.add-to-cart');
// Now it should be enabled!
await expect(checkoutBtn).toBeEnabled();
☑️ toBeChecked - Is the Box Ticked?
The Story
Think of a checklist. You check the box when something is done. toBeChecked asks: “Is this checkbox ticked?”
Works with:
- Checkboxes ☑️
- Radio buttons 🔘
Example
// "Remember me" checkbox should be checked
const rememberMe = page.locator('#remember-me');
await expect(rememberMe).toBeChecked();
Real Life Example
User agrees to terms before signing up:
// Check the terms checkbox
await page.check('#agree-terms');
// Verify it's checked
const termsBox = page.locator('#agree-terms');
await expect(termsBox).toBeChecked();
// To check it's NOT checked:
await expect(termsBox).not.toBeChecked();
🎯 toBeFocused - Who Has Attention?
The Story
In a classroom, one student at a time is called on - they have the teacher’s focus. On a webpage, one element at a time can be focused - usually an input field where you’re typing.
What can be focused?
- Text inputs
- Buttons
- Links
- Anything you can tab to
Example
// After clicking, input should be focused
const searchBox = page.locator('#search');
await searchBox.click();
await expect(searchBox).toBeFocused();
Real Life Example
When you open Google, the search box is automatically focused:
// Navigate to page
await page.goto('https://example.com');
// Search box should be focused automatically
const searchInput = page.locator('#search-input');
await expect(searchInput).toBeFocused();
// You can start typing right away!
🎨 Quick Visual Summary
graph LR A[expect function] --> B[Get Element] B --> C{Choose Assertion} C --> D[toBeVisible 👁️] C --> E[toBeHidden 🙈] C --> F[toBeEnabled ✅] C --> G[toBeDisabled 🚫] C --> H[toBeChecked ☑️] C --> I[toBeFocused 🎯]
🏠 The House Analogy
Think of a webpage like a house:
| Assertion | House Example |
|---|---|
toBeVisible |
Can you see the door? |
toBeHidden |
Is the safe hidden? |
toBeEnabled |
Does the doorbell work? |
toBeDisabled |
Is the lock jammed? |
toBeChecked |
Is the alarm set? |
toBeFocused |
Is the spotlight on you? |
🚀 Pro Tips
1. Use not for Opposite Checks
// Element should NOT be visible
await expect(element).not.toBeVisible();
// Checkbox should NOT be checked
await expect(checkbox).not.toBeChecked();
2. Playwright Auto-Waits!
Playwright is smart. It waits a bit for elements to reach the expected state. No need for manual delays!
// Playwright waits for button to be visible
// (up to timeout, usually 5 seconds)
await expect(button).toBeVisible();
3. Custom Timeout
Need more time? Add a timeout:
await expect(element).toBeVisible({
timeout: 10000 // Wait up to 10 seconds
});
🎯 Complete Example
Here’s a real test using all assertions:
test('login form works', async ({ page }) => {
await page.goto('/login');
// Username field should be visible
const username = page.locator('#username');
await expect(username).toBeVisible();
// Username should be focused
await expect(username).toBeFocused();
// Submit button starts disabled
const submit = page.locator('#submit');
await expect(submit).toBeDisabled();
// Fill the form
await username.fill('testuser');
await page.fill('#password', '12345');
// Now submit should be enabled
await expect(submit).toBeEnabled();
// Check "remember me"
const remember = page.locator('#remember');
await remember.check();
await expect(remember).toBeChecked();
// Click submit
await submit.click();
// Login form should be hidden
await expect(username).toBeHidden();
});
🎉 You Did It!
Now you know all 6 element state assertions:
- expect - Your question-asker
- toBeVisible - Can you see it?
- toBeHidden - Is it hiding?
- toBeEnabled - Ready to use?
- toBeDisabled - Locked out?
- toBeChecked - Box ticked?
- toBeFocused - Has attention?
You’re now a Playwright Detective ready to check any element’s state! 🕵️♀️