html_image_comparer/
lib.rs

1mod error;
2
3use chromiumoxide::{
4    Page,
5    cdp::browser_protocol::page::{CaptureScreenshotFormat, CaptureScreenshotParams},
6    page::ScreenshotParams,
7};
8pub use error::*;
9
10async fn render(code: &str, page: &Page) -> Result<Vec<u8>> {
11    page.set_content(code).await?;
12
13    let image_buffer = page
14        .screenshot(ScreenshotParams {
15            cdp_params: CaptureScreenshotParams {
16                format: Some(CaptureScreenshotFormat::Png),
17                ..Default::default()
18            },
19            ..Default::default()
20        })
21        .await?;
22
23    Ok(image_buffer)
24}
25
26pub async fn diff(
27    html: &str,
28    expected_image: &[u8],
29    width: u32,
30    height: u32,
31    page: &Page,
32) -> Result<(f64, Vec<u8>)> {
33    let html_image = render(html, page).await?;
34    let rendered_size = (width * height) as usize;
35    let mut diff_buffer = Vec::with_capacity(rendered_size);
36
37    let diff = pixelmatch::pixelmatch::<&[u8], &[u8], _>(
38        &html_image,
39        expected_image,
40        Some(&mut diff_buffer),
41        Some(width),
42        Some(height),
43        Some(pixelmatch::Options {
44            threshold: 0.1,
45            ..Default::default()
46        }),
47    )
48    .map_err(|_| Error::Image("Failed to compare images"))?;
49
50    let match_percent = 1. - (diff as f64) / (rendered_size as f64);
51
52    Ok((match_percent, diff_buffer))
53}