From d0cf9fa8ea2bb0616d40da7b046c7b109cbd9f00 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Tue, 16 Jun 2020 20:34:36 -0700 Subject: [PATCH] feat: expose sessionId in debugger module --- docs/api/debugger.md | 9 ++++- shell/browser/api/electron_api_debugger.cc | 17 ++++++++-- spec-main/api-debugger-spec.ts | 34 +++++++++++++++++++ .../fixtures/sub-frames/debug-frames.html | 8 +++++ spec-main/fixtures/sub-frames/test.js | 1 + 5 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 spec-main/fixtures/sub-frames/debug-frames.html create mode 100644 spec-main/fixtures/sub-frames/test.js diff --git a/docs/api/debugger.md b/docs/api/debugger.md index f912c979f5a56..969f6e6903f9c 100644 --- a/docs/api/debugger.md +++ b/docs/api/debugger.md @@ -52,6 +52,8 @@ Returns: * `method` String - Method name. * `params` any - Event parameters defined by the 'parameters' attribute in the remote debugging protocol. +* `sessionId` String - Unique identifier of attached debugging session, + will match the value sent from `debugger.sendCommand`. Emitted whenever the debugging target issues an instrumentation event. @@ -74,11 +76,16 @@ Returns `Boolean` - Whether a debugger is attached to the `webContents`. Detaches the debugger from the `webContents`. -#### `debugger.sendCommand(method[, commandParams])` +#### `debugger.sendCommand(method[, commandParams, sessionId])` * `method` String - Method name, should be one of the methods defined by the [remote debugging protocol][rdp]. * `commandParams` any (optional) - JSON object with request parameters. +* `sessionId` String (optional) - send command to the target with associated + debugging session id. The initial value can be obtained by sending + [Target.attachToTarget][attachToTarget] message. + +[attachToTarget]: https://chromedevtools.github.io/devtools-protocol/tot/Target/#method-attachToTarget Returns `Promise` - A promise that resolves with the response defined by the 'returns' attribute of the command description in the remote debugging protocol diff --git a/shell/browser/api/electron_api_debugger.cc b/shell/browser/api/electron_api_debugger.cc index c029c891b56bb..19832117d7967 100644 --- a/shell/browser/api/electron_api_debugger.cc +++ b/shell/browser/api/electron_api_debugger.cc @@ -58,11 +58,13 @@ void Debugger::DispatchProtocolMessage(DevToolsAgentHost* agent_host, std::string method; if (!dict->GetString("method", &method)) return; + std::string session_id; + dict->GetString("sessionId", &session_id); base::DictionaryValue* params_value = nullptr; base::DictionaryValue params; if (dict->GetDictionary("params", ¶ms_value)) params.Swap(params_value); - Emit("message", method, params); + Emit("message", method, params, session_id); } else { auto it = pending_requests_.find(id); if (it == pending_requests_.end()) @@ -149,14 +151,25 @@ v8::Local Debugger::SendCommand(gin_helper::Arguments* args) { base::DictionaryValue command_params; args->GetNext(&command_params); + std::string session_id; + if (args->GetNext(&session_id) && session_id.empty()) { + promise.RejectWithErrorMessage("Empty session id is not allowed"); + return handle; + } + base::DictionaryValue request; int request_id = ++previous_request_id_; pending_requests_.emplace(request_id, std::move(promise)); request.SetInteger("id", request_id); request.SetString("method", method); - if (!command_params.empty()) + if (!command_params.empty()) { request.Set("params", base::Value::ToUniquePtrValue(command_params.Clone())); + } + + if (!session_id.empty()) { + request.SetString("sessionId", session_id); + } std::string json_args; base::JSONWriter::Write(request, &json_args); diff --git a/spec-main/api-debugger-spec.ts b/spec-main/api-debugger-spec.ts index 671c29974b51e..dc31b13e89231 100644 --- a/spec-main/api-debugger-spec.ts +++ b/spec-main/api-debugger-spec.ts @@ -229,5 +229,39 @@ describe('debugger module', () => { w.loadURL(`http://127.0.0.1:${(server.address() as AddressInfo).port}`); }); }); + + it('uses empty sessionId by default', async () => { + w.webContents.loadURL('about:blank'); + w.webContents.debugger.attach(); + const onMessage = emittedOnce(w.webContents.debugger, 'message'); + await w.webContents.debugger.sendCommand('Target.setDiscoverTargets', { discover: true }); + const [, method, params, sessionId] = await onMessage; + expect(method).to.equal('Target.targetCreated'); + expect(params.targetInfo.targetId).to.not.be.empty(); + expect(sessionId).to.be.empty(); + w.webContents.debugger.detach(); + }); + + it('creates unique session id for each target', (done) => { + w.webContents.loadFile(path.join(__dirname, 'fixtures', 'sub-frames', 'debug-frames.html')); + w.webContents.debugger.attach(); + let session: String; + + w.webContents.debugger.on('message', (event, ...args) => { + const [method, params, sessionId] = args; + if (method === 'Target.targetCreated') { + w.webContents.debugger.sendCommand('Target.attachToTarget', { targetId: params.targetInfo.targetId, flatten: true }).then(result => { + session = result.sessionId; + w.webContents.debugger.sendCommand('Debugger.enable', {}, result.sessionId); + }); + } + if (method === 'Debugger.scriptParsed') { + expect(sessionId).to.equal(session); + w.webContents.debugger.detach(); + done(); + } + }); + w.webContents.debugger.sendCommand('Target.setDiscoverTargets', { discover: true }); + }); }); }); diff --git a/spec-main/fixtures/sub-frames/debug-frames.html b/spec-main/fixtures/sub-frames/debug-frames.html new file mode 100644 index 0000000000000..f93243e553b6c --- /dev/null +++ b/spec-main/fixtures/sub-frames/debug-frames.html @@ -0,0 +1,8 @@ + + + + This is a frame, is has one child + + + + \ No newline at end of file diff --git a/spec-main/fixtures/sub-frames/test.js b/spec-main/fixtures/sub-frames/test.js new file mode 100644 index 0000000000000..e921523b1b42e --- /dev/null +++ b/spec-main/fixtures/sub-frames/test.js @@ -0,0 +1 @@ +console.log('hello');