forked from openai/codex
-
Notifications
You must be signed in to change notification settings - Fork 229
Expand file tree
/
Copy pathlocal_navigation.rs
More file actions
91 lines (79 loc) · 3.31 KB
/
local_navigation.rs
File metadata and controls
91 lines (79 loc) · 3.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use code_browser::BrowserConfig;
use code_browser::BrowserManager;
use std::io::Read;
use std::io::Write;
use std::net::TcpListener;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use std::thread;
use std::time::Duration;
fn spawn_http_server() -> (String, Arc<AtomicBool>, thread::JoinHandle<()>) {
let listener = TcpListener::bind("127.0.0.1:0").expect("bind test server");
listener
.set_nonblocking(true)
.expect("set non-blocking listener");
let addr = listener.local_addr().expect("listener addr");
let stop = Arc::new(AtomicBool::new(false));
let stop_thread = Arc::clone(&stop);
let handle = thread::spawn(move || {
while !stop_thread.load(Ordering::Relaxed) {
match listener.accept() {
Ok((mut stream, _)) => {
let mut buf = [0_u8; 2048];
let _ = stream.read(&mut buf);
let body = "<html><head><title>Code Browser Local Test</title></head><body><h1>browser-ok</h1></body></html>";
let response = format!(
"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{}",
body.len(), body
);
let _ = stream.write_all(response.as_bytes());
let _ = stream.flush();
}
Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => {
thread::sleep(Duration::from_millis(25));
}
Err(_) => break,
}
}
});
(format!("http://127.0.0.1:{}", addr.port()), stop, handle)
}
async fn assert_manager_can_open_local_http_server(headless: bool) {
let (url, stop, handle) = spawn_http_server();
let mut config = BrowserConfig::default();
config.enabled = true;
config.headless = headless;
config.idle_timeout_ms = 300_000;
let manager = BrowserManager::new(config);
manager.goto(&url).await.expect("navigate to local server");
let current_url = manager
.get_current_url()
.await
.expect("manager current url after goto");
assert!(current_url == url || current_url == format!("{url}/"));
let page = manager.get_or_create_page().await.expect("page after goto");
let href = page.inject_js("location.href").await.expect("raw href");
let href_text = href.as_str().unwrap_or_default();
assert!(href_text == url || href_text == format!("{url}/"));
let body = page
.execute_javascript("document.body && document.body.innerText")
.await
.expect("read page body");
let body_text = body
.get("value")
.and_then(|value| value.as_str())
.unwrap_or_default();
assert!(body_text.contains("browser-ok"), "unexpected page body: {body_text}");
stop.store(true, Ordering::Relaxed);
let _ = handle.join();
let _ = manager.stop().await;
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn internal_browser_can_open_local_http_server() {
assert_manager_can_open_local_http_server(true).await;
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn headed_internal_browser_can_open_local_http_server() {
assert_manager_can_open_local_http_server(false).await;
}