javascriptchrome-devtools-protocol

DevToolsProtocol, Runtime.evaluate against worker execution context


In the console of chrome devtools there is a dropdown at the top to select the execution context.

Here is an example when on www.google.com

enter image description here

Changing the execution context changes the available global variables and what any console invoked .js can access

I'm trying to run some javascript via ChromeDevtools Protocol using the Runtime.evaluate function and I need to run it in the worker context.

Checking the CDP docs, I see that Runtime.evaluate takes a parameter ExecutionContextId. I initially made the assumption that the execution contexts via the DevTools window dropdown would be the same as this parameter. The only way I've worked out how to get a list of the the current ExecutionContextId's is to subscribe to the Runtime.executionContextCreated event then do a Runtime.disable followed by a Runtime.enable which causes an ExecutionContextDiscription to be received by the eventhandler for each loaded context.

However after looking though the ExecutionContextDescription's returned, some match those in the dropdown, but an execution context describing the worker is never returned.

How does one execute js in a worker execution context via CDP, as is trivially done in ChromeDevtools window ?


Solution

  • Whilst I did not find a way to do it with an execution context, I was able to achieve the end game via the below process.

    1. Get a list of the possible TargetID's
    2. Connect to the Target of interest with Target.attachToTarget & note the sessionId returned
    3. Call the CDP method of interest in "flat mode"

    Step 1 has a couple of approaches, and each additional step here may need to be applied in different situations.

    1. Call Target.getTargets which may return the target of interest
    2. Hook into the targetCreated event and call Target.setDiscoverTargets
    3. Call Target.setAutoAttach(true, false) before step 2
    4. Call Target.setAutoAttach(false, false) before step 3

    In my testing here, the worker of interest did not appear via method 1, but does appears in method 2, and in other situations I needed all 4 steps for the event handler to properly fire. I don't know why there is a difference.

    "Flat mode" as mentioned in the docs is basically any CDP command with a sessionId included. e.g.

    {"method": "Domain.method", "params": {"method params"}, "sessionId": "12345"}

    Credit goes to Puppeteer and its logs which helped me to decipher the process.