playwright_rs/protocol/
local_utils.rs1use crate::error::Result;
5use crate::server::channel::Channel;
6use crate::server::channel_owner::{
7 ChannelOwner, ChannelOwnerImpl, DisposeReason, ParentOrConnection,
8};
9use crate::server::connection::ConnectionLike;
10use base64::Engine;
11use serde::Deserialize;
12use serde_json::Value;
13use std::any::Any;
14use std::sync::Arc;
15
16#[derive(Clone)]
20pub struct LocalUtils {
21 base: ChannelOwnerImpl,
22}
23
24impl LocalUtils {
25 pub fn new(
26 parent: ParentOrConnection,
27 type_name: String,
28 guid: Arc<str>,
29 initializer: Value,
30 ) -> Result<Self> {
31 Ok(Self {
32 base: ChannelOwnerImpl::new(parent, type_name, guid, initializer),
33 })
34 }
35
36 pub async fn har_open(&self, file: &str) -> Result<String> {
40 #[derive(Deserialize)]
41 struct HarOpenResult {
42 #[serde(rename = "harId")]
43 har_id: String,
44 }
45 let result: HarOpenResult = self
46 .channel()
47 .send("harOpen", serde_json::json!({ "file": file }))
48 .await?;
49 Ok(result.har_id)
50 }
51
52 pub async fn har_lookup(
57 &self,
58 har_id: &str,
59 url: &str,
60 method: &str,
61 headers: Vec<serde_json::Value>,
62 post_data: Option<&[u8]>,
63 is_navigation_request: bool,
64 ) -> Result<HarLookupResult> {
65 let mut params = serde_json::json!({
66 "harId": har_id,
67 "url": url,
68 "method": method,
69 "headers": headers,
70 "isNavigationRequest": is_navigation_request,
71 });
72
73 if let Some(data) = post_data {
75 let encoded = base64::engine::general_purpose::STANDARD.encode(data);
76 params["postData"] = serde_json::Value::String(encoded);
77 }
78
79 self.channel().send("harLookup", params).await
80 }
81
82 pub async fn har_close(&self, har_id: &str) -> Result<()> {
84 self.channel()
85 .send_no_result("harClose", serde_json::json!({ "harId": har_id }))
86 .await
87 }
88}
89
90#[derive(Debug, Deserialize)]
94pub struct HarLookupResult {
95 pub action: String,
97
98 #[serde(rename = "redirectURL")]
100 pub redirect_url: Option<String>,
101
102 pub status: Option<u16>,
104
105 pub headers: Option<Vec<serde_json::Value>>,
107
108 pub body: Option<String>,
110}
111
112impl ChannelOwner for LocalUtils {
113 fn guid(&self) -> &str {
114 self.base.guid()
115 }
116
117 fn type_name(&self) -> &str {
118 self.base.type_name()
119 }
120
121 fn parent(&self) -> Option<Arc<dyn ChannelOwner>> {
122 self.base.parent()
123 }
124
125 fn connection(&self) -> Arc<dyn ConnectionLike> {
126 self.base.connection()
127 }
128
129 fn initializer(&self) -> &Value {
130 self.base.initializer()
131 }
132
133 fn channel(&self) -> &Channel {
134 self.base.channel()
135 }
136
137 fn dispose(&self, reason: DisposeReason) {
138 self.base.dispose(reason)
139 }
140
141 fn adopt(&self, child: Arc<dyn ChannelOwner>) {
142 self.base.adopt(child)
143 }
144
145 fn add_child(&self, guid: Arc<str>, child: Arc<dyn ChannelOwner>) {
146 self.base.add_child(guid, child)
147 }
148
149 fn remove_child(&self, guid: &str) {
150 self.base.remove_child(guid)
151 }
152
153 fn on_event(&self, method: &str, params: Value) {
154 self.base.on_event(method, params)
155 }
156
157 fn was_collected(&self) -> bool {
158 self.base.was_collected()
159 }
160
161 fn as_any(&self) -> &dyn Any {
162 self
163 }
164}
165
166impl std::fmt::Debug for LocalUtils {
167 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
168 f.debug_struct("LocalUtils")
169 .field("guid", &self.guid())
170 .finish()
171 }
172}