use std::fs;
use std::path::PathBuf;
use serde_json::json;
use light_fw_cli_core::session;
fn scratch() -> PathBuf {
let nanos = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.expect("clock")
.as_nanos();
let dir = std::env::temp_dir().join(format!("light-session-test-{nanos}"));
fs::create_dir_all(&dir).expect("create");
dir
}
const TINY_PNG_B64: &str =
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC";
#[test]
fn session_lifecycle_with_actions_and_screenshot() {
let cwd = scratch();
let _ = fs::remove_dir_all(cwd.join(".light"));
let id = session::start_session(&cwd).expect("start");
assert!(!id.is_empty());
let sessions = cwd.join(".light").join("agent-sessions");
let sess = sessions.join(&id);
assert!(sess.is_dir(), "каталог сессии создан: {sess:?}");
assert!(sess.join("actions.jsonl").is_file(), "actions.jsonl создан");
assert!(sess.join("screenshots").is_dir(), "screenshots/ создан");
assert!(sess.join("state").is_dir(), "state/ создан");
let marker = sessions.join("current");
assert_eq!(fs::read_to_string(&marker).expect("marker"), id);
session::record_action(
&cwd,
"find",
&json!({"tag": "button"}),
&json!({"key": "0.0"}),
None,
)
.expect("record find");
session::record_action(&cwd, "click", &json!({"key": "0.0"}), &json!("ok"), None)
.expect("record click");
let rel = session::save_screenshot(&cwd, &format!("base64:{TINY_PNG_B64}"), "shot")
.expect("save screenshot");
assert!(rel.is_some(), "путь скриншота возвращён");
let png_path = sess.join(rel.as_deref().unwrap());
assert!(png_path.is_file(), "PNG сохранён: {png_path:?}");
session::record_action(&cwd, "shot", &json!(null), &json!("<png>"), rel.as_deref())
.expect("record shot");
let summary = session::stop_session(&cwd, &id).expect("stop");
assert!(summary.is_file(), "summary.md существует: {summary:?}");
assert!(!marker.exists(), "маркер current удалён");
let text = fs::read_to_string(&summary).expect("summary text");
assert!(text.contains("# Agent Session Summary"));
assert!(text.contains("**Actions:** 3"), "счётчик действий: {text}");
assert!(
text.contains("**Screenshots:** 1"),
"счётчик скриншотов: {text}"
);
assert!(text.contains("## Sequence"), "раздел Sequence: {text}");
assert!(text.contains("**find**"), "команда find в хронике: {text}");
assert!(
text.contains("**click**"),
"команда click в хронике: {text}"
);
assert!(
text.contains("screenshot:"),
"ссылка на скриншот в хронике: {text}"
);
assert!(text.contains("## Sequence"), "раздел Sequence: {text}");
let _ = fs::remove_dir_all(&cwd);
}
#[test]
fn stop_without_active_session_fails() {
let cwd = scratch();
let err = session::stop_session(&cwd, "no-such-id").expect_err("нет активной сессии");
let msg = format!("{err}");
assert!(!msg.is_empty(), "возвращается осмысленная ошибка");
let _ = fs::remove_dir_all(&cwd);
}