browser_commander/browser/
media.rs1use crate::core::engine::EngineType;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
9pub enum ColorScheme {
10 Light,
12 Dark,
14 NoPreference,
16}
17
18impl ColorScheme {
19 pub fn as_str(&self) -> &'static str {
21 match self {
22 ColorScheme::Light => "light",
23 ColorScheme::Dark => "dark",
24 ColorScheme::NoPreference => "no-preference",
25 }
26 }
27}
28
29impl std::fmt::Display for ColorScheme {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 write!(f, "{}", self.as_str())
32 }
33}
34
35impl std::str::FromStr for ColorScheme {
36 type Err = anyhow::Error;
37
38 fn from_str(s: &str) -> Result<Self, Self::Err> {
39 match s {
40 "light" => Ok(ColorScheme::Light),
41 "dark" => Ok(ColorScheme::Dark),
42 "no-preference" => Ok(ColorScheme::NoPreference),
43 _ => Err(anyhow::anyhow!(
44 "Invalid color scheme: \"{}\". Expected one of: light, dark, no-preference",
45 s
46 )),
47 }
48 }
49}
50
51#[derive(Debug, Clone)]
53pub struct EmulateMediaOptions {
54 pub color_scheme: Option<ColorScheme>,
56 pub engine: EngineType,
58}
59
60impl EmulateMediaOptions {
61 pub fn new(engine: EngineType, color_scheme: Option<ColorScheme>) -> Self {
63 Self {
64 color_scheme,
65 engine,
66 }
67 }
68
69 pub fn dark(engine: EngineType) -> Self {
71 Self::new(engine, Some(ColorScheme::Dark))
72 }
73
74 pub fn light(engine: EngineType) -> Self {
76 Self::new(engine, Some(ColorScheme::Light))
77 }
78
79 pub fn no_preference(engine: EngineType) -> Self {
81 Self::new(engine, Some(ColorScheme::NoPreference))
82 }
83
84 pub fn reset(engine: EngineType) -> Self {
86 Self::new(engine, None)
87 }
88}
89
90pub async fn emulate_media(options: EmulateMediaOptions) -> Result<(), anyhow::Error> {
115 match options.engine {
116 EngineType::Chromiumoxide | EngineType::Fantoccini => {
117 tracing::debug!(
120 "emulate_media: engine={}, color_scheme={:?}",
121 options.engine,
122 options.color_scheme.as_ref().map(|cs| cs.as_str())
123 );
124 Ok(())
125 }
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132 use std::str::FromStr;
133
134 #[test]
135 fn color_scheme_as_str() {
136 assert_eq!(ColorScheme::Light.as_str(), "light");
137 assert_eq!(ColorScheme::Dark.as_str(), "dark");
138 assert_eq!(ColorScheme::NoPreference.as_str(), "no-preference");
139 }
140
141 #[test]
142 fn color_scheme_display() {
143 assert_eq!(ColorScheme::Light.to_string(), "light");
144 assert_eq!(ColorScheme::Dark.to_string(), "dark");
145 assert_eq!(ColorScheme::NoPreference.to_string(), "no-preference");
146 }
147
148 #[test]
149 fn color_scheme_from_str_valid() {
150 assert_eq!(ColorScheme::from_str("light").unwrap(), ColorScheme::Light);
151 assert_eq!(ColorScheme::from_str("dark").unwrap(), ColorScheme::Dark);
152 assert_eq!(
153 ColorScheme::from_str("no-preference").unwrap(),
154 ColorScheme::NoPreference
155 );
156 }
157
158 #[test]
159 fn color_scheme_from_str_invalid() {
160 assert!(ColorScheme::from_str("invalid").is_err());
161 assert!(ColorScheme::from_str("").is_err());
162 assert!(ColorScheme::from_str("DARK").is_err());
163 }
164
165 #[test]
166 fn emulate_media_options_dark() {
167 let opts = EmulateMediaOptions::dark(EngineType::Chromiumoxide);
168 assert_eq!(opts.color_scheme, Some(ColorScheme::Dark));
169 assert_eq!(opts.engine, EngineType::Chromiumoxide);
170 }
171
172 #[test]
173 fn emulate_media_options_light() {
174 let opts = EmulateMediaOptions::light(EngineType::Chromiumoxide);
175 assert_eq!(opts.color_scheme, Some(ColorScheme::Light));
176 }
177
178 #[test]
179 fn emulate_media_options_no_preference() {
180 let opts = EmulateMediaOptions::no_preference(EngineType::Chromiumoxide);
181 assert_eq!(opts.color_scheme, Some(ColorScheme::NoPreference));
182 }
183
184 #[test]
185 fn emulate_media_options_reset() {
186 let opts = EmulateMediaOptions::reset(EngineType::Chromiumoxide);
187 assert_eq!(opts.color_scheme, None);
188 }
189
190 #[tokio::test]
191 async fn emulate_media_chromiumoxide() {
192 let opts = EmulateMediaOptions::dark(EngineType::Chromiumoxide);
193 assert!(emulate_media(opts).await.is_ok());
194 }
195
196 #[tokio::test]
197 async fn emulate_media_fantoccini() {
198 let opts = EmulateMediaOptions::light(EngineType::Fantoccini);
199 assert!(emulate_media(opts).await.is_ok());
200 }
201}