🎠Playwright Core Interactions: Teaching Your Robot Friend to Play!
The Big Idea: Imagine you have a robot friend who wants to play with toys on a webpage. But this robot is really polite—it waits until toys are ready, checks if it can play with them, and then gently clicks, hovers, focuses, and scrolls. That’s Playwright!
🎯 What We’ll Learn
Think of Playwright like a patient, smart robot helper. Before touching anything on a webpage, it:
- Waits until things are ready (Auto-waiting)
- Checks if it can actually touch them (Actionability checks)
- Clicks buttons and links
- Hovers over things to see hidden menus
- Focuses on input boxes (like when you tap a text field)
- Scrolls up and down to find things
Let’s meet each superpower! 🚀
⏳ Auto-Waiting Mechanism
The Story
Imagine you’re at a toy store. The shelf is empty, but you KNOW new toys are coming. Would you grab at empty air? No! You’d wait for the toys to appear.
Playwright does the same thing. It automatically waits for elements to appear before trying to touch them.
Why This Is Amazing
Without auto-waiting (the old, bad way):
// ❌ OLD WAY - might fail!
await page.waitForSelector('#button');
await page.click('#button');
With auto-waiting (Playwright’s magic):
// âś… PLAYWRIGHT WAY - just works!
await page.click('#button');
Playwright says: “I’ll wait for the button myself. You just tell me to click!”
How Long Does It Wait?
By default, Playwright waits 30 seconds. You can change this:
// Wait up to 10 seconds
await page.click('#button', { timeout: 10000 });
The Magic Behind It
graph TD A[🤖 Click Command] --> B{Element exists?} B -->|No| C[⏳ Wait & Retry] C --> B B -->|Yes| D{Can I click it?} D -->|No| E[⏳ Wait & Retry] E --> D D -->|Yes| F[✅ Click!]
âś… Actionability Checks
The Story
Your robot friend isn’t just patient—it’s thoughtful. Before clicking a button, it asks:
- “Can I see this button?” (Is it visible?)
- “Is the button actually there?” (Is it attached to the page?)
- “Is something blocking it?” (Is it covered by another element?)
- “Is the button awake?” (Is it enabled, not disabled?)
The 6 Actionability Checks
| Check | What It Means | Real Life Example |
|---|---|---|
| Visible | Can you see it? | Not hidden behind a curtain |
| Stable | Has it stopped moving? | A ball that stopped bouncing |
| Attached | Is it part of the page? | A sticker that’s stuck, not falling off |
| Enabled | Can it be clicked? | A door that’s unlocked |
| Editable | Can you type in it? | A notebook that’s open |
| Receives Events | Will it respond? | A doorbell that works |
Example: Waiting for a Button to Be Ready
// Playwright checks ALL of these automatically!
await page.click('#submit-btn');
// The button must be:
// âś… Visible on screen
// âś… Not moving around
// âś… Part of the page (not removed)
// âś… Not disabled
// âś… Not covered by a popup
Force Click (Skip the Checks)
Sometimes you need to click something that’s hidden. Use force:
// ⚠️ Skip actionability checks
await page.click('#hidden-btn', { force: true });
Warning: Use
forcecarefully! It’s like closing your eyes and clicking randomly.
🖱️ Click Actions
The Story
Clicking seems simple, right? But your robot friend can click in many ways—single click, double click, right-click, even click at a specific spot!
Basic Click
// Simple click
await page.click('#button');
// Same thing, using locator (recommended)
await page.locator('#button').click();
Double Click
Like double-clicking to open a folder:
await page.dblclick('#folder-icon');
Right Click (Context Menu)
Like right-clicking to see options:
await page.click('#item', { button: 'right' });
Click at Specific Position
Sometimes you need to click a specific spot:
// Click 10 pixels from left, 20 from top
await page.click('#canvas', {
position: { x: 10, y: 20 }
});
Click with Modifier Keys
Hold keys while clicking:
// Ctrl+Click (opens in new tab)
await page.click('a', { modifiers: ['Control'] });
// Shift+Click (select range)
await page.click('#item', { modifiers: ['Shift'] });
Click Flow
graph TD A[🖱️ Click Command] --> B[Wait for element] B --> C[Check actionability] C --> D[Scroll into view] D --> E[Move mouse to element] E --> F[Press mouse button] F --> G[Release mouse button] G --> H[✅ Click complete!]
🎯 Hovering Over Elements
The Story
Some things on websites are shy! They only show up when you hover over them—like a dropdown menu that appears when you point at it.
Your robot friend can hover too!
Basic Hover
// Hover over a menu item
await page.hover('#dropdown-menu');
// The hidden submenu appears!
await page.click('#submenu-item');
Real Example: Dropdown Menu
// Step 1: Hover to reveal hidden menu
await page.hover('.nav-item');
// Step 2: Now click the revealed option
await page.click('.dropdown-option');
Hover at Specific Position
// Hover near the edge of an element
await page.hover('#tooltip-trigger', {
position: { x: 5, y: 5 }
});
Why Hover Matters
| Scenario | Why Hover? |
|---|---|
| Dropdown menus | Reveal hidden options |
| Tooltips | Show helpful text |
| Image galleries | Show zoom/edit buttons |
| Shopping carts | Preview cart contents |
🎯 Focus and Blur
The Story
Remember how you tap on a text box on your phone, and the keyboard pops up? That’s focus!
And when you tap somewhere else, the keyboard goes away? That’s blur (losing focus).
Focus: Give Attention to an Element
// Focus on an input field
await page.focus('#email-input');
// Now it's ready to receive typing!
await page.fill('#email-input', 'hello@example.com');
Blur: Take Attention Away
// First, focus on something
await page.focus('#username');
// Then, blur it (trigger validation)
await page.locator('#username').blur();
Why Focus/Blur Matter
graph TD A[👆 Focus on input] --> B[Cursor appears] B --> C[Type text] C --> D[👋 Blur/click away] D --> E[Validation runs] E --> F{Valid?} F -->|Yes| G[✅ Green checkmark] F -->|No| H[❌ Error message]
Real Example: Form Validation
// Type in a field
await page.fill('#email', 'bad-email');
// Blur triggers validation
await page.locator('#email').blur();
// Check for error message
const error = await page.locator('.error').textContent();
console.log(error); // "Please enter valid email"
Focus vs Click
| Action | What Happens |
|---|---|
click() |
Focuses + triggers click event |
focus() |
Only focuses, no click event |
Use focus() when you just want to activate an input without clicking it.
📜 Scrolling Elements
The Story
Imagine a long piece of paper inside a tiny window. You can only see part of it. To see more, you scroll!
Playwright can scroll in two ways:
- Automatic: It scrolls automatically when needed
- Manual: You tell it exactly where to scroll
Automatic Scrolling (Magic!)
Playwright scrolls automatically before clicking:
// Button is below the visible area
// Playwright scrolls to it automatically!
await page.click('#button-at-bottom');
Manual Scrolling
Scroll Element into View
// Make sure element is visible
await page.locator('#footer').scrollIntoViewIfNeeded();
Scroll by Amount
// Scroll down 500 pixels
await page.mouse.wheel(0, 500);
Scroll to Specific Element
// Scroll inside a container
await page.locator('.scroll-container').evaluate(
el => el.scrollTop = 1000
);
Scrollable Containers
Sometimes only a part of the page scrolls:
// Scroll inside a chat window
const chatBox = page.locator('.chat-messages');
await chatBox.evaluate(el => {
el.scrollTop = el.scrollHeight; // Scroll to bottom
});
Scroll Visualization
graph TD A[🔍 Find element] --> B{In view?} B -->|Yes| C[✅ Ready to interact] B -->|No| D[📜 Scroll into view] D --> E[Wait for scroll] E --> C
🎪 Putting It All Together
Here’s a real-world example using ALL the concepts:
const { test, expect } = require('@playwright/test');
test('complete form interaction', async ({ page }) => {
await page.goto('https://example.com/form');
// 1. AUTO-WAITING: Just click, it waits
await page.click('#start-btn');
// 2. HOVER: Reveal dropdown
await page.hover('.menu-trigger');
await page.click('.menu-option');
// 3. FOCUS & TYPE
await page.focus('#name-input');
await page.fill('#name-input', 'Robot Friend');
// 4. BLUR: Trigger validation
await page.locator('#name-input').blur();
// 5. SCROLL: Find hidden button
await page.locator('#submit').scrollIntoViewIfNeeded();
// 6. CLICK: Submit the form
await page.click('#submit');
// All done! 🎉
});
đź§ Quick Summary
| Concept | What It Does | One-Line Example |
|---|---|---|
| Auto-waiting | Waits for elements automatically | await page.click('#btn') |
| Actionability | Checks if action is possible | Happens automatically! |
| Click | Clicks buttons & links | await page.click('#btn') |
| Double-click | Opens files/folders | await page.dblclick('#file') |
| Hover | Reveals hidden menus | await page.hover('.menu') |
| Focus | Activates input fields | await page.focus('#input') |
| Blur | Deactivates/validates | await locator.blur() |
| Scroll | Moves page up/down | Automatic or manual |
🎯 Remember This!
Playwright is like a polite, patient robot friend.
It waits for things to be ready, checks if it can interact, then gently clicks, hovers, focuses, and scrolls.
You don’t have to tell it to wait—it just knows! 🤖✨
Now you’re ready to teach your robot friend how to play with any webpage!