use crate::http::Call;
use crate::report::html::Testcase;
use crate::report::html::nav::Tab;
use crate::report::html::timeline::unit::Pixel;
use crate::runner::EntryResult;
use hurl_core::ast::HurlFile;
use hurl_core::types::Index;
mod calls;
mod nice;
mod svg;
mod unit;
mod util;
mod waterfall;
const CALL_HEIGHT: Pixel = Pixel(24.0);
const CALL_INSET: Pixel = Pixel(3.0);
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum CallContextKind {
Success, Failure, Retry, }
pub struct CallContext {
pub kind: CallContextKind, pub line: Index, pub entry_index: Index, pub call_entry_index: Index, pub call_index: Index, pub source_filename: String,
pub run_filename: String,
}
impl Testcase {
pub fn get_timeline_html(
&self,
hurl_file: &HurlFile,
content: &str,
entries: &[EntryResult],
secrets: &[&str],
) -> String {
let calls = entries
.iter()
.flat_map(|e| &e.calls)
.collect::<Vec<&Call>>();
let call_ctxs = self.get_call_contexts(hurl_file, entries);
let timeline_css = include_str!("../resources/timeline.css");
let nav = self.get_nav_html(content, Tab::Timeline, secrets);
let nav_css = include_str!("../resources/nav.css");
let calls_svg = self.get_calls_svg(&calls, &call_ctxs, secrets);
let waterfall_svg = self.get_waterfall_svg(&calls, &call_ctxs, secrets);
format!(
include_str!("../resources/timeline.html"),
calls = calls_svg,
filename = self.filename,
nav = nav,
nav_css = nav_css,
timeline_css = timeline_css,
waterfall = waterfall_svg,
)
}
fn get_call_contexts(&self, hurl_file: &HurlFile, entries: &[EntryResult]) -> Vec<CallContext> {
let mut calls_ctx = vec![];
for (entry_index, e) in entries.iter().enumerate() {
let next_e = entries.get(entry_index + 1);
let retry = match next_e {
None => false, Some(next_e) => e.entry_index == next_e.entry_index,
};
let kind = match (e.errors.is_empty(), retry) {
(true, _) => CallContextKind::Success,
(false, true) => CallContextKind::Retry,
(false, false) => CallContextKind::Failure,
};
for (call_entry_index, _) in e.calls.iter().enumerate() {
let entry_src_index = e.entry_index.to_zero_based();
let entry_src = hurl_file.entries.get(entry_src_index).unwrap();
let line = Index::new(entry_src.source_info().start.line);
let ctx = CallContext {
kind,
line,
entry_index: Index::from_zero_based(entry_index),
call_entry_index: Index::from_zero_based(call_entry_index),
call_index: Index::from_zero_based(calls_ctx.len()),
source_filename: self.source_filename(),
run_filename: self.run_filename(),
};
calls_ctx.push(ctx);
}
}
calls_ctx
}
}