Why is `page.waitForFunction` not logging or hitting breakpoints in Playwright.js?

I’m trying to debug a callback inside page.waitForFunction in Playwright.js, but nothing I log appears, and breakpoints inside the callback are ignored. For example:

const { chromium } = require("playwright");

(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  const i = 0;
  await page
    .waitForFunction(
      (i) => {
        i++;
        console.log(`---> evaluating # ${i}`);
        if (i < 3) return false;
        return true;
      },
      i,
      { timeout: 3000 }
    )
    .catch(console.error);
  console.log("done");
  await browser.close();
})();

I expect it to log:

---> evaluating #1
---> evaluating #2
done

But I only see done. If the function always returns false, I get the timeout error as expected.

How can I debug or properly see what happens inside the page.waitForFunction callback?

The reason your console.log inside page.waitForFunction doesn’t appear is that the function runs in the browser context, not Node.js.

Anything you console.log inside that callback is executed in the page, so Node’s console won’t see it.

To debug, you can either:

  • Use page.evaluate to log directly in the browser’s console:

await page.evaluate(() => console.log("Inside page context"));

  • Use page.on(‘console’, …) to capture browser logs in Node.js:

page.on("console", (msg) => console.log("PAGE LOG:", msg.text()));

Then your waitForFunction logs will appear in Node’s terminal.

Another way I debugged waitForFunction callbacks is by attaching a console listener before calling it:

page.on("console", (msg) => console.log("PAGE LOG:", msg.text()));

let i = 0;
await page.waitForFunction(
  (i) => {
    i++;
    console.log(`Evaluating #${i}`);
    return i >= 3;
  },
  i
);

This captures all logs from the browser context, which is why your previous console.log calls seemed “ignored.”

Breakpoints inside Node won’t hit either, because the function is running inside the browser.

If logging isn’t enough, another approach is to return debug info from the function and print it in Node.js:

let result = await page.waitForFunction(
  (i) => {
    i++;
    return { done: i >= 3, count: i };
  },
  i
);
console.log(await result.jsonValue()); // { done: true, count: 3 }

This technique avoids relying on browser console.log and makes debugging deterministic.

I found it helpful when debugging repeated evaluations inside waitForFunction.