google-chromeselenium-chromedriverchrome-devtools-protocol

Chrome Devtools Protocol: Runtime.evaluate execution problem


I'm maintaining a testing framework that we've been using to evaluate our web UI, based on a fork of MasterDevs C# library. To catch up with some of the security fixes, I've had to update our headless chrome executable to the latest(ish) version.

After getting through the argument changes and the newer options available, I have one last issue I just can't figure out: When I try to run a simple JS expression such as document.body.outerHTML I always get the same response:

{
  "id": 13,
  "error": {
    "code": -32000,
    "message": "Execution was terminated"
  }
}

I always execute Runtime.enable before trying to run this, and I've specified execution context ids, frame id values, and attached to targets, as well as tried various suggested combinations of the options.

Finally, I installed Selenium to run the same setup and eavesdropped using Wireshark, and noticed that Selenium is getting the session Id early on from the Target.attachToTarget response and sending that with just about every command. I tried to do the same, and now the only difference is that I get the sessionId echoed back (just like in Selenium) like so:

{
  "id": 13,
  "error": {
    "code": -32000,
    "message": "Execution was terminated"
  },
  "sessionId": "086FCC1BC3D0825D2B2C1A08742190CD"
}

I've also dug through all the command line switches and options I could find (in case there's some security setting I'm unaware of), to no avail. In the interest of thoroughness, this is the script I'm using on Linux to run the downloaded chrome package:

#!/bin/bash
./chrome-linux/chrome --remote-debugging-port=9720  --disable-gpu --bwsi --no-first-run --enable-automation --disable-notifications --remote-allow-origins=* --disable-client-side-phishing-detection --disable-sync --disable-features=ChromeWhatsNewUI

Aside from digging through the gigs and gigs of Chromium source code, I am at a loss. Neither "Execution was terminated" nor "-32000" seem to come up anywhere via forum or web searches in conjunction with CDP.

Thanks in advance, David


Solution

  • So, in case anyone else runs into this, a colleague of mine helped me figure out the core issue.

    The problem, in this case, didn't have to do with the protocol directly, but with the serialization of the Runtime.evaluate request.

    Basically, the generator didn't correctly handle the optional property timeout in the Runtime.evaluate command, so it was sending a timeout of zero in the background (even though we never set that property).

    I expected to send (and thought I was sending)

    {
        "command":"Runtime.evaluate",
        "params": {
            "expression": "document.body.outerHTML"
        }
    }
    

    but instead I was sending

    {
        "command":"Runtime.evaluate",
        "params": {
            "expression": "document.body.outerHTML",
            "timeout": 0
        }
    }
    

    which (not unreasonably) means immediately stop waiting to complete ("Execution was terminated").

    I changed the property to

    public double? Timeout {get; set;} 
    

    and that fixed it.

    Hope this saves someone else time with this kind of problem.