In [1]:
const {Builder} = require('selenium-webdriver');
const CRI = require('chrome-remote-interface'); // https://github.com/cyrus-and/chrome-remote-interface

In [ ]:
driver = new Builder().forBrowser('chrome').build();

In [ ]:
// https://bugs.chromium.org/p/chromedriver/issues/detail?id=878
driver.get('chrome://version');
var port;
driver.findElement({id: 'command_line'}).then(async (element) => {
    const commandLine = await element.getText()
    const commands = commandLine.split(' ');
    const debuggerPort = commands.find((item) => item.startsWith('--remote-debugging-port'));
    port = debuggerPort.replace('--remote-debugging-port=', '')
})

In [4]:
var devOptions = {"port": port};

In [ ]:
var sessions = [];
var loadingComplete = false;
CRI(devOptions, (client) => {
    const {Network, Page, Target, Runtime} = client;
    const disconnect = async () => {
        if (loadingComplete && sessions.length > 2){
            await Network.emulateNetworkConditions({
                offline: true, 
                latency: 0, 
                downloadThroughput: 0, 
                uploadThroughput: 0, 
                connectionType: "none"
            });
            for (var session of sessions){
                if (session.includes('sub')){
                    const values = session.split('sub');
                    console.log(`\n\n ${values[0]} - ${values[1]}`);
                    await Target.sendMessageToTarget({
                        message:`{
                          \"id\":410,
                          \"method\":\"Target.sendMessageToTarget\",
                          \"params\":{
                              \"message\":\"{
                                  \\\"id\\\":12,
                                  \\\"method\\\":\\\"Network.emulateNetworkConditions\\\",
                                  \\\"params\\\":{
                                     \\\"offline\\\":true,
                                     \\\"latency\\\":0,
                                     \\\"downloadThroughput\\\":0,
                                     \\\"uploadThroughput\\\":0,
                                     \\\"connectionType\\\":\\\"none\\\"
                                   }
                               }\",
                          \"sessionId\":\"${values[1]}\"}}`,
                        "sessionId": values[0]
                    });
                } else {
                    console.log(`\n\n ${session}\n\n`);
                    await Target.sendMessageToTarget({
                        "sessionId": session,
                        message: `{
                           "id":412,
                           "method":"Network.emulateNetworkConditions",
                           "params":{
                              "offline":true,
                              "latency":0,
                              "downloadThroughput":0,
                              "uploadThroughput":0,
                              "connectionType":"none"
                              }
                           }`
                    }); 
                }
            }
        }
        else {
            console.log(`\n\n ${loadingComplete}, ${sessions} \n\n`)
        }
    };
    Target.receivedMessageFromTarget(async (params) => {
        if (params.message.startsWith('{"method":"Target.attachedToTarget"')) {
            const message = JSON.parse(params.message);
            const sessionId = message.params.sessionId;
            sessions.push(`${params.sessionId}sub${sessionId}`);
            disconnect();
            console.log("\n\nFound the dedicated Worker: ", sessionId)
            console.log(message.params, "\n\n")
        } else {
            console.log('receivedMessageFromTarget: =>', params)
        }
    });
    Target.attachedToTarget(async (params) => {
        const targetId = params.targetInfo.targetId;
        const sessionId = params.sessionId;
        sessions.push(sessionId);
        const workerType = params.targetInfo.type;
        const title = params.targetInfo.title;
        console.log(`\n\n${sessionId}, ${workerType}, ${title}\n\n`);
        disconnect();
        if (workerType === 'service_worker' || workerType === 'worker') {
            if (workerType === 'service_worker') swSessionId = sessionId;
            await Target.sendMessageToTarget({
                message:`{
                    "id":63,
                    "method":"Target.setAutoAttach",
                    "params":{
                        "autoAttach":true,
                        "waitForDebuggerOnStart":true
                     }
                }`, 
                "sessionId": sessionId});
            await Target.sendMessageToTarget({
                message:`{"id":65,"method":"Runtime.runIfWaitingForDebugger"}`, 
                "sessionId": sessionId});
        }      
    });
    Promise.all([
        Network.enable({"maxPostDataSize":65536}),
        Page.enable()
    ]).then( async () => {
        await Target.setAutoAttach({autoAttach:true, waitForDebuggerOnStart:true})
        await Runtime.runIfWaitingForDebugger();
        
        await driver.get('http://staging.com/myawesomeapp');
        await driver.findElement({id: 'email'}).sendKeys(credentials.email);
        await driver.findElement({id: "continue"}).click();
        await driver.findElement({id: 'password'}).sendKeys(credentials.password);
        await driver.findElement({css: 'button[value="signin"]'}).click();
        // ... load the ServiceWorker here
        loadingComplete = true;
        disconnect();
        
    }).catch((err) => {
        console.error(`ERROR: ${err.message}`);
        client.close();
    });
}).on('error', (err) => {
    console.error('Cannot connect to remote endpoint:', err);
});

In [ ]:
driver.quit();