Fix clippy warnings across CLI codebase (#654)

* Fix clippy warnings across CLI codebase

Fixes #653

* Fix remaining items_after_test_module clippy warnings

Move functions defined after `mod tests` blocks to before the test
modules in recording.rs and webdriver/client.rs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: ctate <366502+ctate@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Chris Tate
2026-03-06 16:18:51 -06:00
committed by GitHub
co-authored by Claude Opus 4.6 ctate
parent 68cebe5192
commit aba2353112
12 changed files with 85 additions and 119 deletions
+2 -2
View File
@@ -137,7 +137,7 @@ pub fn parse_command(args: &[String], flags: &Flags) -> Result<Value, ParseError
// === Core Actions ===
"click" => {
let new_tab = rest.iter().any(|arg| *arg == "--new-tab");
let new_tab = rest.contains(&"--new-tab");
let sel = rest
.iter()
.find(|arg| **arg != "--new-tab")
@@ -588,7 +588,7 @@ pub fn parse_command(args: &[String], flags: &Flags) -> Result<Value, ParseError
let mut j = 2;
while j < rest.len() {
match rest[j].as_ref() {
match rest[j] {
"--url" => {
url = rest.get(j + 1).cloned();
j += 1;
+22 -36
View File
@@ -173,7 +173,7 @@ impl DaemonState {
let already_tracked = self
.browser
.as_ref()
.map_or(true, |b| b.has_target(&te.target_info.target_id));
.is_none_or(|b| b.has_target(&te.target_info.target_id));
if !already_tracked {
new_targets.push(te);
}
@@ -549,16 +549,16 @@ pub async fn execute_command(cmd: &Value, state: &mut DaemonState) -> Value {
}
// WebDriver backend: reject unsupported CDP-only actions
if matches!(state.backend_type, BackendType::WebDriver) {
if WEBDRIVER_UNSUPPORTED_ACTIONS.contains(&action) {
return error_response(
&id,
&format!(
"Action '{}' is not supported on the WebDriver backend",
action
),
);
}
if matches!(state.backend_type, BackendType::WebDriver)
&& WEBDRIVER_UNSUPPORTED_ACTIONS.contains(&action)
{
return error_response(
&id,
&format!(
"Action '{}' is not supported on the WebDriver backend",
action
),
);
}
let result = match action {
@@ -841,15 +841,7 @@ async fn handle_launch(cmd: &Value, state: &mut DaemonState) -> Result<Value, St
let needs_relaunch = if let Some(ref mgr) = state.browser {
let has_cdp_arg = cdp_url.is_some() || cdp_port.is_some();
let was_cdp = mgr.is_cdp_connection();
if has_cdp_arg != was_cdp {
true
} else if has_cdp_arg && !mgr.is_connection_alive().await {
true
} else if auto_connect && !mgr.is_connection_alive().await {
true
} else {
!mgr.is_connection_alive().await
}
has_cdp_arg != was_cdp || !mgr.is_connection_alive().await
} else {
true
};
@@ -3232,12 +3224,7 @@ async fn handle_frame(cmd: &Value, state: &mut DaemonState) -> Result<Value, Str
.send_command_no_params("Page.getFrameTree", Some(&session_id))
.await?;
fn find_frame(
tree: &Value,
selector: Option<&str>,
name: Option<&str>,
url: Option<&str>,
) -> Option<String> {
fn find_frame(tree: &Value, name: Option<&str>, url: Option<&str>) -> Option<String> {
let frame = tree.get("frame")?;
let frame_name = frame.get("name").and_then(|v| v.as_str()).unwrap_or("");
let frame_url = frame.get("url").and_then(|v| v.as_str()).unwrap_or("");
@@ -3256,7 +3243,7 @@ async fn handle_frame(cmd: &Value, state: &mut DaemonState) -> Result<Value, Str
if let Some(children) = tree.get("childFrames").and_then(|v| v.as_array()) {
for child in children {
if let Some(id) = find_frame(child, selector, name, url) {
if let Some(id) = find_frame(child, name, url) {
return Some(id);
}
}
@@ -3281,13 +3268,13 @@ async fn handle_frame(cmd: &Value, state: &mut DaemonState) -> Result<Value, Str
);
let result = mgr.evaluate(&js, None).await?;
let frame_name = result.as_str().ok_or("Could not find frame for selector")?;
if let Some(frame_id) = find_frame(frame_tree, None, Some(frame_name), None) {
if let Some(frame_id) = find_frame(frame_tree, Some(frame_name), None) {
state.active_frame_id = Some(frame_id);
return Ok(json!({ "frame": frame_name }));
}
}
if let Some(frame_id) = find_frame(frame_tree, selector, name, url) {
if let Some(frame_id) = find_frame(frame_tree, name, url) {
let label = name.or(url).unwrap_or("frame");
state.active_frame_id = Some(frame_id);
return Ok(json!({ "frame": label }));
@@ -4015,14 +4002,13 @@ async fn handle_waitfordownload(cmd: &Value, state: &DaemonState) -> Result<Valu
Ok(Ok(event)) => {
if event.method == "Page.downloadProgress"
&& event.session_id.as_deref() == Some(&session_id)
&& event.params.get("state").and_then(|v| v.as_str()) == Some("completed")
{
if event.params.get("state").and_then(|v| v.as_str()) == Some("completed") {
let path = cmd
.get("path")
.and_then(|v| v.as_str())
.unwrap_or("download");
return Ok(json!({ "path": path }));
}
let path = cmd
.get("path")
.and_then(|v| v.as_str())
.unwrap_or("download");
return Ok(json!({ "path": path }));
}
}
Ok(Err(_)) => return Err("Event stream closed".to_string()),
+3 -4
View File
@@ -215,16 +215,15 @@ fn decrypt_profile(data: &[u8]) -> Result<AuthProfile, String> {
combined.extend_from_slice(&ciphertext);
combined.extend_from_slice(&auth_tag);
let cipher = Aes256Gcm::new_from_slice(&key)
.map_err(|e| format!("Decryption key error: {}", e))?;
let cipher =
Aes256Gcm::new_from_slice(&key).map_err(|e| format!("Decryption key error: {}", e))?;
let plaintext = cipher
.decrypt(aes_gcm::Nonce::from_slice(&iv), combined.as_slice())
.map_err(|e| format!("Decryption failed: {}", e))?;
let json_str = String::from_utf8(plaintext)
.map_err(|e| format!("Decrypted data is not valid UTF-8: {}", e))?;
return serde_json::from_str(&json_str)
.map_err(|e| format!("Invalid profile data: {}", e));
return serde_json::from_str(&json_str).map_err(|e| format!("Invalid profile data: {}", e));
}
// Fallback: try as plain unencrypted JSON profile
+3 -1
View File
@@ -79,7 +79,9 @@ fn validate_lightpanda_options(options: &LaunchOptions) -> Result<(), String> {
return Err("Headed mode is not supported with Lightpanda (headless only)".to_string());
}
if !options.args.is_empty() {
return Err("Custom Chrome arguments (--args) are not supported with Lightpanda".to_string());
return Err(
"Custom Chrome arguments (--args) are not supported with Lightpanda".to_string(),
);
}
Ok(())
}
+2 -13
View File
@@ -23,22 +23,13 @@ impl Drop for LightpandaProcess {
}
}
#[derive(Default)]
pub struct LightpandaLaunchOptions {
pub executable_path: Option<String>,
pub proxy: Option<String>,
pub port: Option<u16>,
}
impl Default for LightpandaLaunchOptions {
fn default() -> Self {
Self {
executable_path: None,
proxy: None,
port: None,
}
}
}
pub fn find_lightpanda() -> Option<PathBuf> {
// Check PATH via `which`
#[cfg(unix)]
@@ -89,9 +80,7 @@ pub fn find_lightpanda() -> Option<PathBuf> {
None
}
pub fn launch_lightpanda(
options: &LightpandaLaunchOptions,
) -> Result<LightpandaProcess, String> {
pub fn launch_lightpanda(options: &LightpandaLaunchOptions) -> Result<LightpandaProcess, String> {
let binary_path = match &options.executable_path {
Some(p) => PathBuf::from(p),
None => find_lightpanda().ok_or(
+1
View File
@@ -532,6 +532,7 @@ pub struct BrowserVersionInfo {
/// Chromium source) into `cli/cdp-protocol/` and rebuild.
///
/// Usage: `use super::cdp::types::generated::cdp_page::*;`
#[allow(clippy::upper_case_acronyms)]
pub mod generated {
include!(concat!(env!("OUT_DIR"), "/cdp_generated.rs"));
}
+19 -19
View File
@@ -112,6 +112,25 @@ pub fn recording_stop(state: &mut RecordingState) -> Result<Value, String> {
}
}
pub fn recording_restart(state: &mut RecordingState, path: &str) -> Result<Value, String> {
let previous = if state.active {
let stop_result = recording_stop(state);
stop_result
.ok()
.and_then(|v| v.get("path").and_then(|p| p.as_str()).map(String::from))
} else {
None
};
recording_start(state, path)?;
Ok(json!({
"restarted": true,
"previousPath": previous,
"path": path,
}))
}
#[cfg(test)]
mod tests {
use super::*;
@@ -182,22 +201,3 @@ mod tests {
let _ = std::fs::remove_dir_all(&state.temp_dir);
}
}
pub fn recording_restart(state: &mut RecordingState, path: &str) -> Result<Value, String> {
let previous = if state.active {
let stop_result = recording_stop(state);
stop_result
.ok()
.and_then(|v| v.get("path").and_then(|p| p.as_str()).map(String::from))
} else {
None
};
recording_start(state, path)?;
Ok(json!({
"restarted": true,
"previousPath": previous,
"path": path,
}))
}
+2 -14
View File
@@ -65,6 +65,7 @@ const STRUCTURAL_ROLES: &[&str] = &[
"RootWebArea",
];
#[derive(Default)]
pub struct SnapshotOptions {
pub selector: Option<String>,
pub interactive: bool,
@@ -73,18 +74,6 @@ pub struct SnapshotOptions {
pub cursor: bool,
}
impl Default for SnapshotOptions {
fn default() -> Self {
Self {
selector: None,
interactive: false,
compact: false,
depth: None,
cursor: false,
}
}
}
struct TreeNode {
role: String,
name: String,
@@ -364,8 +353,7 @@ async fn find_cursor_interactive_elements(
let escaped = text
.replace('\\', "\\\\")
.replace('"', "\\\"")
.replace('\n', " ")
.replace('\r', " ");
.replace(['\n', '\r'], " ");
lines.push(format!("[ref={}] ({}) \"{}\"", ref_id, kind, escaped));
}
+1 -1
View File
@@ -467,7 +467,7 @@ pub fn find_auto_state_file(session_name: &str) -> Option<String> {
.ok()
.and_then(|m| m.modified().ok())
.unwrap_or(std::time::UNIX_EPOCH);
if best_path.as_ref().map_or(true, |(_, t)| modified > *t) {
if best_path.as_ref().is_none_or(|(_, t)| modified > *t) {
best_path = Some((path.to_string_lossy().to_string(), modified));
}
}
+1
View File
@@ -155,6 +155,7 @@ async fn accept_loop(
}
}
#[allow(clippy::result_large_err)]
async fn handle_ws_client(
stream: tokio::net::TcpStream,
_addr: SocketAddr,
+26 -26
View File
@@ -212,32 +212,6 @@ impl WebDriverClient {
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_client_new() {
let client = WebDriverClient::new(4444);
assert_eq!(client.base_url, "http://127.0.0.1:4444");
assert!(client.session_id.is_none());
}
#[test]
fn test_session_id_none() {
let client = WebDriverClient::new(4444);
let result = client.session_id();
assert!(result.is_err());
assert!(result.unwrap_err().contains("No active WebDriver session"));
}
#[test]
fn test_client_custom_port() {
let client = WebDriverClient::new(9515);
assert_eq!(client.base_url, "http://127.0.0.1:9515");
}
}
async fn http_request(method: &str, url: &str, body: Option<&Value>) -> Result<Value, String> {
let parsed = url::Url::parse(url).map_err(|e| format!("Invalid URL: {}", e))?;
let host = parsed.host_str().unwrap_or("127.0.0.1");
@@ -316,3 +290,29 @@ async fn http_request(method: &str, url: &str, body: Option<&Value>) -> Result<V
)
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_client_new() {
let client = WebDriverClient::new(4444);
assert_eq!(client.base_url, "http://127.0.0.1:4444");
assert!(client.session_id.is_none());
}
#[test]
fn test_session_id_none() {
let client = WebDriverClient::new(4444);
let result = client.session_id();
assert!(result.is_err());
assert!(result.unwrap_err().contains("No active WebDriver session"));
}
#[test]
fn test_client_custom_port() {
let client = WebDriverClient::new(9515);
assert_eq!(client.base_url, "http://127.0.0.1:9515");
}
}