[solved] Update to 90.6.7, ExecuteDevToolsMethod not working

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

[solved] Update to 90.6.7, ExecuteDevToolsMethod not working

Postby olzzen » Mon Jun 14, 2021 3:24 am

Hi,

we are using the CEF framework on linux for many years now. The version we have used so far is cef-3.2785.1485. Due to availability/visualization problems with newer JS/CSS functions, we have to update to a newer CEF version.

We have seen that there are many, many changes in the new CEF-API and the used concepts. I know we should actually go through the changes between the different versions in order to see how the new concepts are. But we can't make that effort. We have adapted our code to the new API, in order to successfully compile it. But we consider some runtime problems.

1. We have used the CefFrame::LoadString method to make a screenshot of the visualized content. Our approach was to use a CefStringVisitor to get the visualized content in the current frame, and then create a separate OSR-Browser and load the string. The resulting screenshot was very close to the original.

Now, after the LoadString method has gone, we used the LoadURL method with an in-place url (using createDataURI from ceftests). Unfortunately the result is anything but close to the original and we don't know why.

We googled a bit and found a hint on the CDP which would enable us to get rid of the OSR approach. We have tried to use the Page.notifications to make a screenshot but without any luck. We are getting the error, that the requested methods can't be found.
The following code shows the output from the js console whithin chromium of our attempt to call a method over CDP within cefsimple (cef_binary_90.6.7+g19ba721+chromium-90.0.4430.212).
Code: Select all
> var ws = new WebSocket("ws://127.0.0.1:9222/devtools/browser/d61e61a5-a45c-46aa-835d-77181fb1449c");
undefined
> ws.onmessage = function(m){console.log(m)};
ƒ (m){console.log(m)}
> ws.readyState
1
> ws.send(JSON.stringify({id:1,method:"Page.enable"}));
undefined
VM450:1 MessageEvent {isTrusted: true, data: "{"id":1,"error":{"code":-32601,"message":"'Page.enable' wasn't found"}}", origin: "ws://127.0.0.1:9222", lastEventId: "", source: null, …}
> ws.send(JSON.stringify({id:1,method:"Page.captureScreenshot"}));
undefined
VM450:1
MessageEvent {isTrusted: true, data: "{"id":1,"error":{"code":-32601,"message":"'Page.captureScreenshot' wasn't found"}}", origin: "ws://127.0.0.1:9222", lastEventId: "", source: null, …}
  isTrusted: true
  data: "{"id":1,"error":{"code":-32601,"message":"'Page.captureScreenshot' wasn't found"}}"
  origin: "ws://127.0.0.1:9222"
  lastEventId: ""
  source: null
  ports: []
  userActivation: null
  type: "message"
  target: WebSocket {url: "ws://127.0.0.1:9222/devtools/browser/d61e61a5-a45c-46aa-835d-77181fb1449c", readyState: 1, bufferedAmount: 0, onopen: null, onerror: null, …}
  currentTarget: WebSocket
  url: "ws://127.0.0.1:9222/devtools/browser/d61e61a5-a45c-46aa-835d-77181fb1449c"
  readyState: 1
  bufferedAmount: 0
  onopen: null
  onerror: null
  onclose: null
  extensions: "permessage-deflate; client_max_window_bits=15"
  protocol: ""
  onmessage: ƒ (m)
  binaryType: "blob"
  __proto__: WebSocket
  eventPhase: 0
  bubbles: false
  cancelable: false
  defaultPrevented: false
  composed: false
  timeStamp: 316029.43000011146
  srcElement: WebSocket {url: "ws://127.0.0.1:9222/devtools/browser/d61e61a5-a45c-46aa-835d-77181fb1449c", readyState: 1, bufferedAmount: 0, onopen: null, onerror: null, …}
  returnValue: true
  cancelBubble: false
  path: []
  __proto__: MessageEvent


Do you have any hints or ideas where the problem is?

2. We have our own certificate handling, with the ability to import a certificate into the nss database. To decide wether or not a certificate should be imported, we have used url schemes like "certificate_import://..." in combination with the LoadString method. Now when the in-place url is used instead, this is not going to work any longer.

Same here, do you have any hints or ideas how we can support the certificate handling with the new API?

Thanks in advance!
Last edited by olzzen on Mon Jun 21, 2021 1:50 am, edited 2 times in total.
olzzen
Techie
 
Posts: 46
Joined: Fri Oct 23, 2015 1:01 am

Re: Update from 3.2785.1485 to 90.6.7, screenshot and devtoo

Postby olzzen » Mon Jun 14, 2021 7:54 am

We now have successfully connected to the Page-Domain via CDP.

The problem was that we testet the wrong websocket address. We have used the "webSocketDebuggerUrl" shown at: http://127.0.0.1:9222/json/version
But this is the address of the browser itself. Instead we have to use the "webSocketDebuggerUrl" shown at: http://127.0.0.1:9222/json
[ {
"description": "",
"devtoolsFrontendUrl": "/devtools/inspector.html?ws=127.0.0.1:9222/devtools/page/91F54506339B488D959D7F2010053628",
"id": "91F54506339B488D959D7F2010053628",
"title": "Google",
"type": "page",
"url": "https://www.google.com/?gws_rd=ssl",
"webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/page/91F54506339B488D959D7F2010053628"
} ]

So far so good. We are now able to send commands via CDP. Besides our Tests we have recognized, that CEF offers the possibility to send messages directly to the devtools via ExecuteDevToolsMethod. So we implemented the following minimal code:
Code: Select all
class DevToolsMessageObserver : public CefDevToolsMessageObserver
{
    // CefDevToolsMessageObserver interface
public:
    void OnDevToolsMethodResult(CefRefPtr<CefBrowser> browser, int message_id, bool success,
                                const void *result, size_t result_size) override
    {
        printf("OnDevToolsMethodResult: message_id = %d size = %d\n", message_id, result_size);
    }

    void OnDevToolsEvent(CefRefPtr<CefBrowser> browser, const CefString &method, const void *params,
                         size_t params_size) override
    {
        printf("OnDevToolsEvent:...\n");
    }

private:
    IMPLEMENT_REFCOUNTING(DevToolsMessageObserver);
};

void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser)
{
  browser->GetHost()->AddDevToolsMessageObserver(new DevToolsMessageObserver);
 }

void ClientHandler::CreateThumbnail(CefRefPtr<CefBrowser> browser)
{
  browser->GetHost()->ExecuteDevToolsMethod(0, "Page.captureScreenshot", {});
}


After calling the "CreateThumbnail" method none of the CefDevToolsMessageObserver-callbacks were called. Do we miss something here?
olzzen
Techie
 
Posts: 46
Joined: Fri Oct 23, 2015 1:01 am

Re: Update 3.2785 to 90.6.7, ExecuteDevToolsMethod not worki

Postby olzzen » Fri Jun 18, 2021 7:58 am

After two more days of code adjustment to fit the new CEF version 91 we are still not able to get ExecuteDevToolsMethod to work. None of the callbacks in our CefDevToolsMessageObserver-implemenation are getting called. The curious thing is that it works in the ceftests unittests and also if we use a separate chromium dev console to connect to the debugger websocket and use this connection for sending the commands.
Are there any suggestions on that?
olzzen
Techie
 
Posts: 46
Joined: Fri Oct 23, 2015 1:01 am

Re: Update 3.2785 to 90.6.7, ExecuteDevToolsMethod not worki

Postby magreenblatt » Fri Jun 18, 2021 9:38 am

Maybe you’re formatting the messages incorrectly. CEF has a logging capability that lets you record messages sent by DevTools, etc. Add “--devtools-protocol-log-file=<path>” to your command-line.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: Update 3.2785 to 90.6.7, ExecuteDevToolsMethod not worki

Postby olzzen » Fri Jun 18, 2021 11:23 am

Ok, we have give it a try. But we see no problem with the message-formatting within the following code, do you?

Code: Select all
void ClientHandler::CreateThumbnail(CefRefPtr<CefBrowser> browser)
{
  browser->GetHost()->ExecuteDevToolsMethod(0, "Page.captureScreenshot", {});
}


The only relevant output we can identify is that the Page-Target gets created:
Code: Select all
0618/181303.967923: EVENT: {"method":"Target.targetCreated","params":{"targetInfo":{"targetId":"6A24BAFE787934CB17D994927A455799","type":"page","title":"DevTools","url":"devtools://devtools/devtools_app.html","attached":true,"canAccessOpener":false,"browserContextId":"C6034102C31FCD297E0215E3A3F755A6"}}}
0618/181303.967984: EVENT: {"method":"Target.targetCreated","params":{"targetInfo":{"targetId":"AE8146556DADF3063F4D1BC391883B31","type":"page","title":"MyPageTitle","url":"file://MyHtmlFile.html","attached":true,"canAccessOpener":false,"browserContextId":"C6034102C31FCD297E0215E3A3F755A6"}}}


But there is no "Page.captureScreenshot" in the logfile. Do we have to use the targetId or the browserContextfor sending messages, and if so, where to set this information?
olzzen
Techie
 
Posts: 46
Joined: Fri Oct 23, 2015 1:01 am

Re: Update 3.2785 to 90.6.7, ExecuteDevToolsMethod not worki

Postby magreenblatt » Fri Jun 18, 2021 11:53 am

What does the DevTools protocol documentation say? What does the captureScreenshot message look like when DevTools sends it?
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: Update 3.2785 to 90.6.7, ExecuteDevToolsMethod not worki

Postby olzzen » Fri Jun 18, 2021 12:51 pm

The CDP defines the method with all parameters as optional.

I can successfully call the method from a chromium dev console with the following code, where the websocket address is from the loaded page within CEF:
[ {
"description": "",
"devtoolsFrontendUrl": "/devtools/inspector.html?ws=127.0.0.1:4711/devtools/page/A3C66DF289D0404BFB6FC9C55BB399CB",
"id": "A3C66DF289D0404BFB6FC9C55BB399CB",
"title": "MyPageTitle",
"type": "page",
"url": "file://MyHtmlFile.html",
"webSocketDebuggerUrl": "ws://127.0.0.1:4711/devtools/page/A3C66DF289D0404BFB6FC9C55BB399CB"
} ]


Code: Select all
var ws = new WebSocket("ws://127.0.0.1:4711/devtools/page/A3C66DF289D0404BFB6FC9C55BB399CB");
ws.onmessage=function(text){console.log(text);};
ws.send(JSON.stringify({id:0,method:"Page.captureScreenshot"}));
>>> MessageEvent {isTrusted: true, data: "{"id":0,"result":{"data":"iVBORw0KGgoAAAANSUhEUgAA…oAACABcQUAAJDA/weZkn7W5q8nvAAAAABJRU5ErkJggg=="}}", origin: "ws://127.0.0.1:4711", lastEventId: "", source: null,...}


I tested the method with the page websocket and also with the devtools websocket. In both cases the screenshot was successfully created but without any output in the devtools-protocol-file...

If i set up the websocket within the CEF devtools and send the message, the following output is generated within the logfile:
Code: Select all
0618/200724.966197: EVENT: {"method":"Network.webSocketFrameSent","params":{"requestId":"24406.238","timestamp":128249.916497,"response":{"opcode":1,"mask":true,"payloadData":"{\"id\":0,\"method\":\"Page.captureScreenshot\"}"}}}
0618/200724.966221: RESULT: {"id":292,"result":{"result":{"type":"undefined"}}}
0618/200724.966239: RESULT: {"id":293,"result":{}}
0618/200725.116130: EVENT: {"method":"Network.webSocketFrameReceived","params":{"requestId":"24406.238","timestamp":128250.091509,"response":{"opcode":1,"mask":false,"payloadData":"{\"id\":0,\"result\":{\"data\":\"iVBORw0KGgoAAAANSUhEUgAAA1cAAAI5CAYAAABNS8BuAAAc9NF
0618/200725.116484: EVENT: {"method":"Runtime.consoleAPICalled","params":{"type":"log","args":[{"type":"object","className":"MessageEvent","description":"MessageEvent","objectId":"63404150415154075.1.177","preview":{"type":"object","description":"MessageEvent","overflow":true,"properties":[{"name":"isTrusted","type":"boolean","value":"true"},{"name":"data","type":"string","value":"{\"id\":0,\"result\":{\"data\":\"iVBORw0KGgoAAAANSUhEUgAA\u2026oAACABcQUAAJDA/weZkn7W5q8nvAAAAABJRU5ErkJggg==\"}}"},{"name":"origin","type":"string","value":"ws://127.0.0.1:4711"},{"name":"lastEventId","type":"string","value":""},{"name":"source","type":"object","value":"null","subtype":"null"}]}}],"executionContextId":1,"timestamp":1.6240396450917302e+12,"stackTrace":{"callFrames":[{"functionName":"ws.onmessage","scriptId":"407","url":"","lineNumber":0,"columnNumber":36}]}}}
0618/200748.266191: METHOD: {"id":294,"method":"Runtime.compileScript","params":{"expression":"ws.send(JSON.stringify({id:0,method:\"Page.captureScreenshot\"}));","sourceURL":"","persistScript":false,"executionContextId":1}}
0618/200748.266249: METHOD: {"id":295,"method":"Runtime.evaluate","params":{"expression":"ws.send(JSON.stringify({id:0,method:\"Page.captureScreenshot\"}));","includeCommandLineAPI":true,"uniqueContextId":"-4498111015539562277.7605617464319511894","generatePreview":true,"userGesture":false,"awaitPromise":false,"throwOnSideEffect":true,"timeout":500,"disableBreaks":true,"replMode":true}}
0618/200748.316080: RESULT: {"id":294,"result":{}}
0618/200748.316105: EVENT: {"method":"Debugger.scriptParsed","params":{"scriptId":"416","url":"","startLine":0,"startColumn":0,"endLine":0,"endColumn":64,"executionContextId":1,"hash":"364e41896caa2765357553862a30d8113163f6e0","executionContextAuxData":{"isDefault":true,"type":"default","frameId":"AE8146556DADF3063F4D1BC391883B31"},"isLiveEdit":false,"sourceMapURL":"","hasSourceURL":false,"isModule":false,"length":64,"scriptLanguage":"JavaScript","embedderName":""}}
0618/200748.316146: RESULT: {"id":295,"result":{"result":{"type":"object","subtype":"error","className":"EvalError","description":"EvalError: Possible side-effect in debug-evaluate","objectId":"63404150415154075.1.178"},"exceptionDetails":{"exceptionId":49,"text":"Uncaught","lineNumber":-1,"columnNumber":-1,"scriptId":"1","exception":{"type":"object","subtype":"error","className":"EvalError","description":"EvalError: Possible side-effect in debug-evaluate","objectId":"63404150415154075.1.179"}}}}
olzzen
Techie
 
Posts: 46
Joined: Fri Oct 23, 2015 1:01 am

Re: Update 3.2785 to 90.6.7, ExecuteDevToolsMethod not worki

Postby amaitland » Sun Jun 20, 2021 7:34 pm

Try
Code: Select all
browser->GetHost()->ExecuteDevToolsMethod(1, "Page.captureScreenshot", CefDictionaryValue::Create());


Is the observer added before the call to ExecuteDevToolsMethod? That's a must in my experience, cannot tell from your code.

In the context of `CefSharp` I've had no problems calling `Page.captureScreenshot` works as expected.
Maintainer of the CefSharp project.
amaitland
Virtuoso
 
Posts: 1290
Joined: Wed Jan 14, 2015 2:35 am

Re: Update 3.2785 to 90.6.7, ExecuteDevToolsMethod not worki

Postby magreenblatt » Sun Jun 20, 2021 8:29 pm

AddDevToolsMessageObserver returns a Registration object. You need to hold a reference to keep the registration alive.
magreenblatt
Site Admin
 
Posts: 12382
Joined: Fri May 29, 2009 6:57 pm

Re: Update 3.2785 to 90.6.7, ExecuteDevToolsMethod not worki

Postby olzzen » Mon Jun 21, 2021 1:49 am

amaitland wrote:Try
Code: Select all
browser->GetHost()->ExecuteDevToolsMethod(1, "Page.captureScreenshot", CefDictionaryValue::Create());


Is the observer added before the call to ExecuteDevToolsMethod? That's a must in my experience, cannot tell from your code.

In the context of `CefSharp` I've had no problems calling `Page.captureScreenshot` works as expected.


Yes, the observer is created and added before the very first call to ClientHandler::CreateThumbnail.

magreenblatt wrote:AddDevToolsMessageObserver returns a Registration object. You need to hold a reference to keep the registration alive.


This is it! I am sorry, i obviously didn't read the documenation carefully!

Code: Select all
...
The observer will remain registered until the returned Registration object is destroyed.
...


Thank you very much! Marking thread as solved.
olzzen
Techie
 
Posts: 46
Joined: Fri Oct 23, 2015 1:01 am


Return to Support Forum

Who is online

Users browsing this forum: No registered users and 23 guests