webdriverio icon indicating copy to clipboard operation
webdriverio copied to clipboard

[🐛 Bug]: CDP network emulation does not work in headless mode

Open johnBartos opened this issue 3 years ago • 7 comments

Have you read the Contributing Guidelines on issues?

WebdriverIO Version

latest

Node.js Version

latest

Mode

WDIO Testrunner

Which capabilities are you using?

{
            browserName: 'chrome',
            'goog:loggingPrefs': {
                browser: 'ALL',
            },
            maxInstances: 1,
            browserName: 'chrome',
            acceptInsecureCerts: true,
            'goog:chromeOptions': {
                args: [
                    '--auto-open-devtools-for-tabs',
                    '--no-sandbox',
                    '--disable-infobars',
                    '--headless',
                    '--window-size=1920,1080',
                    '--disk-cache-dir=/dev/null',
                ],
            },
        },

What happened?

When using CDP via the devtools service (browser.cdp), network emulation does not work in headless mode.

What is your expected behavior?

Network emulation works in headless mode

How to reproduce the bug.

    await browser.cdp('Network', 'enable');
    const conditions = {
        downloadThroughput: -1,
        uploadThroughput: -1,
        latency: 0,
        offline: true,
    };
    await browser.cdp('Network', 'emulateNetworkConditions', conditions);
 
    // do something

This does not cause the network to go offline. If I comment out the --headless flag in capabilities, the network will go offline when called.

Relevant log output

n/a

Code of Conduct

  • [X] I agree to follow this project's Code of Conduct

Is there an existing issue for this?

  • [X] I have searched the existing issues

johnBartos avatar Nov 18 '21 20:11 johnBartos

Have you tried using the throttle command?

christian-bromann avatar Nov 18 '21 20:11 christian-bromann

Thanks for response! Yes, it has the same result. The only thing I can think of is that in headless mode, the devtools tab doesn't open (I took a screenshot). Without the devtools open throttling doesn't seem to work. Is there a flag or command to force devtools open for headless? '--auto-open-devtools-for-tabs' doesn't seem to do the trick

johnBartos avatar Nov 18 '21 22:11 johnBartos

The webworker is doing the network requests in my app. Maybe that has something to do with it? I did a really basic test of simply navigating to google in headless mode and it respected offline mode:

        await browser.throttle('offline');
        await browser.url('http://google.com');

I see puppeteer attaching to me worker though. I diffed the logs headless/headed and didn't see any differences

johnBartos avatar Nov 18 '21 22:11 johnBartos

Ok I actually figured this out. I had to manually access the worker via Puppeteer and send Network.enable:

async function enableWorkerNetworkEmulation() {
    const puppet = await browser.getPuppeteer();
    const targets = await puppet.targets();
    const worker = targets.find((t) => t.type() === 'other');
    const workerConnection = await worker.createCDPSession();
    await workerConnection.send('Network.enable');
}

After this, throttling via browser.throttle works as expected. I found a lot of context around workers and CDP here: https://github.com/puppeteer/puppeteer/issues/2469

It seems like this might be straightforward to fix on your end - you'd have to wait until the worker was created (puppeteer has an event for this I think), and then send it Network.enable

johnBartos avatar Nov 19 '21 16:11 johnBartos

@johnBartos thanks for this indepth research! Would you be open to take a stab at this as you have most of the context? Happy to support in any way.

christian-bromann avatar Nov 19 '21 17:11 christian-bromann

I would love to contribute but it will take a while before I can get around to it, so if you'd like to patch this sooner than later please don't wait on me. What would help are a few relevant files which need to be changed (where we start the puppet session would be helpful).

johnBartos avatar Nov 19 '21 21:11 johnBartos

where we start the puppet session would be helpful

Please checkout the devtools package which is the automation lib WebdriverIO uses if no automation driver is setup and everything runs through Puppeteer. Then we have a method called getPuppeteer that we use in WebdriverIO to attach to a running browser.

christian-bromann avatar Nov 22 '21 09:11 christian-bromann