feat: render results to HTML page
This commit is contained in:
parent
8b0e05ba14
commit
01844ed321
5 changed files with 260 additions and 1 deletions
118
Cargo.lock
generated
118
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
88
src/pages/mod.rs
Normal file
88
src/pages/mod.rs
Normal file
|
@ -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<String> {
|
||||
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<Context>,
|
||||
}
|
||||
|
||||
#[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()
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
|
|
52
templates/index.html
Normal file
52
templates/index.html
Normal file
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Ftest results</title>
|
||||
</head>
|
||||
<body>
|
||||
{% for suite in payload.results.suites %}
|
||||
|
||||
<h1>{{ suite.suite.name }}</h1>
|
||||
|
||||
<p>{{ suite.suite.description }}</p>
|
||||
<h2>Tests</h2>
|
||||
{% for test in suite.tests %}
|
||||
<details class="test">
|
||||
{% if test.result.success %}
|
||||
<summary><h3 class="test__name">[OK] {{ test.name }}</h3></summary>
|
||||
{% else %}
|
||||
<summary><h3 class="test__name">[FAILED] {{ test.name }}</h3></summary>
|
||||
{% endif %}
|
||||
<h4>Logs</h4>
|
||||
<code>{{ test.result.logs | linebreaksbr }}</code>
|
||||
<h4>Container Logs: {{ test.result.container.name }}</h4>
|
||||
<code>{{ test.result.container.logs | linebreaksbr }}</code>
|
||||
</details>
|
||||
{% endfor %} {% endfor %} {% if payload.results.init_containers %}
|
||||
|
||||
<h2>Initialization Workflow</h2>
|
||||
|
||||
{% for init in payload.results.init_containers %}
|
||||
|
||||
<details>
|
||||
{% if init.success %}
|
||||
<summary>
|
||||
<h3 class="test__name">[OK] {{init.container.name}}</h3>
|
||||
</summary>
|
||||
{% else %}
|
||||
<summary>
|
||||
<h3 class="test__name">[FAILED] {{init.container.name}}</h3>
|
||||
</summary>
|
||||
{% endif %}
|
||||
<code>{{ init.container.logs | linebreaksbr }}</code>
|
||||
</details>
|
||||
{% endfor %} {% endif %}
|
||||
</body>
|
||||
<style>
|
||||
.test__name {
|
||||
display: inline;
|
||||
}
|
||||
</style>
|
||||
</html>
|
Loading…
Reference in a new issue