waitForResponse() timing: the one-line fix with a non-obvious mental model
The test hung for 30 seconds. The response had already fired. One moved line fixed it. The test hung for 30 seconds, then timed out. The browser had received the response. The page had loaded. The data was there. The test was still waiting. The wizard I was writing a helper to walk through a 4-step booking wizard. After clicking "Next" on step 1, the page does a full navigation — window.location.href to step 2. Step 2 immediately loads doctor data from the API. The helper looked like this: await Promise . all ([ page . waitForURL ( /step=2/ ), step1Next . click ()]); await page . waitForResponse ( r => r . url (). includes ( ' /doctors ' )); Standard pattern: wait for navigation, then wait for the data request. Timeout. Every time. What I checked first The URL pattern. Maybe /doctors wasn't matching. Opened the network tab. The request was there: GET /api/v1/doctors , 200, 47ms. Correct URL, correct response. The page looked fine. The data was rendered. The test said it was waiting for a response that had already happened. Added waitForLoadState . Still hung. Added an explicit waitForSelector for an element that was clearly on the page. That passed. Then waitForResponse hung again. The response existed. The test couldn't see it. What was actually happening page.waitForResponse() is not a query. It doesn't look at what happened. It registers a listener — from that exact moment forward — and waits for the next matching response. The sequence in my code: Promise.all resolves when the URL changes to step=2 By the time the URL changed, step 2 had already loaded Step 2 had already sent and received /api/v1/doctors Then waitForResponse registered its listener Now it's waiting for the next /doctors response Which never comes Playwright doesn't buffer missed events. If the response fired before the listener was registered — it's gone. The fix await Promise . all ([ page . waitForURL ( /step=2/ ), page . waitForResponse ( r => r . url (). includes ( ' /doctors ' )), step1Next