MCPcopy Create free account
hub / github.com/aeroxy/chrome-devtools-cli / ensure_persistent_session

Method ensure_persistent_session

src/cdp.rs:197–287  ·  view source on GitHub ↗

Ensure a persistent CDP session is attached to the given target for continuous event collection (Network + Console). If the target has changed, detaches the old session and attaches to the new one.

(&mut self, target_id: &str)

Source from the content-addressed store, hash-verified

195 /// event collection (Network + Console). If the target has changed, detaches
196 /// the old session and attaches to the new one.
197 pub async fn ensure_persistent_session(&mut self, target_id: &str) -> Result<()> {
198 // Already attached to this target
199 if self.persistent_target_id.as_deref() == Some(target_id)
200 && self.persistent_session.is_some()
201 {
202 return Ok(());
203 }
204
205 // Target is changing — discard events accumulated under the previous
206 // target so a later drain under the new page can't return stale events.
207 self.network_events.clear();
208 self.console_events.clear();
209
210 // Save the previously-active tab's emulation state so it can be restored
211 // when we return to it (per-tab isolation). The active state lives in the
212 // top-level fields; stash it under the old target id — but only if the
213 // tab actually has overrides, so the map doesn't accumulate empty entries
214 // for every tab ever visited.
215 if let Some(old_target) = self.persistent_target_id.clone() {
216 let saved = TabEmulation {
217 blocklist: std::mem::take(&mut self.blocklist),
218 viewport: self.viewport.take(),
219 geolocation: self.geolocation.take(),
220 };
221 stash_tab_emulation(&mut self.emulation_saved, old_target, saved);
222 }
223
224 // Detach old session if target changed
225 if let Some(old_session) = self.persistent_session.take() {
226 let _ = self
227 .send("Target.detachFromTarget", json!({"sessionId": old_session}))
228 .await;
229 self.persistent_target_id = None;
230 self.events
231 .retain(|event| event["sessionId"].as_str() != Some(old_session.as_str()));
232 }
233
234 // Attach new persistent session
235 let result = self
236 .send(
237 "Target.attachToTarget",
238 json!({"targetId": target_id, "flatten": true}),
239 )
240 .await?;
241
242 let session_id = result["sessionId"]
243 .as_str()
244 .ok_or_else(|| anyhow!("No sessionId in persistent attachToTarget"))?
245 .to_string();
246
247 // Store the session id BEFORE enabling domains so events arriving
248 // during Network.enable / Runtime.enable are routed to persistent
249 // buffers instead of the generic events buffer.
250 self.persistent_session = Some(session_id.clone());
251 self.persistent_target_id = Some(target_id.to_string());
252
253 // Enable Network and Runtime domains on the persistent session. If
254 // either fails, clear the just-set session, detach it (so it isn't

Callers 1

execute_commandFunction · 0.80

Calls 6

stash_tab_emulationFunction · 0.85
send_to_targetMethod · 0.80
sendMethod · 0.45

Tested by

no test coverage detected