ferridriver_test/expect/
page.rs1use std::future::Future;
5use std::sync::Arc;
6use std::time::Duration;
7
8use ferridriver::Page;
9use ferridriver_expect::{Expect, ExpectContext, MatchError, poll_until as expect_poll_until};
10
11use crate::model::TestFailure;
12
13fn page_ctx(method: &'static str, is_not: bool) -> ExpectContext {
14 ExpectContext {
15 method,
16 subject: "page".into(),
17 is_not,
18 }
19}
20
21async fn poll_until_test<F, Fut>(timeout: Duration, ctx: ExpectContext, check: F) -> Result<(), TestFailure>
22where
23 F: FnMut() -> Fut,
24 Fut: Future<Output = Result<(), MatchError>>,
25{
26 expect_poll_until(timeout, ctx, check).await.map_err(Into::into)
27}
28
29#[allow(async_fn_in_trait)]
32pub trait PageSnapshotMatchers {
33 async fn to_have_screenshot(&self, name: &str) -> Result<(), TestFailure>;
34 async fn to_match_aria_snapshot(&self, expected: &str) -> Result<(), TestFailure>;
35}
36
37impl PageSnapshotMatchers for Expect<'_, Arc<Page>> {
38 async fn to_have_screenshot(&self, name: &str) -> Result<(), TestFailure> {
39 let page = self.subject;
40 let actual_png = page
41 .screenshot(ferridriver::options::ScreenshotOptions::default())
42 .await
43 .map_err(|e| TestFailure {
44 message: format!("page screenshot failed: {e}"),
45 stack: None,
46 diff: None,
47 screenshot: None,
48 })?;
49
50 crate::snapshot::compare_screenshot_png(&actual_png, name)
51 }
52
53 async fn to_match_aria_snapshot(&self, expected: &str) -> Result<(), TestFailure> {
54 let page = self.subject;
55 let is_not = self.is_not;
56 let expected = expected.to_string();
57
58 poll_until_test(self.timeout, page_ctx("toMatchAriaSnapshot", is_not), || {
59 let expected = expected.clone();
60 async move {
61 let snapshot = page
62 .snapshot_for_ai(ferridriver::snapshot::SnapshotOptions {
63 depth: None,
64 track: None,
65 })
66 .await
67 .map_err(|e| MatchError::new("(aria snapshot)", format!("error: {e}")))?;
68
69 let contains = snapshot.full.contains(&expected);
70 if contains == is_not {
71 Err(MatchError::new(
72 format!("{}\n{expected}", if is_not { "not matching" } else { "matching" }),
73 snapshot.full[..snapshot.full.len().min(500)].to_string(),
74 ))
75 } else {
76 Ok(())
77 }
78 }
79 })
80 .await
81 }
82}