Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: expose sessionId in debugger module #24398

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 8 additions & 1 deletion docs/api/debugger.md
Expand Up @@ -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.

Expand All @@ -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<any>` - A promise that resolves with the response defined by
the 'returns' attribute of the command description in the remote debugging protocol
Expand Down
17 changes: 15 additions & 2 deletions shell/browser/api/electron_api_debugger.cc
Expand Up @@ -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", &params_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())
Expand Down Expand Up @@ -149,14 +151,25 @@ v8::Local<v8::Promise> 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);
Expand Down
34 changes: 34 additions & 0 deletions spec-main/api-debugger-spec.ts
Expand Up @@ -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 });
});
});
});
8 changes: 8 additions & 0 deletions spec-main/fixtures/sub-frames/debug-frames.html
@@ -0,0 +1,8 @@
<!DOCTYPE html>
<html lang="en">
<body>
This is a frame, is has one child
<iframe src="./frame.html"></iframe>
</body>
<script src="./test.js"></script>
</html>
1 change: 1 addition & 0 deletions spec-main/fixtures/sub-frames/test.js
@@ -0,0 +1 @@
console.log('hello');