Collect CDP events for a given duration (milliseconds). Drains any already-buffered events first, then reads from the WebSocket until the timeout expires. Events are also routed through persistent session buffers when active to avoid duplicates.
(&mut self, duration_ms: u64)
| 761 | /// until the timeout expires. Events are also routed through persistent |
| 762 | /// session buffers when active to avoid duplicates. |
| 763 | pub async fn read_events_for(&mut self, duration_ms: u64) -> Result<Vec<Value>> { |
| 764 | let mut events: Vec<Value> = self.events.drain(..).collect(); |
| 765 | let deadline = tokio::time::Instant::now() + std::time::Duration::from_millis(duration_ms); |
| 766 | |
| 767 | loop { |
| 768 | let remaining = deadline.saturating_duration_since(tokio::time::Instant::now()); |
| 769 | if remaining.is_zero() { |
| 770 | break; |
| 771 | } |
| 772 | match tokio::time::timeout(remaining, self.read_text()).await { |
| 773 | Ok(Ok(text)) => { |
| 774 | if let Ok(resp) = serde_json::from_str::<Value>(&text) { |
| 775 | if let Some(method) = resp.get("method").and_then(|v| v.as_str()) { |
| 776 | // Events are routed to persistent session buffers (network_events, |
| 777 | // console_events) AND returned in the `events` vector here. |
| 778 | // |
| 779 | // In direct mode (no persistent session), we avoid pushing |
| 780 | // Network/Runtime events to the generic `self.events` buffer. |
| 781 | // This prevents them from being stashed and then returned |
| 782 | // again in a subsequent drain (double-processing). |
| 783 | let is_persistent_event = self |
| 784 | .persistent_session |
| 785 | .as_deref() |
| 786 | .is_some_and(|s| resp["sessionId"].as_str() == Some(s)); |
| 787 | if is_persistent_event { |
| 788 | self.push_event(resp.clone()); |
| 789 | } else if !method.starts_with("Network.") |
| 790 | && !method.starts_with("Runtime.") |
| 791 | { |
| 792 | self.push_event(resp.clone()); |
| 793 | } |
| 794 | events.push(resp); |
| 795 | } |
| 796 | } |
| 797 | } |
| 798 | // Timeout expired — normal completion path. |
| 799 | Err(_) => break, |
| 800 | // read_text() itself failed (socket closed, decode error, |
| 801 | // etc.) — real transport error. Log it so the user has a |
| 802 | // signal when the partial result is suspicious, then stop. |
| 803 | Ok(Err(e)) => { |
| 804 | eprintln!("Warning: WebSocket read failed during event collection: {e}"); |
| 805 | break; |
| 806 | } |
| 807 | } |
| 808 | } |
| 809 | |
| 810 | Ok(events) |
| 811 | } |
| 812 | |
| 813 | /// Get the current page URL via JavaScript evaluation. |
| 814 | pub async fn current_url(&mut self, session_id: &str) -> Result<String> { |
no test coverage detected