pythonfirefoxwebsocketchrome-devtools-protocol

How to send messages to Firefox through devtools protocol?


i'm trying to write my own custom webdriver interface to control firefox through chrome devtools protocol (cdp). i launch firefox using firefox-esr --remote-debugging-port 0 and then it creates a websocket that i connect to using python:

async def main_client():
    async with websockets.connect("ws://localhost:34805/devtools/browser/f67014fd-9397-478d-a11e-66c189704ab0") as client_connection:
        while True:
            message = input("type in a command: ")
            await client_connection.send(message)

asyncio.run(main_client())

then i send a message in json format

{
"command":"Runtime.evaluate",
"parameters":{"expression": "console.log(\"this is a message\")"}
}

the problem is that when i send the message nothing happens on the receiving end. does anyone know how to send messages over websocket to firefox?

thanks


Solution

  • so i did a bit more research and it turns out that to be able to interact with firefox cdp after starting using ./firefox --remote-debugging-port 12345 you need to make a get request to localhost:12345/json/list. here you will find the list of websocket targets you can connect to. by default you have a top most browser target that doesn't have any tab elements to interact with and then you have tab targets that you can interact with. here is any example of a json list when starting firefox cdp:

    [
        {
            "description": "",
            "devtoolsFrontendUrl": null,
            "faviconUrl": "",
            "id": "ef9b04c6-409f-4fe9-bea9-c50979049820",
            "type": "page",
            "url": "about:blank",
            "webSocketDebuggerUrl": "ws://127.0.0.1:12345/devtools/page/ef9b04c6-409f-4fe9-bea9-c50979049820"
        },
        {
            "description": "Main process target",
            "devtoolsFrontendUrl": "",
            "faviconUrl": "",
            "id": "c726e615-36cc-4a73-a48a-a75cc0fa941e",
            "title": "Main process target",
            "type": "browser",
            "url": "",
            "webSocketDebuggerUrl": "ws://127.0.0.1:12345/devtools/browser/c726e615-36cc-4a73-a48a-a75cc0fa941e"
        }
    ]
    

    after getting the json response with the json list then you can connect to one of the websockets using python and then you can send messages through websocket.

    not all targets support all cdp commands. also some cdp commands require a response but some don't, although if the command was unsuccessful, you will get a response with the error message. you can find a list of all cdp commands at https://chromedevtools.github.io/devtools-protocol/ and you can find all the supported cdp commands by your firefox version at http://localhost:12345/json/protocol after launching firefox with cdp.

    i still haven't figured out how to run Runtime.evaluate because you need to specify a contextId (it says it's optional but when sending commands through websocket it is required) and i don't know where to get the current context id from. if anyone finds out let me know.