Waiting Strategies

Back

Loading concept...

🎭 Playwright Waiting Strategies: The Art of Perfect Timing

Imagine you’re at a bus stop. You wouldn’t just run into the street hoping a bus appears—you’d WAIT for it to arrive. That’s exactly what Playwright waiting strategies do: they help your code WAIT for the right moment before taking action.


🌟 The Big Picture

When you automate a website, things don’t happen instantly. Pages load, buttons appear, URLs change. If your code rushes ahead before the page is ready, it crashes—like trying to board a bus that hasn’t arrived yet!

Playwright’s waiting strategies are your patient helpers. Each one waits for something specific:

Wait Method What It Waits For
waitForSelector An element to appear
waitForLoadState Page to finish loading
waitForURL URL to change
waitForFunction A condition to become true
waitForEvent Something to happen
waitForTimeout A set amount of time

🔍 page.waitForSelector

What Is It?

This is like waiting for your friend to show up at a meeting spot. You stand there until you SEE them.

Simple Example

// Wait for a button to appear
await page.waitForSelector('#submit-btn');
// Now click it safely!
await page.click('#submit-btn');

Real Life Scenario

A shopping cart icon appears AFTER you add an item. You need to wait for it:

await page.click('.add-to-cart');
// Wait for cart badge to show
await page.waitForSelector('.cart-badge');
console.log('Item added!');

Options You Can Use

await page.waitForSelector('.popup', {
  state: 'visible',   // visible, hidden, attached
  timeout: 5000       // wait max 5 seconds
});

🏁 page.waitForLoadState

What Is It?

Think of a website like a restaurant kitchen. There are different stages:

  • domcontentloaded: The menu is ready (HTML loaded)
  • load: All dishes are on the table (images, scripts done)
  • networkidle: The kitchen is quiet (no more requests)

Simple Example

// Wait for page to fully load
await page.waitForLoadState('load');
// Now the page is complete!

When to Use Each State

// Fast: Just need HTML structure
await page.waitForLoadState('domcontentloaded');

// Medium: Need all images and scripts
await page.waitForLoadState('load');

// Slow but thorough: Wait for all network quiet
await page.waitForLoadState('networkidle');

Real Life Scenario

After clicking a link, wait for the new page:

await page.click('a.next-page');
await page.waitForLoadState('networkidle');
// Now scrape the fully loaded content

🔗 page.waitForURL

What Is It?

Like waiting at an airport departure screen until YOUR flight number appears. You watch the URL bar until it shows what you expect.

Simple Example

// After login, wait for dashboard URL
await page.click('#login-button');
await page.waitForURL('**/dashboard');
// Now we're on the dashboard!

Different Ways to Match URLs

// Exact match
await page.waitForURL('https://example.com/home');

// Pattern match with glob
await page.waitForURL('**/products/*');

// Regex match
await page.waitForURL(/\/order\/\d+/);

// Function match
await page.waitForURL(url => url.includes('success'));

Real Life Scenario

After placing an order, wait for confirmation page:

await page.click('#place-order');
await page.waitForURL('**/order-confirmation*');
const orderId = await page.textContent('.order-id');

🧪 page.waitForFunction

What Is It?

This is the SMARTEST waiter. It checks a condition over and over until it becomes TRUE. Like waiting until a pot of water starts boiling!

Simple Example

// Wait until counter shows 5
await page.waitForFunction(() => {
  const el = document.querySelector('#counter');
  return el && el.textContent === '5';
});

Why Is It Special?

It runs YOUR custom JavaScript inside the page. You can check ANYTHING:

// Wait for array to have 3 items
await page.waitForFunction(() => {
  return window.myData && window.myData.length >= 3;
});

// Wait for animation to complete
await page.waitForFunction(() => {
  const box = document.querySelector('.animated-box');
  return box.classList.contains('animation-done');
});

With Arguments

You can pass data from your test into the page:

const expectedText = 'Welcome, John!';
await page.waitForFunction(
  (text) => document.body.innerText.includes(text),
  expectedText
);

📡 page.waitForEvent

What Is It?

Like a detective with their ear to the ground, waiting for a specific SOUND. This waits for browser events like popups, downloads, or console messages.

Simple Example

// Wait for a popup window
const popupPromise = page.waitForEvent('popup');
await page.click('#open-popup');
const popup = await popupPromise;
// Now work with the popup!

Common Events to Wait For

// Wait for file download
const downloadPromise = page.waitForEvent('download');
await page.click('#download-btn');
const download = await downloadPromise;

// Wait for console message
const consolePromise = page.waitForEvent('console');
await page.click('#log-something');
const msg = await consolePromise;
console.log(msg.text());

// Wait for dialog (alert/confirm)
page.on('dialog', d => d.accept());
const dialogPromise = page.waitForEvent('dialog');
await page.click('#show-alert');
await dialogPromise;

With Filters

// Wait for a specific console error
const error = await page.waitForEvent('console',
  msg => msg.type() === 'error'
);

⏰ page.waitForTimeout

What Is It?

This is the SIMPLEST waiter—just a plain timer. Like setting an alarm and doing nothing until it rings.

Simple Example

// Wait for 2 seconds
await page.waitForTimeout(2000);

⚠️ Important Warning!

This should be your LAST resort! It’s like guessing how long something takes instead of actually checking.

// ❌ BAD: Guessing wait times
await page.waitForTimeout(5000);
await page.click('.button');

// ✅ GOOD: Wait for actual condition
await page.waitForSelector('.button');
await page.click('.button');

When It’s Okay to Use

  • Debugging: Slow down to see what’s happening
  • Rate limiting: Wait between API calls
  • Animations: When no other signal exists
// Acceptable: Rate limit protection
for (const item of items) {
  await page.click(item);
  await page.waitForTimeout(500); // Prevent spam
}

🎯 Quick Decision Guide

graph TD A["What are you waiting for?"] --> B{Element?} B -->|Yes| C["waitForSelector"] B -->|No| D{Page load?} D -->|Yes| E["waitForLoadState"] D -->|No| F{URL change?} F -->|Yes| G["waitForURL"] F -->|No| H{Custom condition?} H -->|Yes| I["waitForFunction"] H -->|No| J{Browser event?} J -->|Yes| K["waitForEvent"] J -->|No| L["waitForTimeout ⚠️"]

🚀 Pro Tips

  1. Always prefer smart waits over waitForTimeout
  2. Combine waits when needed:
    await page.waitForLoadState('networkidle');
    await page.waitForSelector('.content');
    
  3. Set reasonable timeouts to fail fast:
    await page.waitForSelector('.slow-thing', {
      timeout: 10000
    });
    

🎬 Summary

Method Use When…
waitForSelector Need an element to exist
waitForLoadState Page needs to finish loading
waitForURL Navigation should complete
waitForFunction Custom condition must be true
waitForEvent Browser event should fire
waitForTimeout Last resort only!

Remember: Good waiting = Reliable tests. Don’t rush—let Playwright wait for the perfect moment! 🎭

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.