|

Playwright expect.poll() and expect.toPass(): Polling Assertions for Async Operations

Some conditions cannot be checked by auto-retry assertions alone. API processing, background jobs, eventual consistency — these need polling. expect.poll() and expect.toPass() solve this.

🎭 Want to master this with real projects? Join the Playwright Automation Mastery course at The Testing Academy.

Contents

expect.poll(): Poll Until Condition Met

// Poll API until order status changes
test('order processes eventually', async ({ request }) => {
  const orderId = await createOrder(request);

  await expect.poll(async () => {
    const res = await request.get('/api/orders/' + orderId);
    const order = await res.json();
    return order.status;
  }, {
    message: 'Order should reach "completed" status',
    intervals: [1000, 2000, 5000],  // Poll at 1s, 2s, 5s intervals
    timeout: 30000,                  // Give up after 30s
  }).toBe('completed');
});

expect.toPass(): Retry Entire Block

// Retry a block of assertions until all pass
test('dashboard data loads eventually', async ({ page }) => {
  await page.goto('/dashboard');

  await expect(async () => {
    await expect(page.getByTestId('user-count')).not.toHaveText('0');
    await expect(page.getByTestId('revenue')).not.toHaveText('$0');
    await expect(page.getByTestId('chart')).toBeVisible();
  }).toPass({
    intervals: [1000, 2000, 5000],
    timeout: 30000,
  });
});

🚀 Level Up Your Playwright

From locators to CI pipelines — build a production-grade Playwright + TypeScript framework step by step.

When to Use Which

PatternUse ForExample
expect(locator)DOM element stateButton visible, text matches
expect.poll()Non-DOM async valueAPI status, DB state, job completion
expect().toPass()Multiple conditions togetherDashboard fully loaded with all data

Real-World Patterns

// Wait for email to arrive (via Mailhog API)
await expect.poll(async () => {
  const res = await request.get('http://mailhog:8025/api/v2/messages');
  const messages = await res.json();
  return messages.total;
}, { timeout: 15000 }).toBeGreaterThan(0);

// Wait for file to appear on disk
await expect.poll(async () => {
  return fs.existsSync('/tmp/export.csv');
}, { timeout: 10000 }).toBe(true);

// Wait for background job to complete
await expect.poll(async () => {
  const res = await request.get('/api/jobs/' + jobId);
  return (await res.json()).progress;
}, { timeout: 60000 }).toBe(100);

🎓 Master Playwright End to End

Join hundreds of SDETs building real automation frameworks. Lifetime access, hands-on projects, and a job-ready portfolio.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.