feat: render results to HTML page

This commit is contained in:
Aravinth Manivannan 2023-10-04 21:04:42 +05:30
parent 8b0e05ba14
commit 01844ed321
Signed by: realaravinth
GPG Key ID: F8F50389936984FF
5 changed files with 260 additions and 1 deletions

118
Cargo.lock generated
View File

@ -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"

View File

@ -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
View 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()
}
}

View File

@ -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
View 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>