I have a Puppeteer script that clicks on an element triggering AJAX requests. I want to wait for network idle after the click before continuing.
Example code:
```javascript
const browser = await puppeteer.launch({ headless: false });
await page.goto(url, { waitUntil: 'networkidle' });
await page.click('.to_cart'); // Click triggers AJAX request
// Need to wait for network idle here
await page.click('.to_cart');
There is no navigation after the click, so `waitForNavigation` is not applicable. How can I ensure the network requests complete?
In my tests, when a click triggers AJAX requests without navigation, I use page.waitForNetworkIdle with a page.waitForResponse fallback:
await page.click('.to_cart');
// wait until there are no more network requests for at least 500ms
await page.waitForNetworkIdle({ idleTime: 500, timeout: 5000 });
In Puppeteer v19+, waitForNetworkIdle is available on the page and allows waiting for network to settle. Adjust idleTime and timeout based on your AJAX behavior.
Sometimes network idle can be tricky if there are background requests. I prefer waiting for the exact request I know will finish:
await Promise.all([
page.waitForResponse(response => response.url().includes('/cart/add') && response.status() === 200),
page.click('.to_cart')
]);
This ensures Puppeteer continues only after the critical AJAX call finishes. I find this more reliable than generic network idle for highly dynamic pages.
If you don’t know which requests will fire, a pragmatic approach I sometimes use is combining waitForNetworkIdle with a tiny timeout to ensure all network activity finishes:
await page.click('.to_cart');
await page.waitForNetworkIdle({ idleTime: 300, timeout: 5000 });
await page.waitForTimeout(200); // extra buffer for JS processing
Not perfect, but for pages with unpredictable AJAX behavior, it reduces flaky tests.