简体   繁体   中英

debug in chromium / puppeteer doesn't populate evaluate script

So I have the following code launching

this.browser = await puppeteer.launch( { headless: false, devtools: true, slowMo: 200});
this.page = await this.browser.newPage();

await this.page.goto(pageUrl);

let result = await this.page.evaluate(() => {
            const labels = document.querySelectorAll("li.product-item");

            let productList = [];

            for(let product of labels) {
                productList.push(product);
            }
            debugger;

            //filter only product stacks that have a price
            const productStacks = productList.filter(product => product.querySelector("span.price-wrapper") !== null);

            let results = productStacks.map(product => {
                return product.querySelector("span.price-wrapper").getAttribute("data-price-amount");
            });

            return results;
        });

So chromium starts up and pauses at the appropriate code (as best as I can tell), I can even see the local variables populate with the expect result and step through the code, however the open file puppeteer_evaluation_script is not populated with the evaluation script and remains with the contents, so I'm stepping through blind.

//# sourceURL=__puppeteer_evaluation_script__

Occasionally after many minutes it sometimes does actually populate with the code. I have no idea what's wrong, I've tried updating the latest node lts and puppeteer but have the same behavior.

I don't know what causes this issue, but here is a pair of possible solutions.

To avoid getting:

//# sourceURL=__puppeteer_evaluation_script__

You can expose a function:

const puppeteer = require('puppeteer'); 

var browser = null;
var page = null;

(async () => 
{
    browser = await puppeteer.launch(
    {
        headless: false,
        devtools: true,
    });

    page = await browser.newPage();

    await page.goto("https://google.com/");

    // Expose a function
    page.exposeFunction("nothing", () => null);


    await page.evaluate(async function()
    {
        debugger;
        
        console.log("Do task");
    });
})();

In case that fails in the future. I made a wrapper for using eval() since the source appears using that. It works with both sync and async functions and supports passing args and returning values.

function evaluateFixed(page, realFunction)
{
    return page.evaluate(async function(realFunction, args)
    {
        var func = eval(`(${realFunction})`);

        if(func.constructor.name === "AsyncFunction")
            return await func(...args);
        else
            return func(...args);
    },
    realFunction.toString(), Array.from(arguments).slice(2));
}


(async () => 
{
    browser = await puppeteer.launch(
    {
        headless: false,
        devtools: true,
    });

    
    page = await browser.newPage();

    await page.goto("https://google.com/");

    console.log("Doing test");

    let res = await evaluateFixed(page, async function(x, y, z)
    {
        debugger;

        console.log("Do task", x, y, z);

        function sleep(amount)
        {
            return new Promise((resolve) => setTimeout(resolve, amount));
        }
        
        for(let  i = 0; i < 10; i++)
        {
            console.log("on seconds", i);
            await sleep(1000);
        }

        return { "fee": "foo" };

    }, 1, "two", { "three": 3});
    
    console.log("Res 1", res);
    

    res = await evaluateFixed(page, () =>
    {
        debugger;

        return 1 + 2;
    });
    
    console.log("Res 2", res);
    
})();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM