From 186f5099b561bcd7eed57f77d649907e51f61986 Mon Sep 17 00:00:00 2001 From: Tate Date: Thu, 14 Aug 2025 22:47:20 +1200 Subject: [PATCH 1/4] Close browser page on Civilization shutdown --- toolproof/src/civilization.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/toolproof/src/civilization.rs b/toolproof/src/civilization.rs index f57ba88..67514da 100644 --- a/toolproof/src/civilization.rs +++ b/toolproof/src/civilization.rs @@ -37,13 +37,20 @@ pub struct Civilization<'u> { } impl<'u> Civilization<'u> { - pub async fn shutdown(&mut self) { + pub async fn shutdown(self) { for handle in &self.handles { handle.stop(false).await; } for thread in &self.threads { thread.abort(); } + + if let Some(BrowserWindow::Chrome(window)) = self.window { + window + .close() + .await + .expect("Failed to close browser window"); + } } } From 44daada552c75edd9c8dd5825b18e22f9d4a8921 Mon Sep 17 00:00:00 2001 From: Tate Date: Thu, 14 Aug 2025 23:02:38 +1200 Subject: [PATCH 2/4] Fix clippy warnings --- toolproof/src/definitions/assertions/mod.rs | 28 +++++++++---------- .../definitions/browser/browser_specific.rs | 5 +--- toolproof/src/definitions/browser/mod.rs | 12 ++------ toolproof/src/definitions/filesystem/mod.rs | 3 -- toolproof/src/definitions/hosting/mod.rs | 5 +--- toolproof/src/definitions/mod.rs | 21 +++++++------- toolproof/src/definitions/process/mod.rs | 10 +++---- toolproof/src/errors.rs | 2 -- toolproof/src/interactive.rs | 2 +- toolproof/src/main.rs | 18 ++---------- toolproof/src/options.rs | 8 ++---- toolproof/src/runner.rs | 10 +++---- toolproof/src/segments.rs | 7 ++--- toolproof/src/snapshot_writer.rs | 7 +---- 14 files changed, 45 insertions(+), 93 deletions(-) diff --git a/toolproof/src/definitions/assertions/mod.rs b/toolproof/src/definitions/assertions/mod.rs index 9c21fbe..5a9fea9 100644 --- a/toolproof/src/definitions/assertions/mod.rs +++ b/toolproof/src/definitions/assertions/mod.rs @@ -1,11 +1,9 @@ -use std::collections::HashMap; - use async_trait::async_trait; use crate::civilization::Civilization; -use crate::errors::{ToolproofInputError, ToolproofInternalError, ToolproofStepError}; +use crate::errors::{ToolproofInternalError, ToolproofStepError}; -use super::{SegmentArgs, ToolproofAssertion, ToolproofInstruction, ToolproofRetriever}; +use super::{SegmentArgs, ToolproofAssertion}; fn value_contains_value( base: &serde_json::Value, @@ -87,7 +85,7 @@ fn value_type(val: &serde_json::Value) -> &'static str { } mod contain { - use crate::errors::{ToolproofInternalError, ToolproofTestFailure}; + use crate::errors::ToolproofTestFailure; use super::*; @@ -107,7 +105,7 @@ mod contain { &self, base_value: serde_json::Value, args: &SegmentArgs<'_>, - civ: &mut Civilization, + _civ: &mut Civilization, ) -> Result<(), ToolproofStepError> { let expected = args.get_value("expected")?; @@ -143,7 +141,7 @@ mod contain { &self, base_value: serde_json::Value, args: &SegmentArgs<'_>, - civ: &mut Civilization, + _civ: &mut Civilization, ) -> Result<(), ToolproofStepError> { let expected = args.get_value("expected")?; @@ -163,7 +161,7 @@ mod contain { } mod exactly { - use crate::errors::{ToolproofInternalError, ToolproofTestFailure}; + use crate::errors::ToolproofTestFailure; use super::*; @@ -183,7 +181,7 @@ mod exactly { &self, base_value: serde_json::Value, args: &SegmentArgs<'_>, - civ: &mut Civilization, + _civ: &mut Civilization, ) -> Result<(), ToolproofStepError> { let expected = args.get_value("expected")?; @@ -217,7 +215,7 @@ mod exactly { &self, base_value: serde_json::Value, args: &SegmentArgs<'_>, - civ: &mut Civilization, + _civ: &mut Civilization, ) -> Result<(), ToolproofStepError> { let expected = args.get_value("expected")?; @@ -237,7 +235,7 @@ mod exactly { } mod empty { - use crate::errors::{ToolproofInternalError, ToolproofTestFailure}; + use crate::errors::ToolproofTestFailure; use super::*; @@ -256,8 +254,8 @@ mod empty { async fn run( &self, base_value: serde_json::Value, - args: &SegmentArgs<'_>, - civ: &mut Civilization, + _args: &SegmentArgs<'_>, + _civ: &mut Civilization, ) -> Result<(), ToolproofStepError> { if value_is_empty(&base_value) { Ok(()) @@ -289,8 +287,8 @@ mod empty { async fn run( &self, base_value: serde_json::Value, - args: &SegmentArgs<'_>, - civ: &mut Civilization, + _args: &SegmentArgs<'_>, + _civ: &mut Civilization, ) -> Result<(), ToolproofStepError> { if value_is_empty(&base_value) { Err(ToolproofStepError::Assertion( diff --git a/toolproof/src/definitions/browser/browser_specific.rs b/toolproof/src/definitions/browser/browser_specific.rs index 1717e1f..3b12f5f 100644 --- a/toolproof/src/definitions/browser/browser_specific.rs +++ b/toolproof/src/definitions/browser/browser_specific.rs @@ -1,9 +1,6 @@ use std::path::PathBuf; -use chromiumoxide::cdp::browser_protocol::{ - input::{DispatchKeyEventParams, DispatchKeyEventType}, - page::CaptureScreenshotFormat, -}; +use chromiumoxide::cdp::browser_protocol::page::CaptureScreenshotFormat; use crate::errors::{ToolproofInputError, ToolproofStepError, ToolproofTestFailure}; diff --git a/toolproof/src/definitions/browser/mod.rs b/toolproof/src/definitions/browser/mod.rs index 0ff382b..f6d9310 100644 --- a/toolproof/src/definitions/browser/mod.rs +++ b/toolproof/src/definitions/browser/mod.rs @@ -2,13 +2,10 @@ use std::path::PathBuf; use std::sync::Arc; use async_trait::async_trait; -use chromiumoxide::cdp::browser_protocol::page::{ - CaptureScreenshotFormat, CaptureScreenshotParams, -}; +use chromiumoxide::cdp::browser_protocol::page::CaptureScreenshotParams; use chromiumoxide::cdp::browser_protocol::target::{ CreateBrowserContextParams, CreateTargetParams, }; -use chromiumoxide::cdp::js_protocol::runtime::RemoteObjectType; use chromiumoxide::error::CdpError; use chromiumoxide::handler::viewport::Viewport; use chromiumoxide::page::ScreenshotParams; @@ -627,10 +624,6 @@ mod load_page { } mod eval_js { - use std::time::Duration; - - use futures::TryFutureExt; - use tokio::time::sleep; use crate::errors::{ToolproofInternalError, ToolproofTestFailure}; @@ -747,7 +740,7 @@ mod eval_js { async fn run( &self, - args: &SegmentArgs<'_>, + _args: &SegmentArgs<'_>, civ: &mut Civilization, ) -> Result { eval_and_return_js("return toolproof_log_events[`ALL`];".to_string(), civ).await @@ -756,7 +749,6 @@ mod eval_js { } pub mod screenshots { - use crate::errors::{ToolproofInternalError, ToolproofTestFailure}; use super::*; diff --git a/toolproof/src/definitions/filesystem/mod.rs b/toolproof/src/definitions/filesystem/mod.rs index cf88ec0..6c54abc 100644 --- a/toolproof/src/definitions/filesystem/mod.rs +++ b/toolproof/src/definitions/filesystem/mod.rs @@ -1,5 +1,3 @@ -use std::collections::HashMap; - use async_trait::async_trait; use crate::civilization::Civilization; @@ -46,7 +44,6 @@ mod new_file { } mod read_files { - use crate::errors::ToolproofTestFailure; use super::*; diff --git a/toolproof/src/definitions/hosting/mod.rs b/toolproof/src/definitions/hosting/mod.rs index e6b7a74..7b4aa36 100644 --- a/toolproof/src/definitions/hosting/mod.rs +++ b/toolproof/src/definitions/hosting/mod.rs @@ -1,8 +1,6 @@ -use std::collections::HashMap; - use super::{SegmentArgs, ToolproofInstruction}; use crate::civilization::Civilization; -use crate::errors::{ToolproofInputError, ToolproofStepError}; +use crate::errors::ToolproofStepError; use async_trait::async_trait; @@ -10,7 +8,6 @@ mod host_dir { use std::time::Duration; use actix_web::{App, HttpServer}; - use futures::pending; use schematic::color::owo::OwoColorize; use tokio::time::sleep; diff --git a/toolproof/src/definitions/mod.rs b/toolproof/src/definitions/mod.rs index 943508d..2a7650a 100644 --- a/toolproof/src/definitions/mod.rs +++ b/toolproof/src/definitions/mod.rs @@ -1,13 +1,12 @@ -use std::{collections::HashMap, hash::Hash}; +use std::collections::HashMap; use async_trait::async_trait; use crate::{ civilization::Civilization, - errors::{ToolproofInputError, ToolproofStepError}, - options::{ToolproofContext, ToolproofParams}, + errors::ToolproofStepError, parser::parse_segments, - segments::{SegmentArgs, ToolproofSegment, ToolproofSegments}, + segments::{SegmentArgs, ToolproofSegments}, }; mod assertions; @@ -115,8 +114,8 @@ mod test { async fn run( &self, - args: &SegmentArgs<'_>, - civ: &mut Civilization, + _args: &SegmentArgs<'_>, + _civ: &mut Civilization, ) -> Result<(), ToolproofStepError> { Ok(()) } @@ -153,8 +152,8 @@ mod test { async fn run( &self, - args: &SegmentArgs<'_>, - civ: &mut Civilization, + _args: &SegmentArgs<'_>, + _civ: &mut Civilization, ) -> Result { Ok(serde_json::Value::Null) } @@ -190,9 +189,9 @@ mod test { async fn run( &self, - base_value: serde_json::Value, - args: &SegmentArgs<'_>, - civ: &mut Civilization, + _base_value: serde_json::Value, + _args: &SegmentArgs<'_>, + _civ: &mut Civilization, ) -> Result<(), ToolproofStepError> { Ok(()) } diff --git a/toolproof/src/definitions/process/mod.rs b/toolproof/src/definitions/process/mod.rs index 5ec228c..d20e457 100644 --- a/toolproof/src/definitions/process/mod.rs +++ b/toolproof/src/definitions/process/mod.rs @@ -1,11 +1,9 @@ -use std::collections::HashMap; - use async_trait::async_trait; use crate::civilization::Civilization; -use crate::errors::{ToolproofInputError, ToolproofStepError}; +use crate::errors::ToolproofStepError; -use super::{SegmentArgs, ToolproofAssertion, ToolproofInstruction, ToolproofRetriever}; +use super::{SegmentArgs, ToolproofInstruction, ToolproofRetriever}; mod env_var { use super::*; @@ -135,7 +133,7 @@ mod stdio { async fn run( &self, - args: &SegmentArgs<'_>, + _args: &SegmentArgs<'_>, civ: &mut Civilization, ) -> Result { let Some(output) = &civ.last_command_output else { @@ -164,7 +162,7 @@ mod stdio { async fn run( &self, - args: &SegmentArgs<'_>, + _args: &SegmentArgs<'_>, civ: &mut Civilization, ) -> Result { let Some(output) = &civ.last_command_output else { diff --git a/toolproof/src/errors.rs b/toolproof/src/errors.rs index a09eb92..3756f49 100644 --- a/toolproof/src/errors.rs +++ b/toolproof/src/errors.rs @@ -1,5 +1,3 @@ -use std::path::PathBuf; - use chromiumoxide::error::CdpError; use pagebrowse::PagebrowseError; use thiserror::Error; diff --git a/toolproof/src/interactive.rs b/toolproof/src/interactive.rs index 1e1ae37..8e24050 100644 --- a/toolproof/src/interactive.rs +++ b/toolproof/src/interactive.rs @@ -1,4 +1,4 @@ -use std::{fmt::Display, io, path::PathBuf, sync::Arc}; +use std::{io, sync::Arc}; use console::{Key, Term}; use dialoguer::{theme::ColorfulTheme, Confirm, FuzzySelect, Select}; diff --git a/toolproof/src/main.rs b/toolproof/src/main.rs index bfa8d26..84d37f6 100644 --- a/toolproof/src/main.rs +++ b/toolproof/src/main.rs @@ -656,22 +656,8 @@ async fn main_inner() -> Result<(), ()> { } } } - ToolproofTestStep::Extract { - extract, - extract_location, - args, - orig, - state, - platforms, - } => todo!(), - ToolproofTestStep::Snapshot { - snapshot, - snapshot_content, - args, - orig, - state, - platforms, - } => todo!(), + ToolproofTestStep::Extract { .. } => todo!(), + ToolproofTestStep::Snapshot { .. } => todo!(), } } _ => { diff --git a/toolproof/src/options.rs b/toolproof/src/options.rs index 4a31153..ad00254 100644 --- a/toolproof/src/options.rs +++ b/toolproof/src/options.rs @@ -1,8 +1,6 @@ -use clap::{ - arg, builder::PossibleValuesParser, command, value_parser, Arg, ArgAction, ArgMatches, Command, -}; +use clap::{arg, builder::PossibleValuesParser, command, value_parser, ArgMatches}; use miette::IntoDiagnostic; -use schematic::{derive_enum, Config, ConfigEnum, ConfigLoader}; +use schematic::{Config, ConfigEnum, ConfigLoader}; use serde::{Deserialize, Serialize}; use std::{collections::HashMap, env, path::PathBuf}; @@ -48,7 +46,7 @@ pub fn configure() -> ToolproofContext { match ToolproofContext::load(result.config) { Ok(ctx) => ctx, - Err(e) => { + Err(_e) => { eprintln!("Failed to initialize configuration"); std::process::exit(1); } diff --git a/toolproof/src/runner.rs b/toolproof/src/runner.rs index db08dca..8a262d5 100644 --- a/toolproof/src/runner.rs +++ b/toolproof/src/runner.rs @@ -1,5 +1,5 @@ use async_recursion::async_recursion; -use futures::FutureExt; + use normalize_path::NormalizePath; use similar_string::find_best_similarity; use std::{ @@ -10,8 +10,6 @@ use std::{ }; use tokio::time::{self, Duration}; -use console::style; - use crate::{ civilization::Civilization, definitions::{browser::screenshots::ScreenshotViewport, ToolproofInstruction}, @@ -226,9 +224,10 @@ async fn run_toolproof_steps( crate::ToolproofTestStep::Instruction { step, args, - orig, + state, platforms, + .. } => { let Some((reference_segments, instruction)) = civ.universe.instructions.get_key_value(step) @@ -270,9 +269,10 @@ async fn run_toolproof_steps( retrieval, assertion, args, - orig, + state, platforms, + .. } => { let Some((reference_ret, retrieval_step)) = civ.universe.retrievers.get_key_value(retrieval) diff --git a/toolproof/src/segments.rs b/toolproof/src/segments.rs index 0bc49e5..b7859a4 100644 --- a/toolproof/src/segments.rs +++ b/toolproof/src/segments.rs @@ -1,8 +1,7 @@ use std::{collections::HashMap, hash::Hash}; -use crate::{civilization::Civilization, errors::ToolproofInputError, options::ToolproofContext}; +use crate::{civilization::Civilization, errors::ToolproofInputError}; -use async_trait::async_trait; use path_slash::{PathBufExt, PathExt}; use serde_json::Value; @@ -292,9 +291,7 @@ mod test { use crate::{ civilization::Civilization, - definitions::{register_instructions, ToolproofInstruction}, - errors::ToolproofStepError, - options::ToolproofParams, + options::{ToolproofContext, ToolproofParams}, parser::parse_segments, universe::Universe, }; diff --git a/toolproof/src/snapshot_writer.rs b/toolproof/src/snapshot_writer.rs index 6bf0007..f09fff4 100644 --- a/toolproof/src/snapshot_writer.rs +++ b/toolproof/src/snapshot_writer.rs @@ -8,12 +8,7 @@ pub fn write_yaml_snapshots(input_doc: &str, hydrated_file: &ToolproofTestFile) for (step_id, step) in hydrated_file.steps.iter().enumerate() { match step { ToolproofTestStep::Snapshot { - snapshot, - snapshot_content, - args, - orig, - state, - platforms, + snapshot_content, .. } => { let Some(snapshot_content) = snapshot_content else { continue; From 985c2e61cf9647a14e088024aef9dd29f2ee21c2 Mon Sep 17 00:00:00 2001 From: Tate Date: Thu, 14 Aug 2025 23:20:53 +1200 Subject: [PATCH 3/4] Update dependencies --- toolproof/Cargo.toml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/toolproof/Cargo.toml b/toolproof/Cargo.toml index 057fc7c..7f54a3e 100644 --- a/toolproof/Cargo.toml +++ b/toolproof/Cargo.toml @@ -7,34 +7,34 @@ license = "MIT" [dependencies] thiserror = "1.0" -wax = "0.5.0" +wax = "0.6.0" tokio = { version = "1", features = ["full", "tracing"] } futures = "0.3" -async-recursion = "1.1.0" +async-recursion = "1.1.1" serde = { version = "1.0", features = ["derive"] } serde_yaml = "0.9" serde_json = "1" nondestructive = "0.0.20" -similar = { version = "2.4.0", features = ["inline"] } -inventory = "0.3.15" +similar = { version = "2.7.0", features = ["inline"] } +inventory = "0.3.20" portpicker = "0.1" actix-web = "4" actix-files = "0.6" json_dotpath = "1.1.0" -tempfile = "3.0.2" +tempfile = "3.20.0" similar-string = "1.4.3" -console = "0.15" +console = "0.16" dialoguer = { version = "0.11", features = ["fuzzy-select"] } -async-trait = "0.1.78" +async-trait = "0.1.88" pagebrowse = "0.1.1" chromiumoxide = "0.7" clap = { version = "4", features = ["cargo"] } -schematic = { version = "0.18.4", features = ["yaml"] } -strip-ansi-escapes = "0.2.0" +schematic = { version = "0.18.12", features = ["yaml"] } +strip-ansi-escapes = "0.2.1" path-slash = "0.2.1" normalize-path = "0.2.1" miette = { version = "7", features = ["fancy"] } -semver = "1.0.25" +semver = "1.0.26" [profile.dev.package.similar] opt-level = 3 From 1159887d6100c6b2758e8af5e26faae87d7a7c42 Mon Sep 17 00:00:00 2001 From: Tate Date: Thu, 14 Aug 2025 23:21:26 +1200 Subject: [PATCH 4/4] Update changelog --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c81aa75..d750420 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,19 @@ ## Unreleased +* Fixed Chrome browser windows not being closed after a test run +* Updated dependencies + * Updated wax to 0.6.0 + * Updated async-recursion to 1.1.1 + * Updated similar to 2.7.0 + * Updated inventory to 0.3.20 + * Updated tempfile to 3.20.0 + * Updated console to 0.16 + * Updated async-trait to 0.1.88 + * Updated schematic to 0.18.12 + * Updated strip-ansi-escapes to 0.2.1 + * Updated semver to 1.0.26 + ## v0.15.0 (May 16, 2025) * Added a `--retry-count` option to retry failed tests