chore: seed sgclaw rust baseline
This commit is contained in:
89
tests/integration/handshake_flow_test.rs
Normal file
89
tests/integration/handshake_flow_test.rs
Normal file
@@ -0,0 +1,89 @@
|
||||
use std::io::{Cursor, Result as IoResult, Write};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
|
||||
use sgclaw::pipe::{
|
||||
perform_handshake, Action, AgentMessage, BrowserPipeTool, StdioTransport, Timing,
|
||||
};
|
||||
use sgclaw::security::MacPolicy;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
struct SharedBuffer {
|
||||
inner: Arc<Mutex<Vec<u8>>>,
|
||||
}
|
||||
|
||||
impl SharedBuffer {
|
||||
fn snapshot(&self) -> String {
|
||||
String::from_utf8(self.inner.lock().unwrap().clone()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for SharedBuffer {
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
|
||||
self.inner.lock().unwrap().extend_from_slice(buf);
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> IoResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn handshake_and_command_flow_work_over_json_line_transport() {
|
||||
let reader = Cursor::new(
|
||||
concat!(
|
||||
r#"{"type":"init","version":"1.0","hmac_seed":"0123456789abcdef","capabilities":["browser_action"]}"#,
|
||||
"\n",
|
||||
r#"{"type":"response","seq":1,"success":true,"data":{"text":"提交成功"},"aom_snapshot":[],"timing":{"queue_ms":2,"exec_ms":38}}"#,
|
||||
"\n"
|
||||
)
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
);
|
||||
let writer = SharedBuffer::default();
|
||||
let captured = writer.clone();
|
||||
let transport = Arc::new(StdioTransport::new(reader, writer));
|
||||
|
||||
let handshake = perform_handshake(transport.as_ref(), Duration::from_secs(1)).unwrap();
|
||||
let policy = MacPolicy::from_json_str(
|
||||
r#"{
|
||||
"version": "1.0",
|
||||
"domains": { "allowed": ["oa.example.com"] },
|
||||
"pipe_actions": {
|
||||
"allowed": ["click", "type", "navigate", "getText"],
|
||||
"blocked": []
|
||||
}
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
let tool = BrowserPipeTool::new(transport, policy, handshake.session_key)
|
||||
.with_response_timeout(Duration::from_secs(1));
|
||||
|
||||
let result = tool
|
||||
.invoke(
|
||||
Action::Click,
|
||||
serde_json::json!({ "selector": "#submit" }),
|
||||
"oa.example.com",
|
||||
)
|
||||
.unwrap();
|
||||
let written = captured.snapshot();
|
||||
|
||||
assert_eq!(
|
||||
result.timing,
|
||||
Timing {
|
||||
queue_ms: 2,
|
||||
exec_ms: 38
|
||||
}
|
||||
);
|
||||
assert!(written.contains(r#""type":"init_ack""#));
|
||||
assert!(written.contains(r#""type":"command""#));
|
||||
assert!(written.contains(r#""action":"click""#));
|
||||
|
||||
let lines: Vec<&str> = written.lines().collect();
|
||||
let command: AgentMessage = serde_json::from_str(lines[1]).unwrap();
|
||||
assert!(matches!(
|
||||
command,
|
||||
AgentMessage::Command { seq, .. } if seq == 1
|
||||
));
|
||||
}
|
||||
Reference in New Issue
Block a user