mirror of
https://github.com/lexmount/moli.git
synced 2026-11-13 08:08:10 +00:00
refactor(inspector): derive response IDs and make parsing explicit
This commit is contained in:
+11
-12
@@ -126,18 +126,17 @@ pub use moli_renderer_v8::{
|
||||
RendererRuntimeInspectorIoCommandClaim, RendererRuntimeInspectorIoCommandRoute,
|
||||
RendererRuntimeInspectorMainCommandCompletion, RendererRuntimeInspectorMainCommandRoute,
|
||||
RendererRuntimeInspectorMessage, RendererRuntimeInspectorMessageBatch,
|
||||
RendererRuntimeInspectorProtocolMessage, RendererRuntimeInspectorProtocolMessageValueMut,
|
||||
RendererRuntimeObservableSourceItem, RendererRuntimeObservableSourceSummary,
|
||||
RendererRuntimeRealmInfo, RendererScreenshotClip, RendererScreenshotFormat,
|
||||
RendererScreenshotRegion, RendererScrollIntoViewResult, RendererServiceWorkerConsoleMessage,
|
||||
RendererServiceWorkerExceptionMessage, RendererServiceWorkerFetchDiagnostic,
|
||||
RendererServiceWorkerFetchDiagnosticResult, RendererServiceWorkerRunIdentity,
|
||||
RendererServiceWorkerTargetEvent, RendererServiceWorkerTargetInfo,
|
||||
RendererServiceWorkerVersionStatus, RendererSetDocumentContentResult,
|
||||
RendererSharedWorkerConsoleMessage, RendererSharedWorkerTargetEvent,
|
||||
RendererSharedWorkerTargetInfo, RendererSyntheticResponseBody, RendererTextSearchMatch,
|
||||
RendererTouchPoint, RendererVisualStateToken, RendererWindowDocumentSource,
|
||||
RuntimeConsoleMessageSnapshot, WorkerInspectorError,
|
||||
RendererRuntimeInspectorProtocolMessage, RendererRuntimeObservableSourceItem,
|
||||
RendererRuntimeObservableSourceSummary, RendererRuntimeRealmInfo, RendererScreenshotClip,
|
||||
RendererScreenshotFormat, RendererScreenshotRegion, RendererScrollIntoViewResult,
|
||||
RendererServiceWorkerConsoleMessage, RendererServiceWorkerExceptionMessage,
|
||||
RendererServiceWorkerFetchDiagnostic, RendererServiceWorkerFetchDiagnosticResult,
|
||||
RendererServiceWorkerRunIdentity, RendererServiceWorkerTargetEvent,
|
||||
RendererServiceWorkerTargetInfo, RendererServiceWorkerVersionStatus,
|
||||
RendererSetDocumentContentResult, RendererSharedWorkerConsoleMessage,
|
||||
RendererSharedWorkerTargetEvent, RendererSharedWorkerTargetInfo, RendererSyntheticResponseBody,
|
||||
RendererTextSearchMatch, RendererTouchPoint, RendererVisualStateToken,
|
||||
RendererWindowDocumentSource, RuntimeConsoleMessageSnapshot, WorkerInspectorError,
|
||||
};
|
||||
pub use moli_renderer_v8::{
|
||||
RendererAppManifest, RendererAppManifestDisplayMode, RendererAppManifestError,
|
||||
|
||||
@@ -5597,7 +5597,7 @@ fn runtime_protocol_response_by_id(
|
||||
) -> Option<&serde_json::Value> {
|
||||
messages.iter().find_map(|message| match message {
|
||||
RendererRuntimeInspectorMessage::Protocol(value)
|
||||
if value.get("id").and_then(serde_json::Value::as_i64) == Some(response_id) =>
|
||||
if value.payload().id_i64() == Some(response_id) =>
|
||||
{
|
||||
Some(value.value())
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ use serde_json::{Number, Value, value::RawValue};
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
fmt,
|
||||
ops::Deref,
|
||||
sync::{Arc, OnceLock},
|
||||
};
|
||||
|
||||
@@ -336,12 +335,6 @@ impl From<Value> for InspectorJson {
|
||||
Self::Parsed(value)
|
||||
}
|
||||
}
|
||||
impl Deref for InspectorJson {
|
||||
type Target = Value;
|
||||
fn deref(&self) -> &Value {
|
||||
self.value()
|
||||
}
|
||||
}
|
||||
impl Serialize for InspectorJson {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
match self {
|
||||
|
||||
@@ -40,6 +40,7 @@ impl CdpFrontendRoutingState {
|
||||
flattened_protocol,
|
||||
} => {
|
||||
if let Some(child_session_id) = message
|
||||
.value()
|
||||
.pointer("/result/sessionId")
|
||||
.and_then(Value::as_str)
|
||||
.map(str::to_owned)
|
||||
@@ -77,11 +78,11 @@ impl CdpFrontendRoutingState {
|
||||
let target_event_session_id = method
|
||||
.as_deref()
|
||||
.filter(|method| method.starts_with("Target."))
|
||||
.and_then(|_| message.pointer("/params/sessionId"))
|
||||
.and_then(|_| message.value().pointer("/params/sessionId"))
|
||||
.and_then(Value::as_str)
|
||||
.map(str::to_owned);
|
||||
let target_event_target_id = (method.as_deref() == Some("Target.attachedToTarget"))
|
||||
.then(|| message.pointer("/params/targetInfo/targetId"))
|
||||
.then(|| message.value().pointer("/params/targetInfo/targetId"))
|
||||
.flatten()
|
||||
.and_then(Value::as_str)
|
||||
.map(str::to_owned);
|
||||
|
||||
@@ -126,8 +126,8 @@ fn browser_and_page_client_command_ids_are_isolated_and_restored() {
|
||||
)
|
||||
.expect("route browser response");
|
||||
assert_eq!(browser_frontend.frontend_id, 5);
|
||||
assert_eq!(browser_response["id"], json!(7));
|
||||
assert!(browser_response.get("sessionId").is_none());
|
||||
assert_eq!(browser_response.id_u64(), Some(7));
|
||||
assert!(browser_response.session_id().is_none());
|
||||
|
||||
let (page_frontend, page_response) = routing
|
||||
.route_message(
|
||||
@@ -141,8 +141,8 @@ fn browser_and_page_client_command_ids_are_isolated_and_restored() {
|
||||
)
|
||||
.expect("route page response");
|
||||
assert_eq!(page_frontend.frontend_id, 10);
|
||||
assert_eq!(page_response["id"], json!(7));
|
||||
assert!(page_response.get("sessionId").is_none());
|
||||
assert_eq!(page_response.id_u64(), Some(7));
|
||||
assert!(page_response.session_id().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -187,9 +187,9 @@ fn browser_frontends_with_the_same_client_command_id_route_independently() {
|
||||
)
|
||||
.expect("route second response");
|
||||
assert_eq!(frontend.frontend_id(), 6);
|
||||
assert_eq!(response["id"], json!(7));
|
||||
assert_eq!(response["result"]["product"], json!("second"));
|
||||
assert!(response.get("sessionId").is_none());
|
||||
assert_eq!(response.id_u64(), Some(7));
|
||||
assert_eq!(response.value()["result"]["product"], json!("second"));
|
||||
assert!(response.session_id().is_none());
|
||||
|
||||
let (frontend, response) = routing
|
||||
.route_message(
|
||||
@@ -203,9 +203,9 @@ fn browser_frontends_with_the_same_client_command_id_route_independently() {
|
||||
)
|
||||
.expect("route first response");
|
||||
assert_eq!(frontend.frontend_id(), 5);
|
||||
assert_eq!(response["id"], json!(7));
|
||||
assert_eq!(response["result"]["product"], json!("first"));
|
||||
assert!(response.get("sessionId").is_none());
|
||||
assert_eq!(response.id_u64(), Some(7));
|
||||
assert_eq!(response.value()["result"]["product"], json!("first"));
|
||||
assert!(response.session_id().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -230,7 +230,7 @@ fn browser_base_session_events_are_private_and_frontend_scoped() {
|
||||
)
|
||||
.expect("route first browser event");
|
||||
assert_eq!(frontend.frontend_id(), 5);
|
||||
assert!(event.get("sessionId").is_none());
|
||||
assert!(event.session_id().is_none());
|
||||
|
||||
assert!(
|
||||
routing
|
||||
@@ -273,7 +273,7 @@ fn root_detach_with_a_known_child_routes_to_its_exact_frontend() {
|
||||
)
|
||||
.expect("route owner-qualified root detach");
|
||||
assert_eq!(frontend.frontend_id(), 5);
|
||||
assert!(event.get("sessionId").is_none());
|
||||
assert!(event.session_id().is_none());
|
||||
|
||||
assert!(matches!(
|
||||
routing.prepare_command(
|
||||
@@ -333,7 +333,7 @@ fn root_detach_restores_visible_parent_for_nested_child() {
|
||||
None,
|
||||
)
|
||||
.expect("route nested root detach");
|
||||
assert_eq!(event["sessionId"], json!("SID-child"));
|
||||
assert_eq!(event.session_id(), Some("SID-child"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -397,7 +397,7 @@ fn unregistering_one_browser_drops_only_its_pending_commands() {
|
||||
)
|
||||
.expect("second browser response remains routable");
|
||||
assert_eq!(frontend.frontend_id(), 6);
|
||||
assert_eq!(response["id"], json!(1));
|
||||
assert_eq!(response.id_u64(), Some(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -444,7 +444,7 @@ fn browser_child_session_is_preserved_on_browser_frontend() {
|
||||
None,
|
||||
)
|
||||
.expect("route child response");
|
||||
assert_eq!(response["sessionId"], json!("SID-client-child"));
|
||||
assert_eq!(response.session_id(), Some("SID-client-child"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -779,8 +779,8 @@ fn attached_event_registers_child_before_attach_response() {
|
||||
)
|
||||
.expect("route attached event");
|
||||
assert_eq!(frontend.frontend_id(), 5);
|
||||
assert!(event.get("sessionId").is_none());
|
||||
assert_eq!(event["params"]["sessionId"], json!("SID-child"));
|
||||
assert!(event.session_id().is_none());
|
||||
assert_eq!(event.value()["params"]["sessionId"], json!("SID-child"));
|
||||
|
||||
let child_command = expect_prepared_command(
|
||||
routing.prepare_command(
|
||||
@@ -813,8 +813,8 @@ fn attached_event_registers_child_before_attach_response() {
|
||||
None,
|
||||
)
|
||||
.expect("route attach response");
|
||||
assert_eq!(response["id"], json!(30));
|
||||
assert!(response.get("sessionId").is_none());
|
||||
assert_eq!(response.id_u64(), Some(30));
|
||||
assert!(response.session_id().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -847,8 +847,8 @@ fn browser_frontend_hides_base_session_on_wire() {
|
||||
None,
|
||||
)
|
||||
.expect("route browser response");
|
||||
assert_eq!(response["id"], json!(9));
|
||||
assert!(response.get("sessionId").is_none());
|
||||
assert_eq!(response.id_u64(), Some(9));
|
||||
assert!(response.session_id().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -975,7 +975,10 @@ fn private_page_session_detach_does_not_fall_back_to_browser_frontend() {
|
||||
)
|
||||
.expect("route browser-owned target detach");
|
||||
assert_eq!(frontend.frontend_id, 5);
|
||||
assert_eq!(message["params"]["sessionId"], json!("SID-browser-child"));
|
||||
assert_eq!(
|
||||
message.value()["params"]["sessionId"],
|
||||
json!("SID-browser-child")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -83,9 +83,9 @@ fn legacy_transport_admits_actual_command_and_routes_its_background_reply_once()
|
||||
.route_message(background.clone(), Some("SID-page-1"), None)
|
||||
.unwrap();
|
||||
assert_eq!(frontend.frontend_id(), 5);
|
||||
assert!(event.get("sessionId").is_none());
|
||||
assert!(event.session_id().is_none());
|
||||
assert_eq!(
|
||||
unwrap_message(&event, "SID-page-1"),
|
||||
unwrap_message(event.value(), "SID-page-1"),
|
||||
json!({"id":42,"result":{"loaderId":"LID-1"}})
|
||||
);
|
||||
assert!(
|
||||
@@ -132,7 +132,7 @@ fn recursive_transport_preserves_ack_paths_and_explicit_payload_session() {
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
let inner = unwrap_message(&response, "SID-page-1");
|
||||
let inner = unwrap_message(response.value(), "SID-page-1");
|
||||
assert!(inner.get("sessionId").is_none());
|
||||
assert_eq!(
|
||||
unwrap_message(&inner, "SID-worker"),
|
||||
@@ -163,9 +163,9 @@ fn transport_with_explicit_carrier_keeps_only_that_carrier_on_outer_event() {
|
||||
let (_, response) = routing
|
||||
.route_message(json!({"id":command.request().id(),"result":{}}), None, None)
|
||||
.unwrap();
|
||||
assert_eq!(response["sessionId"], "SID-page-1");
|
||||
assert_eq!(response.session_id(), Some("SID-page-1"));
|
||||
assert_eq!(
|
||||
unwrap_message(&response, "SID-worker"),
|
||||
unwrap_message(response.value(), "SID-worker"),
|
||||
json!({"id":42,"result":{}})
|
||||
);
|
||||
}
|
||||
@@ -247,7 +247,7 @@ fn nested_attach_keeps_normal_registration_and_disconnect_retires_pending_reply(
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
unwrap_message(&response, "SID-page-1"),
|
||||
unwrap_message(response.value(), "SID-page-1"),
|
||||
json!({"id":42,"result":{"sessionId":"SID-other"}})
|
||||
);
|
||||
let (_, command) = target_command(
|
||||
@@ -286,7 +286,7 @@ fn root_received_target_event_uses_owning_frontend_and_parent_carrier() {
|
||||
"method":"Target.receivedMessageFromTarget","params":{"sessionId":session,"message":"{}"},
|
||||
}),None, None).unwrap();
|
||||
assert_eq!(frontend.frontend_id(), 5);
|
||||
assert_eq!(response.get("sessionId").and_then(Value::as_str), parent);
|
||||
assert_eq!(response.session_id(), parent);
|
||||
}
|
||||
assert!(routing.route_message(json!({"method":"Target.receivedMessageFromTarget","params":{"sessionId":"SID-missing","message":"{}"}}),None, None).is_none());
|
||||
}
|
||||
@@ -306,7 +306,7 @@ fn nonflat_attachment_routes_events_before_and_after_reply_without_losing_parent
|
||||
Some(false),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(attached["sessionId"], "SID-page-1");
|
||||
assert_eq!(attached.session_id(), Some("SID-page-1"));
|
||||
let enable = expect_prepared_command(
|
||||
routing.prepare_command(
|
||||
5,
|
||||
@@ -335,18 +335,18 @@ fn nonflat_attachment_routes_events_before_and_after_reply_without_losing_parent
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(event["sessionId"], "SID-page-1");
|
||||
assert_eq!(event.session_id(), Some("SID-page-1"));
|
||||
assert_eq!(
|
||||
unwrap_message(&event, "SID-nonflat"),
|
||||
unwrap_message(event.value(), "SID-nonflat"),
|
||||
json!({"method":method,"params":params})
|
||||
);
|
||||
if method == "Runtime.executionContextCreated" {
|
||||
let (_, reply) = routing
|
||||
.route_message(json!({"id":enable.request().id(),"result":{}}), None, None)
|
||||
.unwrap();
|
||||
assert_eq!(reply["sessionId"], "SID-page-1");
|
||||
assert_eq!(reply.session_id(), Some("SID-page-1"));
|
||||
assert_eq!(
|
||||
unwrap_message(&reply, "SID-nonflat"),
|
||||
unwrap_message(reply.value(), "SID-nonflat"),
|
||||
json!({"id":80,"result":{}})
|
||||
);
|
||||
}
|
||||
@@ -382,8 +382,8 @@ fn nonflat_attachment_routes_events_before_and_after_reply_without_losing_parent
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(reply["sessionId"], "SID-page-1");
|
||||
assert_eq!(unwrap_message(&reply, "SID-nonflat")["id"], 81);
|
||||
assert_eq!(reply.session_id(), Some("SID-page-1"));
|
||||
assert_eq!(unwrap_message(reply.value(), "SID-nonflat")["id"], 81);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -401,8 +401,8 @@ fn mixed_flat_and_nonflat_ancestors_share_one_event_and_response_encoder() {
|
||||
let (_, event) = routing.route_message(json!({
|
||||
"method":"Runtime.executionContextCreated","sessionId":"SID-inner","params":{"context":{"id":3}},
|
||||
}), Some("SID-inner"), None).unwrap();
|
||||
assert!(event.get("sessionId").is_none());
|
||||
let middle = unwrap_message(&event, "SID-outer");
|
||||
assert!(event.session_id().is_none());
|
||||
let middle = unwrap_message(event.value(), "SID-outer");
|
||||
assert_eq!(middle["sessionId"], "SID-flat");
|
||||
let inner = unwrap_message(&middle, "SID-inner");
|
||||
assert!(inner.get("sessionId").is_none());
|
||||
@@ -415,7 +415,7 @@ fn mixed_flat_and_nonflat_ancestors_share_one_event_and_response_encoder() {
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
unwrap_message(&flat_event, "SID-outer")["sessionId"],
|
||||
unwrap_message(flat_event.value(), "SID-outer")["sessionId"],
|
||||
"SID-flat"
|
||||
);
|
||||
let (_, detached) = routing
|
||||
@@ -426,7 +426,7 @@ fn mixed_flat_and_nonflat_ancestors_share_one_event_and_response_encoder() {
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
unwrap_message(&detached, "SID-outer")["sessionId"],
|
||||
unwrap_message(detached.value(), "SID-outer")["sessionId"],
|
||||
"SID-flat"
|
||||
);
|
||||
assert!(routing.frontends.session("SID-inner").is_none());
|
||||
@@ -464,7 +464,7 @@ fn nested_target_commands_share_implicit_session_policy_with_the_adapter() {
|
||||
let (_, wrapped) = routing
|
||||
.route_message(json!({"id":command.request().id(),"result":{}}), None, None)
|
||||
.unwrap();
|
||||
let reply = unwrap_message(&wrapped, "SID-page-1");
|
||||
let reply = unwrap_message(wrapped.value(), "SID-page-1");
|
||||
assert_eq!(reply["id"], 42);
|
||||
assert_eq!(reply.get("sessionId").and_then(Value::as_str), explicit);
|
||||
}
|
||||
|
||||
@@ -236,12 +236,12 @@ impl RuntimeInspectorResponseReady {
|
||||
Ok(completion) => {
|
||||
let message =
|
||||
runtime_command_output_response_message(&completion.output, completion.call_id)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| Value::Null.into());
|
||||
.map(InspectorJson::value)
|
||||
.unwrap_or(&Value::Null);
|
||||
let payload = runtime_inspector_mismatched_completion_payload(
|
||||
command_id,
|
||||
completion.call_id,
|
||||
&message,
|
||||
message,
|
||||
);
|
||||
(
|
||||
completion.renderer_agent_attachment_id(),
|
||||
@@ -287,12 +287,12 @@ impl RuntimeInspectorResponseReady {
|
||||
Ok(completion) => {
|
||||
let message =
|
||||
runtime_command_output_response_message(&completion.output, completion.call_id)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| Value::Null.into());
|
||||
.map(InspectorJson::value)
|
||||
.unwrap_or(&Value::Null);
|
||||
runtime_inspector_mismatched_completion_payload(
|
||||
self.frontend_command_id.get(),
|
||||
completion.call_id,
|
||||
&message,
|
||||
message,
|
||||
)
|
||||
}
|
||||
Err(message) => BackgroundCommandResponsePayload::internal_error(message.to_string()),
|
||||
@@ -3077,10 +3077,10 @@ impl ProtocolDeliveryEnvelope {
|
||||
) -> bool {
|
||||
match &self.payload {
|
||||
BackgroundProtocolEventPayload::Protocol(event) => {
|
||||
event.message["method"] == json!("Console.messageAdded")
|
||||
&& event.message["params"]["message"]["source"] == json!(source)
|
||||
&& event.message["params"]["message"]["level"] == json!(level)
|
||||
&& event.message["params"]["message"]["text"] == json!(text)
|
||||
event.message.method() == Some("Console.messageAdded")
|
||||
&& event.message.value()["params"]["message"]["source"] == json!(source)
|
||||
&& event.message.value()["params"]["message"]["level"] == json!(level)
|
||||
&& event.message.value()["params"]["message"]["text"] == json!(text)
|
||||
}
|
||||
BackgroundProtocolEventPayload::ConsoleMessageAdded(event) => {
|
||||
event.source == source && event.level == level && event.text == text
|
||||
@@ -5960,10 +5960,10 @@ mod tests {
|
||||
}});
|
||||
assert!(InspectorJson::from_slice(host.to_string().as_bytes()).is_err());
|
||||
let wire = BackgroundProtocolEvent::immediate(host).into_cdp_message();
|
||||
assert_eq!(wire["params"]["requestId"], "public-id");
|
||||
assert_eq!(wire.value()["params"]["requestId"], "public-id");
|
||||
for key in PRIVATE_PROTOCOL_PARAM_FIELDS {
|
||||
assert_eq!(
|
||||
wire["params"].get(*key).is_some(),
|
||||
wire.value()["params"].get(*key).is_some(),
|
||||
method == "Fetch.requestPaused" && *key == "__moliBlockedInterceptors"
|
||||
);
|
||||
}
|
||||
@@ -5974,7 +5974,7 @@ mod tests {
|
||||
.unwrap();
|
||||
inspector.value_mut()["params"]["__moliFetchRequestId"] = json!("private-id");
|
||||
let wire = BackgroundProtocolEvent::immediate(inspector).into_cdp_message();
|
||||
assert!(wire["params"].get("__moliFetchRequestId").is_none());
|
||||
assert!(wire.value()["params"].get("__moliFetchRequestId").is_none());
|
||||
let inspector = InspectorJson::from_slice(
|
||||
br#"{"method":"Runtime.consoleAPICalled","params":{"args":[{"value":{"__moliFetchRequestId":"\ud800"}}]}}"#,
|
||||
)
|
||||
|
||||
@@ -199,7 +199,7 @@ fn runtime_inspector_frontend_response(
|
||||
let RendererRuntimeInspectorMessage::Protocol(message) = message else {
|
||||
return None;
|
||||
};
|
||||
(message.get("id").and_then(Value::as_u64) == Some(command_id)).then(|| message.value())
|
||||
(message.payload().id_u64() == Some(command_id)).then(|| message.value())
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -202,7 +202,10 @@ impl CdpConnection {
|
||||
);
|
||||
}
|
||||
if Some(id) == current_cmd_id {
|
||||
self.register_runtime_remote_object_ids_from_value_for_owner(owner, &message);
|
||||
self.register_runtime_remote_object_ids_from_value_for_owner(
|
||||
owner,
|
||||
message.value(),
|
||||
);
|
||||
if matches!(message, InspectorJson::Raw(_)) {
|
||||
message.set_session_id(current_session_id);
|
||||
response_events.push(BackgroundProtocolEvent::immediate(message));
|
||||
@@ -226,7 +229,7 @@ impl CdpConnection {
|
||||
}
|
||||
None => {
|
||||
if message.method() == Some("Page.windowOpen") {
|
||||
let params = message.get("params").unwrap_or(&Value::Null);
|
||||
let params = message.value().get("params").unwrap_or(&Value::Null);
|
||||
let Some(url) = params.get("url").and_then(Value::as_str) else {
|
||||
tracing::warn!("dropping Page.windowOpen without a string url");
|
||||
return false;
|
||||
@@ -282,7 +285,10 @@ impl CdpConnection {
|
||||
| "Runtime.executionContextsCleared"
|
||||
)
|
||||
) {
|
||||
self.register_runtime_remote_object_ids_from_value_for_owner(owner, &message);
|
||||
self.register_runtime_remote_object_ids_from_value_for_owner(
|
||||
owner,
|
||||
message.value(),
|
||||
);
|
||||
}
|
||||
if matches!(
|
||||
message.method(),
|
||||
@@ -712,13 +718,13 @@ impl CdpConnection {
|
||||
if let Some(object_group) = response.object_group() {
|
||||
self.register_runtime_remote_object_ids_from_value_for_owner_with_group(
|
||||
response.owner(),
|
||||
&response.message,
|
||||
response.message.value(),
|
||||
object_group,
|
||||
);
|
||||
} else {
|
||||
self.register_runtime_remote_object_ids_from_value_for_owner(
|
||||
response.owner(),
|
||||
&response.message,
|
||||
response.message.value(),
|
||||
);
|
||||
}
|
||||
let mut message = response.into_protocol_message();
|
||||
@@ -767,7 +773,7 @@ impl CdpConnection {
|
||||
return BidiChannelListenerRoute::Consumed;
|
||||
}
|
||||
let listener = residence.listener();
|
||||
let message = &response.message;
|
||||
let message = response.message.value();
|
||||
if let Some(error) = message.get("error") {
|
||||
tracing::debug!(
|
||||
?error,
|
||||
|
||||
@@ -354,6 +354,7 @@ mod tests {
|
||||
return None;
|
||||
};
|
||||
message
|
||||
.value()
|
||||
.get("params")
|
||||
.and_then(|params| params.get("marker"))
|
||||
.and_then(serde_json::Value::as_str)
|
||||
|
||||
@@ -13,8 +13,7 @@ pub(super) fn command_response_succeeded(
|
||||
let RendererRuntimeInspectorMessage::Protocol(message) = message else {
|
||||
return false;
|
||||
};
|
||||
message.get("id").and_then(Value::as_u64) == Some(command_id)
|
||||
&& message.get("result").is_some()
|
||||
message.payload().id_u64() == Some(command_id) && message.payload().has_field("result")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -31,9 +30,8 @@ pub(super) fn command_response_succeeded_for_events(
|
||||
{
|
||||
return matches!(payload, BackgroundCommandResponsePayloadRef::Success { .. });
|
||||
}
|
||||
event.protocol_message().is_some_and(|message| {
|
||||
message.get("id").and_then(Value::as_u64) == Some(command_id)
|
||||
&& message.get("result").is_some()
|
||||
event.protocol_json().is_some_and(|message| {
|
||||
message.id_u64() == Some(command_id) && message.has_field("result")
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1102,3 +1100,40 @@ pub(super) fn forget_pre_registered_runtime_await(
|
||||
conn.forget_pending_inspector_await_for_owner(command_id, owner);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod raw_response_tests {
|
||||
use super::*;
|
||||
use moli_inspector_json::InspectorJson;
|
||||
|
||||
#[test]
|
||||
fn command_success_checks_use_raw_metadata_without_parsing_the_body() {
|
||||
for (body, succeeded) in [
|
||||
(
|
||||
format!(r#""result":{{"value":"{}"}}"#, "x".repeat(1024 * 1024)),
|
||||
true,
|
||||
),
|
||||
(
|
||||
format!(r#""result":{}0{}"#, "[".repeat(150), "]".repeat(150)),
|
||||
true,
|
||||
),
|
||||
(
|
||||
r#""error":{"code":-32603,"message":"\ud800"}"#.to_owned(),
|
||||
false,
|
||||
),
|
||||
] {
|
||||
let source =
|
||||
InspectorJson::from_slice(format!(r#"{{"id":7,{body}}}"#).as_bytes()).unwrap();
|
||||
let messages = [RendererRuntimeInspectorMessage::protocol(source.clone())];
|
||||
assert_eq!(command_response_succeeded(&messages, Some(7)), succeeded);
|
||||
assert!(!command_response_succeeded(&messages, Some(8)));
|
||||
let events = [BackgroundProtocolEvent::immediate(source.clone())];
|
||||
assert_eq!(
|
||||
command_response_succeeded_for_events(&events, Some(7)),
|
||||
succeeded
|
||||
);
|
||||
assert!(!command_response_succeeded_for_events(&events, Some(8)));
|
||||
assert!(!source.is_materialized());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,11 @@ fn try_start_binding(conn: &mut CdpConnection, cmd: &Cmd<'_>) -> Option<NativeCo
|
||||
move |reply| match reply {
|
||||
Ok(RendererPageReply::RuntimeInspectorProtocolMessages(output)) => {
|
||||
if let Some(error) = output.messages().iter().find_map(|message| match message {
|
||||
RendererRuntimeInspectorMessage::Protocol(message) => message.get("error"),
|
||||
RendererRuntimeInspectorMessage::Protocol(message)
|
||||
if message.payload().has_field("error") =>
|
||||
{
|
||||
message.value().get("error")
|
||||
}
|
||||
_ => None,
|
||||
}) {
|
||||
return RendererNativeProtocolResponse::error(
|
||||
|
||||
+16
-16
@@ -324,22 +324,22 @@ pub use runtime::{
|
||||
RendererRuntimeInspectorIoCommandRoute, RendererRuntimeInspectorMainCommandCompletion,
|
||||
RendererRuntimeInspectorMainCommandRoute, RendererRuntimeInspectorMessage,
|
||||
RendererRuntimeInspectorMessageBatch, RendererRuntimeInspectorProtocolMessage,
|
||||
RendererRuntimeInspectorProtocolMessageValueMut, RendererRuntimeInspectorResponseChannel,
|
||||
RendererRuntimeInspectorResponseSender, RendererRuntimeObservableSourceItem,
|
||||
RendererRuntimeObservableSourceSummary, RendererRuntimeRealmInfo, RendererRuntimeRemoteObject,
|
||||
RendererRuntimeRemoteObjectResolution, RendererScreenshotClip, RendererScreenshotFormat,
|
||||
RendererScreenshotRegion, RendererScriptExecutionMemoryDiagnostics,
|
||||
RendererScriptSourceMemoryDiagnostics, RendererScrollIntoViewResult,
|
||||
RendererServiceWorkerConsoleMessage, RendererServiceWorkerExceptionMessage,
|
||||
RendererServiceWorkerFetchDiagnostic, RendererServiceWorkerFetchDiagnosticResult,
|
||||
RendererServiceWorkerMainResourceFetch, RendererServiceWorkerRunIdentity,
|
||||
RendererServiceWorkerTargetEvent, RendererServiceWorkerTargetInfo,
|
||||
RendererServiceWorkerVersionStatus, RendererSetDocumentContentResult,
|
||||
RendererSharedWorkerConsoleMessage, RendererSharedWorkerTargetEvent,
|
||||
RendererSharedWorkerTargetInfo, RendererStyleSheetHeader, RendererStyleSheetInventoryUpdate,
|
||||
RendererStyleSheetPayload, RendererSyntheticResponseBody, RendererTextSearchMatch,
|
||||
RendererTouchPoint, RendererVisualStateToken, RendererWindowDocumentSource,
|
||||
RuntimeConsoleMessageSnapshot, WorkerInspectorError, renderer_output_transport_channel,
|
||||
RendererRuntimeInspectorResponseChannel, RendererRuntimeInspectorResponseSender,
|
||||
RendererRuntimeObservableSourceItem, RendererRuntimeObservableSourceSummary,
|
||||
RendererRuntimeRealmInfo, RendererRuntimeRemoteObject, RendererRuntimeRemoteObjectResolution,
|
||||
RendererScreenshotClip, RendererScreenshotFormat, RendererScreenshotRegion,
|
||||
RendererScriptExecutionMemoryDiagnostics, RendererScriptSourceMemoryDiagnostics,
|
||||
RendererScrollIntoViewResult, RendererServiceWorkerConsoleMessage,
|
||||
RendererServiceWorkerExceptionMessage, RendererServiceWorkerFetchDiagnostic,
|
||||
RendererServiceWorkerFetchDiagnosticResult, RendererServiceWorkerMainResourceFetch,
|
||||
RendererServiceWorkerRunIdentity, RendererServiceWorkerTargetEvent,
|
||||
RendererServiceWorkerTargetInfo, RendererServiceWorkerVersionStatus,
|
||||
RendererSetDocumentContentResult, RendererSharedWorkerConsoleMessage,
|
||||
RendererSharedWorkerTargetEvent, RendererSharedWorkerTargetInfo, RendererStyleSheetHeader,
|
||||
RendererStyleSheetInventoryUpdate, RendererStyleSheetPayload, RendererSyntheticResponseBody,
|
||||
RendererTextSearchMatch, RendererTouchPoint, RendererVisualStateToken,
|
||||
RendererWindowDocumentSource, RuntimeConsoleMessageSnapshot, WorkerInspectorError,
|
||||
renderer_output_transport_channel,
|
||||
};
|
||||
pub use runtime::{
|
||||
RendererElementClickError, RendererElementClickTarget, RendererPreparedPointerClick,
|
||||
|
||||
@@ -386,20 +386,19 @@ pub use self::page_surface::{
|
||||
RendererRuntimeCommandOutput, RendererRuntimeEvaluationResult, RendererRuntimeHeapSpaceUsage,
|
||||
RendererRuntimeHeapUsage, RendererRuntimeInspectorAsyncCompletion,
|
||||
RendererRuntimeInspectorMessage, RendererRuntimeInspectorMessageBatch,
|
||||
RendererRuntimeInspectorProtocolMessage, RendererRuntimeInspectorProtocolMessageValueMut,
|
||||
RendererRuntimeInspectorResponseChannel, RendererRuntimeInspectorResponseSender,
|
||||
RendererRuntimeObservableSourceItem, RendererRuntimeObservableSourceSummary,
|
||||
RendererRuntimeRealmInfo, RendererRuntimeRemoteObject, RendererRuntimeRemoteObjectResolution,
|
||||
RendererScriptExecutionMemoryDiagnostics, RendererScriptSourceMemoryDiagnostics,
|
||||
RendererScrollIntoViewResult, RendererServiceWorkerConsoleMessage,
|
||||
RendererServiceWorkerExceptionMessage, RendererServiceWorkerFetchDiagnostic,
|
||||
RendererServiceWorkerFetchDiagnosticResult, RendererServiceWorkerTargetEvent,
|
||||
RendererServiceWorkerTargetInfo, RendererServiceWorkerVersionStatus,
|
||||
RendererSetDocumentContentResult, RendererSharedWorkerConsoleMessage,
|
||||
RendererSharedWorkerTargetEvent, RendererSharedWorkerTargetInfo, RendererStyleSheetHeader,
|
||||
RendererStyleSheetInventoryUpdate, RendererStyleSheetPayload, RendererSyntheticResponseBody,
|
||||
RendererTextSearchMatch, RendererTouchPoint, RendererWindowDocumentSource,
|
||||
RuntimeConsoleMessageSnapshot,
|
||||
RendererRuntimeInspectorProtocolMessage, RendererRuntimeInspectorResponseChannel,
|
||||
RendererRuntimeInspectorResponseSender, RendererRuntimeObservableSourceItem,
|
||||
RendererRuntimeObservableSourceSummary, RendererRuntimeRealmInfo, RendererRuntimeRemoteObject,
|
||||
RendererRuntimeRemoteObjectResolution, RendererScriptExecutionMemoryDiagnostics,
|
||||
RendererScriptSourceMemoryDiagnostics, RendererScrollIntoViewResult,
|
||||
RendererServiceWorkerConsoleMessage, RendererServiceWorkerExceptionMessage,
|
||||
RendererServiceWorkerFetchDiagnostic, RendererServiceWorkerFetchDiagnosticResult,
|
||||
RendererServiceWorkerTargetEvent, RendererServiceWorkerTargetInfo,
|
||||
RendererServiceWorkerVersionStatus, RendererSetDocumentContentResult,
|
||||
RendererSharedWorkerConsoleMessage, RendererSharedWorkerTargetEvent,
|
||||
RendererSharedWorkerTargetInfo, RendererStyleSheetHeader, RendererStyleSheetInventoryUpdate,
|
||||
RendererStyleSheetPayload, RendererSyntheticResponseBody, RendererTextSearchMatch,
|
||||
RendererTouchPoint, RendererWindowDocumentSource, RuntimeConsoleMessageSnapshot,
|
||||
};
|
||||
pub(crate) use self::page_surface::{
|
||||
RendererCommandTurnOutputRecorder, RendererDevToolsSessionOutputHost,
|
||||
|
||||
@@ -103,7 +103,7 @@ fn renderer_inspector_response_succeeded(
|
||||
let RendererRuntimeInspectorMessage::Protocol(message) = message else {
|
||||
return false;
|
||||
};
|
||||
message.get("id").and_then(Value::as_u64) == Some(call_id) && message.get("error").is_none()
|
||||
message.payload().id_u64() == Some(call_id) && !message.payload().has_field("error")
|
||||
})
|
||||
}
|
||||
const DOM_STABLE_COMPLETE_BASE_WINDOW: std::time::Duration = std::time::Duration::from_millis(350);
|
||||
@@ -119,7 +119,7 @@ fn runtime_inspector_response_message(
|
||||
let RendererRuntimeInspectorMessage::Protocol(message) = message else {
|
||||
return None;
|
||||
};
|
||||
(message.get("id").and_then(Value::as_u64) == Some(response_id)).then_some(message.value())
|
||||
(message.payload().id_u64() == Some(response_id)).then(|| message.value())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1854,7 +1854,7 @@ impl PageVm {
|
||||
.filter(|message| {
|
||||
message.has_v8_inspector_method()
|
||||
|| matches!(message, RendererRuntimeInspectorMessage::Protocol(message)
|
||||
if message.get("error").is_some())
|
||||
if message.payload().has_field("error"))
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
@@ -1873,7 +1873,7 @@ impl PageVm {
|
||||
let output = output.map_err(anyhow::Error::msg)?;
|
||||
if !output.messages().iter().any(|message| {
|
||||
matches!(message, RendererRuntimeInspectorMessage::Protocol(message)
|
||||
if message.get("error").is_some())
|
||||
if message.payload().has_field("error"))
|
||||
}) {
|
||||
let session_key = DevToolsSessionKey::from_wire_session_id(inspector_session_id);
|
||||
let mut session_bindings = self
|
||||
|
||||
@@ -911,12 +911,7 @@ pub enum RendererRuntimeInspectorMessage {
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct RendererRuntimeInspectorProtocolMessage {
|
||||
renderer_call_id: Option<moli_page_types::RendererCallId>,
|
||||
value: InspectorJson,
|
||||
}
|
||||
|
||||
pub struct RendererRuntimeInspectorProtocolMessageValueMut<'a> {
|
||||
message: &'a mut RendererRuntimeInspectorProtocolMessage,
|
||||
payload: InspectorJson,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq)]
|
||||
@@ -1026,16 +1021,8 @@ impl RendererRuntimeCommandOutput {
|
||||
}
|
||||
|
||||
pub fn protocol_response(&self, call_id: i32) -> Option<&Value> {
|
||||
self.messages.iter().find_map(|message| match message {
|
||||
RendererRuntimeInspectorMessage::Protocol(message)
|
||||
if message
|
||||
.renderer_call_id()
|
||||
.is_some_and(|id| id.get() == call_id) =>
|
||||
{
|
||||
Some(message.value())
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
self.protocol_response_payload(call_id)
|
||||
.map(InspectorJson::value)
|
||||
}
|
||||
|
||||
pub fn into_protocol_response(self, call_id: i32) -> Option<Value> {
|
||||
@@ -1153,70 +1140,38 @@ impl RendererRuntimeInspectorMessage {
|
||||
}
|
||||
|
||||
impl RendererRuntimeInspectorProtocolMessage {
|
||||
pub fn new(value: impl Into<InspectorJson>) -> Self {
|
||||
let value = value.into();
|
||||
let renderer_call_id = renderer_call_id_from_protocol_message(&value);
|
||||
pub fn new(payload: impl Into<InspectorJson>) -> Self {
|
||||
Self {
|
||||
renderer_call_id,
|
||||
value,
|
||||
payload: payload.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn renderer_call_id(&self) -> Option<moli_page_types::RendererCallId> {
|
||||
self.renderer_call_id
|
||||
renderer_call_id_from_protocol_message(&self.payload)
|
||||
}
|
||||
|
||||
pub fn value(&self) -> &Value {
|
||||
self.value.value()
|
||||
self.payload.value()
|
||||
}
|
||||
|
||||
pub fn payload(&self) -> &InspectorJson {
|
||||
&self.value
|
||||
&self.payload
|
||||
}
|
||||
|
||||
pub fn into_payload(self) -> InspectorJson {
|
||||
self.value
|
||||
self.payload
|
||||
}
|
||||
|
||||
pub fn set_frontend_id(&mut self, id: u64) {
|
||||
self.value.set_id(id);
|
||||
self.renderer_call_id = renderer_call_id_from_protocol_message(&self.value);
|
||||
self.payload.set_id(id);
|
||||
}
|
||||
|
||||
pub fn value_mut(&mut self) -> RendererRuntimeInspectorProtocolMessageValueMut<'_> {
|
||||
RendererRuntimeInspectorProtocolMessageValueMut { message: self }
|
||||
pub fn value_mut(&mut self) -> &mut Value {
|
||||
self.payload.value_mut()
|
||||
}
|
||||
|
||||
pub fn into_value(self) -> Value {
|
||||
self.value.into_value()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for RendererRuntimeInspectorProtocolMessageValueMut<'_> {
|
||||
type Target = Value;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.message.value.value()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::DerefMut for RendererRuntimeInspectorProtocolMessageValueMut<'_> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.message.value.value_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for RendererRuntimeInspectorProtocolMessageValueMut<'_> {
|
||||
fn drop(&mut self) {
|
||||
self.message.renderer_call_id = renderer_call_id_from_protocol_message(&self.message.value);
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for RendererRuntimeInspectorProtocolMessage {
|
||||
type Target = Value;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.value()
|
||||
self.payload.into_value()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1002,7 +1002,8 @@ async fn runtime_enable_events_include_renderer_root_frame_id_for_default_contex
|
||||
let default_contexts = events
|
||||
.iter()
|
||||
.filter(|message| {
|
||||
message.get("method") == Some(&serde_json::json!("Runtime.executionContextCreated"))
|
||||
message.get("method").and_then(serde_json::Value::as_str)
|
||||
== Some("Runtime.executionContextCreated")
|
||||
&& message["params"]["context"]["auxData"]["isDefault"] == serde_json::json!(true)
|
||||
&& message["params"]["context"]["auxData"]["type"] == serde_json::json!("default")
|
||||
})
|
||||
@@ -1230,7 +1231,7 @@ async fn inspector_output_flushes_v8_state_for_commands_and_notifications() {
|
||||
) if batch.messages.iter().any(|message| matches!(
|
||||
message,
|
||||
RendererRuntimeInspectorMessage::Protocol(message)
|
||||
if message.get("id").and_then(serde_json::Value::as_i64) == Some(701)
|
||||
if message.payload().id_i64() == Some(701)
|
||||
))
|
||||
)
|
||||
})
|
||||
@@ -1255,8 +1256,7 @@ async fn inspector_output_flushes_v8_state_for_commands_and_notifications() {
|
||||
&& batch.messages.iter().any(|message| matches!(
|
||||
message,
|
||||
RendererRuntimeInspectorMessage::Protocol(message)
|
||||
if message.get("method")
|
||||
== Some(&serde_json::json!("Runtime.consoleAPICalled"))
|
||||
if message.payload().method() == Some("Runtime.consoleAPICalled")
|
||||
))
|
||||
))
|
||||
}),
|
||||
@@ -1315,8 +1315,7 @@ async fn owner_command_fences_exact_cursor_when_later_output_is_already_publishe
|
||||
if batch.messages.iter().any(|message| matches!(
|
||||
message,
|
||||
RendererRuntimeInspectorMessage::Protocol(message)
|
||||
if message.get("method")
|
||||
== Some(&serde_json::json!("Runtime.consoleAPICalled"))
|
||||
if message.payload().method() == Some("Runtime.consoleAPICalled")
|
||||
))
|
||||
)),
|
||||
"the early publication must own the Runtime notification emitted by the owner command"
|
||||
@@ -1419,8 +1418,7 @@ async fn page_diagnostics_snapshot_is_read_only_for_current_inspector_output() {
|
||||
if batch.messages.iter().any(|message| matches!(
|
||||
message,
|
||||
RendererRuntimeInspectorMessage::Protocol(message)
|
||||
if message.get("method")
|
||||
== Some(&serde_json::json!("Runtime.consoleAPICalled"))
|
||||
if message.payload().method() == Some("Runtime.consoleAPICalled")
|
||||
))
|
||||
))
|
||||
}),
|
||||
@@ -4171,9 +4169,9 @@ async fn pending_expression_publishes_console_output_before_settlement() {
|
||||
let RendererRuntimeInspectorMessage::Protocol(message) = message else {
|
||||
continue;
|
||||
};
|
||||
if message.get("method").and_then(serde_json::Value::as_str)
|
||||
if message.payload().method()
|
||||
== Some("Runtime.consoleAPICalled")
|
||||
&& let Some(value) = message["params"]["args"][0]["value"].as_str()
|
||||
&& let Some(value) = message.value()["params"]["args"][0]["value"].as_str()
|
||||
{
|
||||
observed.push(value.to_owned());
|
||||
}
|
||||
@@ -4277,8 +4275,8 @@ async fn navigation_follow_publishes_command_output_before_replacing_document()
|
||||
if batch.messages.iter().any(|message| matches!(
|
||||
message,
|
||||
RendererRuntimeInspectorMessage::Protocol(message)
|
||||
if message["method"] == "Runtime.consoleAPICalled"
|
||||
&& message["params"]["args"][0]["value"] == "command-output-before-navigation"
|
||||
if message.payload().method() == Some("Runtime.consoleAPICalled")
|
||||
&& message.value()["params"]["args"][0]["value"] == "command-output-before-navigation"
|
||||
))
|
||||
))
|
||||
})
|
||||
|
||||
@@ -798,7 +798,7 @@ mod tests {
|
||||
let restored_context = restored_messages
|
||||
.iter()
|
||||
.find(|message| {
|
||||
message.get("method").and_then(Value::as_str)
|
||||
message.method()
|
||||
== Some("Runtime.executionContextCreated")
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
@@ -807,7 +807,8 @@ mod tests {
|
||||
)
|
||||
});
|
||||
assert_eq!(
|
||||
restored_context["params"]["context"]["origin"], "https://example.test",
|
||||
restored_context.value()["params"]["context"]["origin"],
|
||||
"https://example.test",
|
||||
"V8ContextInfo must carry the embedder-bound origin without outbound JSON rewriting"
|
||||
);
|
||||
let formatter_probe = serde_json::json!({
|
||||
@@ -934,19 +935,13 @@ mod tests {
|
||||
let messages = restored.outbound.values_after(0);
|
||||
let cleared_index = messages
|
||||
.iter()
|
||||
.position(|message| {
|
||||
message.get("method").and_then(Value::as_str)
|
||||
== Some("Runtime.executionContextsCleared")
|
||||
})
|
||||
.position(|message| message.method() == Some("Runtime.executionContextsCleared"))
|
||||
.unwrap_or_else(|| {
|
||||
panic!("restored Runtime session should clear old contexts: {messages:?}")
|
||||
});
|
||||
let created_index = messages
|
||||
.iter()
|
||||
.position(|message| {
|
||||
message.get("method").and_then(Value::as_str)
|
||||
== Some("Runtime.executionContextCreated")
|
||||
})
|
||||
.position(|message| message.method() == Some("Runtime.executionContextCreated"))
|
||||
.unwrap_or_else(|| {
|
||||
panic!("restored Runtime session should report the new context: {messages:?}")
|
||||
});
|
||||
|
||||
@@ -52,7 +52,7 @@ fn inspector_protocol_message_has_typed_and_consistent_response_id() {
|
||||
Some(moli_page_types::RendererCallId::new(0))
|
||||
);
|
||||
{
|
||||
let mut value = response.value_mut();
|
||||
let value = response.value_mut();
|
||||
value["id"] = json!(-7);
|
||||
}
|
||||
assert_eq!(
|
||||
@@ -249,7 +249,7 @@ fn runtime_command_output_only_parks_its_own_response_callback() {
|
||||
assert!(matches!(
|
||||
¤t.messages()[0],
|
||||
crate::runtime::RendererRuntimeInspectorMessage::Protocol(message)
|
||||
if message["method"] == json!("Runtime.consoleAPICalled")
|
||||
if message.payload().method() == Some("Runtime.consoleAPICalled")
|
||||
));
|
||||
assert_eq!(
|
||||
current.protocol_response(8),
|
||||
@@ -549,3 +549,25 @@ fn inspector_outbound_raw_utf16_and_response_id_validation_keep_call_authority()
|
||||
assert_eq!(outbound.response_callback_counts(), (0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inspector_response_id_reads_opaque_metadata_and_tracks_explicit_mutation() {
|
||||
let body = format!("{}0{}", "[".repeat(150), "]".repeat(150));
|
||||
let source =
|
||||
InspectorJson::from_slice(format!(r#"{{"id":7,"result":{body}}}"#).as_bytes()).unwrap();
|
||||
let mut message = crate::runtime::RendererRuntimeInspectorProtocolMessage::new(source.clone());
|
||||
assert_eq!(message.renderer_call_id().map(|id| id.get()), Some(7));
|
||||
message.set_frontend_id(u64::MAX);
|
||||
assert_eq!(message.renderer_call_id(), None);
|
||||
assert_eq!(message.payload().id_u64(), Some(u64::MAX));
|
||||
message.set_frontend_id(9);
|
||||
assert_eq!(message.renderer_call_id().map(|id| id.get()), Some(9));
|
||||
assert!(!source.is_materialized());
|
||||
assert!(!message.payload().is_materialized());
|
||||
message.value_mut()["id"] = json!(-7);
|
||||
assert_eq!(message.renderer_call_id().map(|id| id.get()), Some(-7));
|
||||
message.value_mut().as_object_mut().unwrap().remove("id");
|
||||
assert_eq!(message.renderer_call_id(), None);
|
||||
message.value_mut()["id"] = json!(i64::MAX);
|
||||
assert_eq!(message.renderer_call_id(), None);
|
||||
}
|
||||
|
||||
@@ -479,7 +479,7 @@ impl ServiceWorkerRuntimeService {
|
||||
.into_iter()
|
||||
.partition(|message| match message {
|
||||
RendererRuntimeInspectorMessage::Protocol(message) => {
|
||||
message.get("id").is_some()
|
||||
message.payload().has_field("id")
|
||||
}
|
||||
RendererRuntimeInspectorMessage::RuntimeContext(_) => false,
|
||||
});
|
||||
|
||||
@@ -119,7 +119,7 @@ impl RendererSharedWorkerHost {
|
||||
.into_iter()
|
||||
.partition(|message| match message {
|
||||
RendererRuntimeInspectorMessage::Protocol(message) => {
|
||||
message.get("id").is_some()
|
||||
message.payload().has_field("id")
|
||||
}
|
||||
RendererRuntimeInspectorMessage::RuntimeContext(_) => false,
|
||||
});
|
||||
|
||||
@@ -942,7 +942,7 @@ mod tests {
|
||||
.iter()
|
||||
.find_map(|message| match message {
|
||||
RendererRuntimeInspectorMessage::Protocol(message)
|
||||
if message.value().get("id").and_then(Value::as_i64) == Some(call_id) =>
|
||||
if message.payload().id_i64() == Some(call_id) =>
|
||||
{
|
||||
Some(message.value().clone())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user