//! Responsive WebUI regression pins for issue #10. //! //! These guard the two *textual* acceptance criteria that survive //! without a headless browser: every page ships a `width=device-width` //! viewport meta tag, and the three desktop-width pages (cases list, //! case page, recordings) carry at least one `@media` breakpoint so the //! layout can reflow on narrow viewports. The visual criteria (operable //! at 390px, 44px touch targets) are verified by eye; these tests stop a //! future template rewrite from silently dropping the viewport tag or //! the breakpoints. mod common; use axum::body::Body; use axum::http::{Request, StatusCode}; use tower::util::ServiceExt; use common::{TestConfig, body_string, get_with_cookie, paths, seed_case, test_user}; const VIEWPORT: &str = "width=device-width"; #[tokio::test] async fn login_page_has_viewport_meta() { let cfg = TestConfig::new() .with_label("resp-login") .with_user(test_user("dr_a")) .build(); let app = doctate_server::create_router(cfg); let resp = app .oneshot( Request::builder() .uri(paths::LOGIN) .body(Body::empty()) .unwrap(), ) .await .unwrap(); assert_eq!(resp.status(), StatusCode::OK); let body = body_string(resp).await; assert!(body.contains(VIEWPORT), "login page missing viewport meta"); } #[tokio::test] async fn cases_list_has_viewport_and_media_query() { let cfg = TestConfig::new() .with_label("resp-cases") .with_user(test_user("dr_a")) .build(); let app = doctate_server::create_router(cfg); let cookie = common::login(&app, "dr_a", "s").await; let resp = app .oneshot(get_with_cookie(paths::CASES, &cookie)) .await .unwrap(); assert_eq!(resp.status(), StatusCode::OK); let body = body_string(resp).await; assert!(body.contains(VIEWPORT), "cases list missing viewport meta"); assert!( body.contains("@media"), "cases list missing @media breakpoint" ); } #[tokio::test] async fn case_page_has_viewport_and_media_query() { let cfg = TestConfig::new() .with_label("resp-cp") .with_user(test_user("dr_a")) .with_llm("http://unused") .build(); let case_id = "22222222-2222-2222-2222-222222222222"; seed_case(&cfg.data_path, "dr_a", case_id); let app = doctate_server::create_router(cfg); let cookie = common::login(&app, "dr_a", "s").await; let resp = app .oneshot(get_with_cookie(paths::case_detail(case_id), &cookie)) .await .unwrap(); assert_eq!(resp.status(), StatusCode::OK); let body = body_string(resp).await; assert!(body.contains(VIEWPORT), "case page missing viewport meta"); assert!( body.contains("@media"), "case page missing @media breakpoint" ); } #[tokio::test] async fn case_recordings_has_viewport_and_media_query() { let cfg = TestConfig::new() .with_label("resp-rec") .with_user(test_user("dr_a")) .build(); let case_id = "33333333-3333-3333-3333-333333333333"; seed_case(&cfg.data_path, "dr_a", case_id); let app = doctate_server::create_router(cfg); let cookie = common::login(&app, "dr_a", "s").await; let resp = app .oneshot(get_with_cookie(paths::case_recordings(case_id), &cookie)) .await .unwrap(); assert_eq!(resp.status(), StatusCode::OK); let body = body_string(resp).await; assert!( body.contains(VIEWPORT), "recordings page missing viewport meta" ); assert!( body.contains("@media"), "recordings page missing @media breakpoint" ); }