diff --git a/Cargo.lock b/Cargo.lock index 043c429..e160bec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -473,6 +473,16 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "bstr" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "bumpalo" version = "3.13.0" @@ -983,6 +993,7 @@ dependencies = [ "serde_json", "sqlx 0.6.3", "sqlx 0.7.2", + "tera", "tokio", "toml 0.7.6", "tracing", @@ -1102,6 +1113,30 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +[[package]] +name = "globset" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" +dependencies = [ + "aho-corasick", + "bstr", + "fnv", + "log", + "regex", +] + +[[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags 1.3.2", + "ignore", + "walkdir", +] + [[package]] name = "h2" version = "0.3.21" @@ -1302,6 +1337,23 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "ignore" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492" +dependencies = [ + "globset", + "lazy_static", + "log", + "memchr", + "regex", + "same-file", + "thread_local", + "walkdir", + "winapi-util", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -2826,6 +2878,22 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "tera" +version = "1.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "970dff17c11e884a4a09bc76e3a17ef71e01bb13447a11e85226e254fe6d10b8" +dependencies = [ + "globwalk", + "lazy_static", + "pest", + "pest_derive", + "regex", + "serde", + "serde_json", + "unic-segment", +] + [[package]] name = "termcolor" version = "1.2.0" @@ -3110,6 +3178,56 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" +dependencies = [ + "unic-ucd-segment", +] + +[[package]] +name = "unic-ucd-segment" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + [[package]] name = "unicase" version = "2.7.0" diff --git a/Cargo.toml b/Cargo.toml index 7647b6d..dd27db5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,7 @@ toml = "0.7.6" tokio = { version = "1.32.0", features = ["sync", "time"] } clap = { version = "4.4.6", features = ["derive"] } actix-rt = "2.7.0" +tera = { version = "1.19.1", default-features = false } [build-dependencies] serde_json = "1" diff --git a/src/pages/mod.rs b/src/pages/mod.rs new file mode 100644 index 0000000..d3c3b20 --- /dev/null +++ b/src/pages/mod.rs @@ -0,0 +1,88 @@ +use std::cell::RefCell; + +use lazy_static::lazy_static; +use rust_embed::RustEmbed; +use serde::{Deserialize, Serialize}; +use tera::*; + +lazy_static! { + pub static ref TEMPLATES: Tera = { + let mut tera = match Tera::new("templates/**/*") { + Ok(t) => t, + Err(e) => { + println!("Parsing error(s): {}", e); + ::std::process::exit(1); + } + }; + register_templates(&mut tera); + tera.autoescape_on(vec![".html", ".sql"]); + tera + }; +} + +#[derive(RustEmbed)] +#[folder = "templates/"] +pub struct Templates; + +impl Templates { + pub fn get_template(t: &TemplateFile) -> Option { + match Self::get(t.path) { + Some(file) => Some(String::from_utf8_lossy(&file.data).into_owned()), + None => None, + } + } +} + +pub struct TemplateFile { + pub name: &'static str, + pub path: &'static str, +} + +impl TemplateFile { + pub const fn new(name: &'static str, path: &'static str) -> Self { + Self { name, path } + } + + pub fn register(&self, t: &mut Tera) -> std::result::Result<(), tera::Error> { + t.add_raw_template(self.name, &Templates::get_template(self).expect(self.name)) + } + + #[cfg(test)] + #[allow(dead_code)] + pub fn register_from_file(&self, t: &mut Tera) -> std::result::Result<(), tera::Error> { + use std::path::Path; + t.add_template_file(Path::new("templates/").join(self.path), Some(self.name)) + } +} + +pub const INDEX: TemplateFile = TemplateFile::new("index", "index.html"); + +pub fn register_templates(t: &mut tera::Tera) { + for template in [INDEX].iter() { + template.register(t).expect(template.name); + } +} +#[derive(Clone)] +pub struct ViewResult { + ctx: RefCell, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Payload { + pub results: crate::runner::results::ArchivableResult, +} + +const PAYLOAD_KEY: &str = "payload"; + +impl ViewResult { + pub fn new(payload: Payload) -> Self { + let mut ctx = Context::new(); + ctx.insert(PAYLOAD_KEY, &payload); + let ctx = RefCell::new(ctx); + Self { ctx } + } + + pub fn render(&self) -> String { + TEMPLATES.render(INDEX.name, &self.ctx.borrow()).unwrap() + } +} diff --git a/src/runner/suite.rs b/src/runner/suite.rs index 197735e..a137ad1 100644 --- a/src/runner/suite.rs +++ b/src/runner/suite.rs @@ -295,7 +295,7 @@ mod tests { for archivable_test in results.tests.iter() { //let archivable_test = results.tests.get(0).unwrap(); - let t = if archivable_test.name == dummy_test.name.as_ref() { + let t = if archivable_test.name == dummy_test.name { dummy_test.clone() } else { dummy_test2.clone() diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..2a99ec1 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,52 @@ + + + + + + Ftest results + + + {% for suite in payload.results.suites %} + +

{{ suite.suite.name }}

+ +

{{ suite.suite.description }}

+

Tests

+ {% for test in suite.tests %} +
+ {% if test.result.success %} +

[OK] {{ test.name }}

+ {% else %} +

[FAILED] {{ test.name }}

+ {% endif %} +

Logs

+ {{ test.result.logs | linebreaksbr }} +

Container Logs: {{ test.result.container.name }}

+ {{ test.result.container.logs | linebreaksbr }} +
+ {% endfor %} {% endfor %} {% if payload.results.init_containers %} + +

Initialization Workflow

+ + {% for init in payload.results.init_containers %} + +
+ {% if init.success %} + +

[OK] {{init.container.name}}

+
+ {% else %} + +

[FAILED] {{init.container.name}}

+
+ {% endif %} + {{ init.container.logs | linebreaksbr }} +
+ {% endfor %} {% endif %} + + +