1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 use crate::common::{WebElement, ELEMENT_KEY};
6 use serde::de::{self, Deserialize, Deserializer};
7 use serde::ser::{Serialize, Serializer};
8 use serde_json::Value;
9 use std::default::Default;
10 use unicode_segmentation::UnicodeSegmentation;
11
12 #[derive(Debug, PartialEq, Serialize, Deserialize)]
13 pub struct ActionSequence {
14 pub id: String,
15 #[serde(flatten)]
16 pub actions: ActionsType,
17 }
18
19 #[derive(Debug, PartialEq, Serialize, Deserialize)]
20 #[serde(tag = "type")]
21 pub enum ActionsType {
22 #[serde(rename = "none")]
23 Null { actions: Vec<NullActionItem> },
24 #[serde(rename = "key")]
25 Key { actions: Vec<KeyActionItem> },
26 #[serde(rename = "pointer")]
27 Pointer {
28 #[serde(default)]
29 parameters: PointerActionParameters,
30 actions: Vec<PointerActionItem>,
31 },
32 }
33
34 #[derive(Debug, PartialEq, Serialize, Deserialize)]
35 #[serde(untagged)]
36 pub enum NullActionItem {
37 General(GeneralAction),
38 }
39
40 #[derive(Debug, PartialEq, Serialize, Deserialize)]
41 #[serde(tag = "type")]
42 pub enum GeneralAction {
43 #[serde(rename = "pause")]
44 Pause(PauseAction),
45 }
46
47 #[derive(Debug, PartialEq, Serialize, Deserialize)]
48 pub struct PauseAction {
49 #[serde(
50 default,
51 skip_serializing_if = "Option::is_none",
52 deserialize_with = "deserialize_to_option_u64"
53 )]
54 pub duration: Option<u64>,
55 }
56
57 #[derive(Debug, PartialEq, Serialize, Deserialize)]
58 #[serde(untagged)]
59 pub enum KeyActionItem {
60 General(GeneralAction),
61 Key(KeyAction),
62 }
63
64 #[derive(Debug, PartialEq, Serialize, Deserialize)]
65 #[serde(tag = "type")]
66 pub enum KeyAction {
67 #[serde(rename = "keyDown")]
68 Down(KeyDownAction),
69 #[serde(rename = "keyUp")]
70 Up(KeyUpAction),
71 }
72
73 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
74 pub struct KeyDownAction {
75 #[serde(deserialize_with = "deserialize_key_action_value")]
76 pub value: String,
77 }
78
79 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
80 pub struct KeyUpAction {
81 #[serde(deserialize_with = "deserialize_key_action_value")]
82 pub value: String,
83 }
84
deserialize_key_action_value<'de, D>(deserializer: D) -> Result<String, D::Error> where D: Deserializer<'de>,85 fn deserialize_key_action_value<'de, D>(deserializer: D) -> Result<String, D::Error>
86 where
87 D: Deserializer<'de>,
88 {
89 String::deserialize(deserializer).map(|value| {
90 // Only a single Unicode grapheme cluster is allowed
91 if value.graphemes(true).count() != 1 {
92 return Err(de::Error::custom(format!(
93 "'{}' should only contain a single Unicode code point",
94 value
95 )));
96 }
97
98 Ok(value)
99 })?
100 }
101
102 #[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
103 #[serde(rename_all = "lowercase")]
104 pub enum PointerType {
105 Mouse,
106 Pen,
107 Touch,
108 }
109
110 impl Default for PointerType {
default() -> PointerType111 fn default() -> PointerType {
112 PointerType::Mouse
113 }
114 }
115
116 #[derive(Debug, Default, PartialEq, Serialize, Deserialize)]
117 pub struct PointerActionParameters {
118 #[serde(rename = "pointerType")]
119 pub pointer_type: PointerType,
120 }
121
122 #[derive(Debug, PartialEq, Serialize, Deserialize)]
123 #[serde(untagged)]
124 pub enum PointerActionItem {
125 General(GeneralAction),
126 Pointer(PointerAction),
127 }
128
129 #[derive(Debug, PartialEq, Serialize, Deserialize)]
130 #[serde(tag = "type")]
131 pub enum PointerAction {
132 #[serde(rename = "pointerCancel")]
133 Cancel,
134 #[serde(rename = "pointerDown")]
135 Down(PointerDownAction),
136 #[serde(rename = "pointerMove")]
137 Move(PointerMoveAction),
138 #[serde(rename = "pointerUp")]
139 Up(PointerUpAction),
140 }
141
142 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
143 pub struct PointerDownAction {
144 pub button: u64,
145 }
146
147 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
148 pub struct PointerMoveAction {
149 #[serde(
150 default,
151 skip_serializing_if = "Option::is_none",
152 deserialize_with = "deserialize_to_option_u64"
153 )]
154 pub duration: Option<u64>,
155 #[serde(default)]
156 pub origin: PointerOrigin,
157 #[serde(
158 default,
159 skip_serializing_if = "Option::is_none",
160 deserialize_with = "deserialize_to_option_i64"
161 )]
162 pub x: Option<i64>,
163 #[serde(
164 default,
165 skip_serializing_if = "Option::is_none",
166 deserialize_with = "deserialize_to_option_i64"
167 )]
168 pub y: Option<i64>,
169 }
170
171 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
172 pub struct PointerUpAction {
173 pub button: u64,
174 }
175
176 #[derive(Clone, Debug, PartialEq, Serialize)]
177 pub enum PointerOrigin {
178 #[serde(
179 rename = "element-6066-11e4-a52e-4f735466cecf",
180 serialize_with = "serialize_webelement_id"
181 )]
182 Element(WebElement),
183 #[serde(rename = "pointer")]
184 Pointer,
185 #[serde(rename = "viewport")]
186 Viewport,
187 }
188
189 impl Default for PointerOrigin {
default() -> PointerOrigin190 fn default() -> PointerOrigin {
191 PointerOrigin::Viewport
192 }
193 }
194
195 // TODO: The custom deserializer can be removed once the support of the legacy
196 // ELEMENT key has been removed from Selenium bindings
197 // See: https://github.com/SeleniumHQ/selenium/issues/6393
198 impl<'de> Deserialize<'de> for PointerOrigin {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,199 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
200 where
201 D: Deserializer<'de>,
202 {
203 let value = Value::deserialize(deserializer)?;
204 if let Some(web_element) = value.get(ELEMENT_KEY) {
205 String::deserialize(web_element)
206 .map(|id| PointerOrigin::Element(WebElement(id)))
207 .map_err(de::Error::custom)
208 } else if value == "pointer" {
209 Ok(PointerOrigin::Pointer)
210 } else if value == "viewport" {
211 Ok(PointerOrigin::Viewport)
212 } else {
213 Err(de::Error::custom(format!(
214 "unknown value `{}`, expected `pointer`, `viewport`, or `element-6066-11e4-a52e-4f735466cecf`",
215 value.to_string()
216 )))
217 }
218 }
219 }
220
serialize_webelement_id<S>(element: &WebElement, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,221 fn serialize_webelement_id<S>(element: &WebElement, serializer: S) -> Result<S::Ok, S::Error>
222 where
223 S: Serializer,
224 {
225 element.to_string().serialize(serializer)
226 }
227
deserialize_to_option_i64<'de, D>(deserializer: D) -> Result<Option<i64>, D::Error> where D: Deserializer<'de>,228 fn deserialize_to_option_i64<'de, D>(deserializer: D) -> Result<Option<i64>, D::Error>
229 where
230 D: Deserializer<'de>,
231 {
232 Option::deserialize(deserializer)?
233 .ok_or_else(|| de::Error::custom("invalid type: null, expected i64"))
234 }
235
deserialize_to_option_u64<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error> where D: Deserializer<'de>,236 fn deserialize_to_option_u64<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
237 where
238 D: Deserializer<'de>,
239 {
240 Option::deserialize(deserializer)?
241 .ok_or_else(|| de::Error::custom("invalid type: null, expected i64"))
242 }
243
244 #[cfg(test)]
245 mod test {
246 use super::*;
247 use crate::test::{assert_de, assert_ser_de};
248 use serde_json::{self, json};
249
250 #[test]
test_json_action_sequence_null()251 fn test_json_action_sequence_null() {
252 let json = json!({
253 "id": "some_key",
254 "type": "none",
255 "actions": [{
256 "type": "pause",
257 "duration": 1,
258 }]
259 });
260 let seq = ActionSequence {
261 id: "some_key".into(),
262 actions: ActionsType::Null {
263 actions: vec![NullActionItem::General(GeneralAction::Pause(PauseAction {
264 duration: Some(1),
265 }))],
266 },
267 };
268
269 assert_ser_de(&seq, json);
270 }
271
272 #[test]
test_json_action_sequence_key()273 fn test_json_action_sequence_key() {
274 let json = json!({
275 "id": "some_key",
276 "type": "key",
277 "actions": [
278 {"type": "keyDown", "value": "f"},
279 ],
280 });
281 let seq = ActionSequence {
282 id: "some_key".into(),
283 actions: ActionsType::Key {
284 actions: vec![KeyActionItem::Key(KeyAction::Down(KeyDownAction {
285 value: String::from("f"),
286 }))],
287 },
288 };
289
290 assert_ser_de(&seq, json);
291 }
292
293 #[test]
test_json_action_sequence_pointer()294 fn test_json_action_sequence_pointer() {
295 let json = json!({
296 "id": "some_pointer",
297 "type": "pointer",
298 "parameters": {
299 "pointerType": "mouse"
300 },
301 "actions": [
302 {"type": "pointerDown", "button": 0},
303 {"type": "pointerMove", "origin": "pointer", "x": 10, "y": 20},
304 {"type": "pointerUp", "button": 0},
305 ]
306 });
307 let seq = ActionSequence {
308 id: "some_pointer".into(),
309 actions: ActionsType::Pointer {
310 parameters: PointerActionParameters {
311 pointer_type: PointerType::Mouse,
312 },
313 actions: vec![
314 PointerActionItem::Pointer(PointerAction::Down(PointerDownAction {
315 button: 0,
316 })),
317 PointerActionItem::Pointer(PointerAction::Move(PointerMoveAction {
318 origin: PointerOrigin::Pointer,
319 duration: None,
320 x: Some(10),
321 y: Some(20),
322 })),
323 PointerActionItem::Pointer(PointerAction::Up(PointerUpAction { button: 0 })),
324 ],
325 },
326 };
327
328 assert_ser_de(&seq, json);
329 }
330
331 #[test]
test_json_action_sequence_id_missing()332 fn test_json_action_sequence_id_missing() {
333 let json = json!({
334 "type": "key",
335 "actions": [],
336 });
337 assert!(serde_json::from_value::<ActionSequence>(json).is_err());
338 }
339
340 #[test]
test_json_action_sequence_id_null()341 fn test_json_action_sequence_id_null() {
342 let json = json!({
343 "id": null,
344 "type": "key",
345 "actions": [],
346 });
347 assert!(serde_json::from_value::<ActionSequence>(json).is_err());
348 }
349
350 #[test]
test_json_action_sequence_actions_missing()351 fn test_json_action_sequence_actions_missing() {
352 assert!(serde_json::from_value::<ActionSequence>(json!({"id": "3"})).is_err());
353 }
354
355 #[test]
test_json_action_sequence_actions_null()356 fn test_json_action_sequence_actions_null() {
357 let json = json!({
358 "id": "3",
359 "actions": null,
360 });
361 assert!(serde_json::from_value::<ActionSequence>(json).is_err());
362 }
363
364 #[test]
test_json_action_sequence_actions_invalid_type()365 fn test_json_action_sequence_actions_invalid_type() {
366 let json = json!({
367 "id": "3",
368 "actions": "foo",
369 });
370 assert!(serde_json::from_value::<ActionSequence>(json).is_err());
371 }
372
373 #[test]
test_json_actions_type_null()374 fn test_json_actions_type_null() {
375 let json = json!({
376 "type": "none",
377 "actions": [{
378 "type": "pause",
379 "duration": 1,
380 }],
381 });
382 let null = ActionsType::Null {
383 actions: vec![NullActionItem::General(GeneralAction::Pause(PauseAction {
384 duration: Some(1),
385 }))],
386 };
387
388 assert_ser_de(&null, json);
389 }
390
391 #[test]
test_json_actions_type_key()392 fn test_json_actions_type_key() {
393 let json = json!({
394 "type": "key",
395 "actions": [{
396 "type": "keyDown",
397 "value": "f",
398 }],
399 });
400 let key = ActionsType::Key {
401 actions: vec![KeyActionItem::Key(KeyAction::Down(KeyDownAction {
402 value: String::from("f"),
403 }))],
404 };
405
406 assert_ser_de(&key, json);
407 }
408
409 #[test]
test_json_actions_type_pointer()410 fn test_json_actions_type_pointer() {
411 let json = json!({
412 "type": "pointer",
413 "parameters": {"pointerType": "mouse"},
414 "actions": [
415 {"type": "pointerDown", "button": 1},
416 ]});
417 let pointer = ActionsType::Pointer {
418 parameters: PointerActionParameters {
419 pointer_type: PointerType::Mouse,
420 },
421 actions: vec![PointerActionItem::Pointer(PointerAction::Down(
422 PointerDownAction { button: 1 },
423 ))],
424 };
425
426 assert_ser_de(&pointer, json);
427 }
428
429 #[test]
test_json_actions_type_pointer_with_parameters_missing()430 fn test_json_actions_type_pointer_with_parameters_missing() {
431 let json = json!({
432 "type": "pointer",
433 "actions": [
434 {"type": "pointerDown", "button": 1},
435 ]});
436 let pointer = ActionsType::Pointer {
437 parameters: PointerActionParameters {
438 pointer_type: PointerType::Mouse,
439 },
440 actions: vec![PointerActionItem::Pointer(PointerAction::Down(
441 PointerDownAction { button: 1 },
442 ))],
443 };
444
445 assert_de(&pointer, json);
446 }
447
448 #[test]
test_json_actions_type_pointer_with_parameters_invalid_type()449 fn test_json_actions_type_pointer_with_parameters_invalid_type() {
450 let json = json!({
451 "type": "pointer",
452 "parameters": null,
453 "actions": [
454 {"type":"pointerDown", "button": 1},
455 ]});
456 assert!(serde_json::from_value::<ActionsType>(json).is_err());
457 }
458
459 #[test]
test_json_actions_type_invalid()460 fn test_json_actions_type_invalid() {
461 let json = json!({"actions": [{"foo": "bar"}]});
462 assert!(serde_json::from_value::<ActionsType>(json).is_err());
463 }
464
465 #[test]
test_json_null_action_item_general()466 fn test_json_null_action_item_general() {
467 let pause =
468 NullActionItem::General(GeneralAction::Pause(PauseAction { duration: Some(1) }));
469 assert_ser_de(&pause, json!({"type": "pause", "duration": 1}));
470 }
471
472 #[test]
test_json_null_action_item_invalid_type()473 fn test_json_null_action_item_invalid_type() {
474 assert!(serde_json::from_value::<NullActionItem>(json!({"type": "invalid"})).is_err());
475 }
476
477 #[test]
test_json_general_action_pause()478 fn test_json_general_action_pause() {
479 let pause = GeneralAction::Pause(PauseAction { duration: Some(1) });
480 assert_ser_de(&pause, json!({"type": "pause", "duration": 1}));
481 }
482
483 #[test]
test_json_general_action_pause_with_duration_missing()484 fn test_json_general_action_pause_with_duration_missing() {
485 let pause = GeneralAction::Pause(PauseAction { duration: None });
486 assert_ser_de(&pause, json!({"type": "pause"}));
487 }
488
489 #[test]
test_json_general_action_pause_with_duration_null()490 fn test_json_general_action_pause_with_duration_null() {
491 let json = json!({"type": "pause", "duration": null});
492 assert!(serde_json::from_value::<GeneralAction>(json).is_err());
493 }
494
495 #[test]
test_json_general_action_pause_with_duration_invalid_type()496 fn test_json_general_action_pause_with_duration_invalid_type() {
497 let json = json!({"type": "pause", "duration":" foo"});
498 assert!(serde_json::from_value::<GeneralAction>(json).is_err());
499 }
500
501 #[test]
test_json_general_action_pause_with_duration_negative()502 fn test_json_general_action_pause_with_duration_negative() {
503 let json = json!({"type": "pause", "duration": -30});
504 assert!(serde_json::from_value::<GeneralAction>(json).is_err());
505 }
506
507 #[test]
test_json_key_action_item_general()508 fn test_json_key_action_item_general() {
509 let pause = KeyActionItem::General(GeneralAction::Pause(PauseAction { duration: Some(1) }));
510 assert_ser_de(&pause, json!({"type": "pause", "duration": 1}));
511 }
512
513 #[test]
test_json_key_action_item_key()514 fn test_json_key_action_item_key() {
515 let key_down = KeyActionItem::Key(KeyAction::Down(KeyDownAction {
516 value: String::from("f"),
517 }));
518 assert_ser_de(&key_down, json!({"type": "keyDown", "value": "f"}));
519 }
520
521 #[test]
test_json_key_action_item_invalid_type()522 fn test_json_key_action_item_invalid_type() {
523 assert!(serde_json::from_value::<KeyActionItem>(json!({"type": "invalid"})).is_err());
524 }
525
526 #[test]
test_json_key_action_missing_subtype()527 fn test_json_key_action_missing_subtype() {
528 assert!(serde_json::from_value::<KeyAction>(json!({"value": "f"})).is_err());
529 }
530
531 #[test]
test_json_key_action_wrong_subtype()532 fn test_json_key_action_wrong_subtype() {
533 let json = json!({"type": "pause", "value": "f"});
534 assert!(serde_json::from_value::<KeyAction>(json).is_err());
535 }
536
537 #[test]
test_json_key_action_down()538 fn test_json_key_action_down() {
539 let key_down = KeyAction::Down(KeyDownAction {
540 value: "f".to_string(),
541 });
542 assert_ser_de(&key_down, json!({"type": "keyDown", "value": "f"}));
543 }
544
545 #[test]
test_json_key_action_down_with_value_unicode()546 fn test_json_key_action_down_with_value_unicode() {
547 let key_down = KeyAction::Down(KeyDownAction {
548 value: "à".to_string(),
549 });
550 assert_ser_de(&key_down, json!({"type": "keyDown", "value": "à"}));
551 }
552
553 #[test]
test_json_key_action_down_with_value_unicode_encoded()554 fn test_json_key_action_down_with_value_unicode_encoded() {
555 let key_down = KeyAction::Down(KeyDownAction {
556 value: "à".to_string(),
557 });
558 assert_de(&key_down, json!({"type": "keyDown", "value": "\u{00E0}"}));
559 }
560
561 #[test]
test_json_key_action_down_with_value_missing()562 fn test_json_key_action_down_with_value_missing() {
563 assert!(serde_json::from_value::<KeyAction>(json!({"type": "keyDown"})).is_err());
564 }
565
566 #[test]
test_json_key_action_down_with_value_null()567 fn test_json_key_action_down_with_value_null() {
568 let json = json!({"type": "keyDown", "value": null});
569 assert!(serde_json::from_value::<KeyAction>(json).is_err());
570 }
571
572 #[test]
test_json_key_action_down_with_value_invalid_type()573 fn test_json_key_action_down_with_value_invalid_type() {
574 let json = json!({"type": "keyDown", "value": ["f", "o", "o"]});
575 assert!(serde_json::from_value::<KeyAction>(json).is_err());
576 }
577
578 #[test]
test_json_key_action_down_with_multiple_code_points()579 fn test_json_key_action_down_with_multiple_code_points() {
580 let json = json!({"type": "keyDown", "value": "fo"});
581 assert!(serde_json::from_value::<KeyAction>(json).is_err());
582 }
583
584 #[test]
test_json_key_action_up()585 fn test_json_key_action_up() {
586 let key_up = KeyAction::Up(KeyUpAction {
587 value: "f".to_string(),
588 });
589 assert_ser_de(&key_up, json!({"type": "keyUp", "value": "f"}));
590 }
591
592 #[test]
test_json_key_action_up_with_value_unicode()593 fn test_json_key_action_up_with_value_unicode() {
594 let key_up = KeyAction::Up(KeyUpAction {
595 value: "à".to_string(),
596 });
597 assert_ser_de(&key_up, json!({"type":"keyUp", "value": "à"}));
598 }
599
600 #[test]
test_json_key_action_up_with_value_unicode_encoded()601 fn test_json_key_action_up_with_value_unicode_encoded() {
602 let key_up = KeyAction::Up(KeyUpAction {
603 value: "à".to_string(),
604 });
605 assert_de(&key_up, json!({"type": "keyUp", "value": "\u{00E0}"}));
606 }
607
608 #[test]
test_json_key_action_up_with_value_missing()609 fn test_json_key_action_up_with_value_missing() {
610 assert!(serde_json::from_value::<KeyAction>(json!({"type": "keyUp"})).is_err());
611 }
612
613 #[test]
test_json_key_action_up_with_value_null()614 fn test_json_key_action_up_with_value_null() {
615 let json = json!({"type": "keyUp", "value": null});
616 assert!(serde_json::from_value::<KeyAction>(json).is_err());
617 }
618
619 #[test]
test_json_key_action_up_with_value_invalid_type()620 fn test_json_key_action_up_with_value_invalid_type() {
621 let json = json!({"type": "keyUp", "value": ["f","o","o"]});
622 assert!(serde_json::from_value::<KeyAction>(json).is_err());
623 }
624
625 #[test]
test_json_key_action_up_with_multiple_code_points()626 fn test_json_key_action_up_with_multiple_code_points() {
627 let json = json!({"type": "keyUp", "value": "fo"});
628 assert!(serde_json::from_value::<KeyAction>(json).is_err());
629 }
630
631 #[test]
test_json_pointer_action_item_general()632 fn test_json_pointer_action_item_general() {
633 let pause =
634 PointerActionItem::General(GeneralAction::Pause(PauseAction { duration: Some(1) }));
635 assert_ser_de(&pause, json!({"type": "pause", "duration": 1}));
636 }
637
638 #[test]
test_json_pointer_action_item_pointer()639 fn test_json_pointer_action_item_pointer() {
640 let cancel = PointerActionItem::Pointer(PointerAction::Cancel);
641 assert_ser_de(&cancel, json!({"type": "pointerCancel"}));
642 }
643
644 #[test]
test_json_pointer_action_item_invalid()645 fn test_json_pointer_action_item_invalid() {
646 assert!(serde_json::from_value::<PointerActionItem>(json!({"type": "invalid"})).is_err());
647 }
648
649 #[test]
test_json_pointer_action_parameters_mouse()650 fn test_json_pointer_action_parameters_mouse() {
651 let mouse = PointerActionParameters {
652 pointer_type: PointerType::Mouse,
653 };
654 assert_ser_de(&mouse, json!({"pointerType": "mouse"}));
655 }
656
657 #[test]
test_json_pointer_action_parameters_pen()658 fn test_json_pointer_action_parameters_pen() {
659 let pen = PointerActionParameters {
660 pointer_type: PointerType::Pen,
661 };
662 assert_ser_de(&pen, json!({"pointerType": "pen"}));
663 }
664
665 #[test]
test_json_pointer_action_parameters_touch()666 fn test_json_pointer_action_parameters_touch() {
667 let touch = PointerActionParameters {
668 pointer_type: PointerType::Touch,
669 };
670 assert_ser_de(&touch, json!({"pointerType": "touch"}));
671 }
672
673 #[test]
test_json_pointer_action_item_invalid_type()674 fn test_json_pointer_action_item_invalid_type() {
675 let json = json!({"type": "pointerInvalid"});
676 assert!(serde_json::from_value::<PointerActionItem>(json).is_err());
677 }
678
679 #[test]
test_json_pointer_action_missing_subtype()680 fn test_json_pointer_action_missing_subtype() {
681 assert!(serde_json::from_value::<PointerAction>(json!({"button": 1})).is_err());
682 }
683
684 #[test]
test_json_pointer_action_invalid_subtype()685 fn test_json_pointer_action_invalid_subtype() {
686 let json = json!({"type": "invalid", "button": 1});
687 assert!(serde_json::from_value::<PointerAction>(json).is_err());
688 }
689
690 #[test]
test_json_pointer_action_cancel()691 fn test_json_pointer_action_cancel() {
692 assert_ser_de(&PointerAction::Cancel, json!({"type": "pointerCancel"}));
693 }
694
695 #[test]
test_json_pointer_action_down()696 fn test_json_pointer_action_down() {
697 let pointer_down = PointerAction::Down(PointerDownAction { button: 1 });
698 assert_ser_de(&pointer_down, json!({"type": "pointerDown", "button": 1}));
699 }
700
701 #[test]
test_json_pointer_action_down_with_button_missing()702 fn test_json_pointer_action_down_with_button_missing() {
703 let json = json!({"type": "pointerDown"});
704 assert!(serde_json::from_value::<PointerAction>(json).is_err());
705 }
706
707 #[test]
test_json_pointer_action_down_with_button_null()708 fn test_json_pointer_action_down_with_button_null() {
709 let json = json!({
710 "type": "pointerDown",
711 "button": null,
712 });
713 assert!(serde_json::from_value::<PointerAction>(json).is_err());
714 }
715
716 #[test]
test_json_pointer_action_down_with_button_invalid_type()717 fn test_json_pointer_action_down_with_button_invalid_type() {
718 let json = json!({
719 "type": "pointerDown",
720 "button": "foo",
721 });
722 assert!(serde_json::from_value::<PointerAction>(json).is_err());
723 }
724
725 #[test]
test_json_pointer_action_down_with_button_negative()726 fn test_json_pointer_action_down_with_button_negative() {
727 let json = json!({
728 "type": "pointerDown",
729 "button": -30,
730 });
731 assert!(serde_json::from_value::<PointerAction>(json).is_err());
732 }
733
734 #[test]
test_json_pointer_action_move()735 fn test_json_pointer_action_move() {
736 let json = json!({
737 "type": "pointerMove",
738 "duration": 100,
739 "origin": "viewport",
740 "x": 5,
741 "y": 10,
742 });
743 let pointer_move = PointerAction::Move(PointerMoveAction {
744 duration: Some(100),
745 origin: PointerOrigin::Viewport,
746 x: Some(5),
747 y: Some(10),
748 });
749
750 assert_ser_de(&pointer_move, json);
751 }
752
753 #[test]
test_json_pointer_action_move_missing_subtype()754 fn test_json_pointer_action_move_missing_subtype() {
755 let json = json!({
756 "duration": 100,
757 "origin": "viewport",
758 "x": 5,
759 "y": 10,
760 });
761 assert!(serde_json::from_value::<PointerAction>(json).is_err());
762 }
763
764 #[test]
test_json_pointer_action_move_wrong_subtype()765 fn test_json_pointer_action_move_wrong_subtype() {
766 let json = json!({
767 "type": "pointerUp",
768 "duration": 100,
769 "origin": "viewport",
770 "x": 5,
771 "y": 10,
772 });
773 assert!(serde_json::from_value::<PointerAction>(json).is_err());
774 }
775
776 #[test]
test_json_pointer_action_move_with_duration_missing()777 fn test_json_pointer_action_move_with_duration_missing() {
778 let json = json!({
779 "type": "pointerMove",
780 "origin": "viewport",
781 "x": 5,
782 "y": 10,
783 });
784 let pointer_move = PointerAction::Move(PointerMoveAction {
785 duration: None,
786 origin: PointerOrigin::Viewport,
787 x: Some(5),
788 y: Some(10),
789 });
790
791 assert_ser_de(&pointer_move, json);
792 }
793
794 #[test]
test_json_pointer_action_move_with_duration_null()795 fn test_json_pointer_action_move_with_duration_null() {
796 let json = json!({
797 "type": "pointerMove",
798 "duration": null,
799 "origin": "viewport",
800 "x": 5,
801 "y": 10,
802 });
803 assert!(serde_json::from_value::<PointerAction>(json).is_err());
804 }
805
806 #[test]
test_json_pointer_action_move_with_duration_invalid_type()807 fn test_json_pointer_action_move_with_duration_invalid_type() {
808 let json = json!({
809 "type": "pointerMove",
810 "duration": "invalid",
811 "origin": "viewport",
812 "x": 5,
813 "y": 10,
814 });
815 assert!(serde_json::from_value::<PointerAction>(json).is_err());
816 }
817
818 #[test]
test_json_pointer_action_move_with_duration_negative()819 fn test_json_pointer_action_move_with_duration_negative() {
820 let json = json!({
821 "type": "pointerMove",
822 "duration": -30,
823 "origin": "viewport",
824 "x": 5,
825 "y": 10,
826 });
827 assert!(serde_json::from_value::<PointerAction>(json).is_err());
828 }
829
830 #[test]
test_json_pointer_action_move_with_origin_missing()831 fn test_json_pointer_action_move_with_origin_missing() {
832 let json = json!({
833 "type": "pointerMove",
834 "duration": 100,
835 "x": 5,
836 "y": 10,
837 });
838 let pointer_move = PointerAction::Move(PointerMoveAction {
839 duration: Some(100),
840 origin: PointerOrigin::Viewport,
841 x: Some(5),
842 y: Some(10),
843 });
844
845 assert_de(&pointer_move, json);
846 }
847
848 #[test]
test_json_pointer_action_move_with_origin_webelement()849 fn test_json_pointer_action_move_with_origin_webelement() {
850 let json = json!({
851 "type": "pointerMove",
852 "duration": 100,
853 "origin": {ELEMENT_KEY: "elem"},
854 "x": 5,
855 "y": 10,
856 });
857 let pointer_move = PointerAction::Move(PointerMoveAction {
858 duration: Some(100),
859 origin: PointerOrigin::Element(WebElement("elem".into())),
860 x: Some(5),
861 y: Some(10),
862 });
863
864 assert_ser_de(&pointer_move, json);
865 }
866
867 #[test]
test_json_pointer_action_move_with_origin_webelement_and_legacy_element()868 fn test_json_pointer_action_move_with_origin_webelement_and_legacy_element() {
869 let json = json!({
870 "type": "pointerMove",
871 "duration": 100,
872 "origin": {ELEMENT_KEY: "elem"},
873 "x": 5,
874 "y": 10,
875 });
876 let pointer_move = PointerAction::Move(PointerMoveAction {
877 duration: Some(100),
878 origin: PointerOrigin::Element(WebElement("elem".into())),
879 x: Some(5),
880 y: Some(10),
881 });
882
883 assert_de(&pointer_move, json);
884 }
885
886 #[test]
test_json_pointer_action_move_with_origin_only_legacy_element()887 fn test_json_pointer_action_move_with_origin_only_legacy_element() {
888 let json = json!({
889 "type": "pointerMove",
890 "duration": 100,
891 "origin": {ELEMENT_KEY: "elem"},
892 "x": 5,
893 "y": 10,
894 });
895 assert!(serde_json::from_value::<PointerOrigin>(json).is_err());
896 }
897
898 #[test]
test_json_pointer_action_move_with_x_missing()899 fn test_json_pointer_action_move_with_x_missing() {
900 let json = json!({
901 "type": "pointerMove",
902 "duration": 100,
903 "origin": "viewport",
904 "y": 10,
905 });
906 let pointer_move = PointerAction::Move(PointerMoveAction {
907 duration: Some(100),
908 origin: PointerOrigin::Viewport,
909 x: None,
910 y: Some(10),
911 });
912
913 assert_ser_de(&pointer_move, json);
914 }
915
916 #[test]
test_json_pointer_action_move_with_x_null()917 fn test_json_pointer_action_move_with_x_null() {
918 let json = json!({
919 "type": "pointerMove",
920 "duration": 100,
921 "origin": "viewport",
922 "x": null,
923 "y": 10,
924 });
925 assert!(serde_json::from_value::<PointerAction>(json).is_err());
926 }
927
928 #[test]
test_json_pointer_action_move_with_x_invalid_type()929 fn test_json_pointer_action_move_with_x_invalid_type() {
930 let json = json!({
931 "type": "pointerMove",
932 "duration": 100,
933 "origin": "viewport",
934 "x": "invalid",
935 "y": 10,
936 });
937 assert!(serde_json::from_value::<PointerAction>(json).is_err());
938 }
939
940 #[test]
test_json_pointer_action_move_with_y_missing()941 fn test_json_pointer_action_move_with_y_missing() {
942 let json = json!({
943 "type": "pointerMove",
944 "duration": 100,
945 "origin": "viewport",
946 "x": 5,
947 });
948 let pointer_move = PointerAction::Move(PointerMoveAction {
949 duration: Some(100),
950 origin: PointerOrigin::Viewport,
951 x: Some(5),
952 y: None,
953 });
954
955 assert_ser_de(&pointer_move, json);
956 }
957
958 #[test]
test_json_pointer_action_move_with_y_null()959 fn test_json_pointer_action_move_with_y_null() {
960 let json = json!({
961 "type": "pointerMove",
962 "duration": 100,
963 "origin": "viewport",
964 "x": 5,
965 "y": null,
966 });
967 assert!(serde_json::from_value::<PointerAction>(json).is_err());
968 }
969
970 #[test]
test_json_pointer_action_move_with_y_invalid_type()971 fn test_json_pointer_action_move_with_y_invalid_type() {
972 let json = json!({
973 "type": "pointerMove",
974 "duration": 100,
975 "origin": "viewport",
976 "x": 5,
977 "y": "invalid",
978 });
979 assert!(serde_json::from_value::<PointerAction>(json).is_err());
980 }
981
982 #[test]
test_json_pointer_action_up()983 fn test_json_pointer_action_up() {
984 let pointer_up = PointerAction::Up(PointerUpAction { button: 1 });
985 assert_ser_de(&pointer_up, json!({"type": "pointerUp", "button": 1}));
986 }
987
988 #[test]
test_json_pointer_action_up_with_button_missing()989 fn test_json_pointer_action_up_with_button_missing() {
990 assert!(serde_json::from_value::<PointerAction>(json!({"type": "pointerUp"})).is_err());
991 }
992
993 #[test]
test_json_pointer_action_up_with_button_null()994 fn test_json_pointer_action_up_with_button_null() {
995 let json = json!({
996 "type": "pointerUp",
997 "button": null,
998 });
999 assert!(serde_json::from_value::<PointerAction>(json).is_err());
1000 }
1001
1002 #[test]
test_json_pointer_action_up_with_button_invalid_type()1003 fn test_json_pointer_action_up_with_button_invalid_type() {
1004 let json = json!({
1005 "type": "pointerUp",
1006 "button": "foo",
1007 });
1008 assert!(serde_json::from_value::<PointerAction>(json).is_err());
1009 }
1010
1011 #[test]
test_json_pointer_action_up_with_button_negative()1012 fn test_json_pointer_action_up_with_button_negative() {
1013 let json = json!({
1014 "type": "pointerUp",
1015 "button": -30,
1016 });
1017 assert!(serde_json::from_value::<PointerAction>(json).is_err());
1018 }
1019
1020 #[test]
test_json_pointer_origin_pointer()1021 fn test_json_pointer_origin_pointer() {
1022 assert_ser_de(&PointerOrigin::Pointer, json!("pointer"));
1023 }
1024
1025 #[test]
test_json_pointer_origin_viewport()1026 fn test_json_pointer_origin_viewport() {
1027 assert_ser_de(&PointerOrigin::Viewport, json!("viewport"));
1028 }
1029
1030 #[test]
test_json_pointer_origin_web_element()1031 fn test_json_pointer_origin_web_element() {
1032 let element = PointerOrigin::Element(WebElement("elem".into()));
1033 assert_ser_de(&element, json!({ELEMENT_KEY: "elem"}));
1034 }
1035
1036 #[test]
test_json_pointer_origin_invalid_type()1037 fn test_json_pointer_origin_invalid_type() {
1038 assert!(serde_json::from_value::<PointerOrigin>(json!("invalid")).is_err());
1039 }
1040
1041 #[test]
test_json_pointer_type_mouse()1042 fn test_json_pointer_type_mouse() {
1043 assert_ser_de(&PointerType::Mouse, json!("mouse"));
1044 }
1045
1046 #[test]
test_json_pointer_type_pen()1047 fn test_json_pointer_type_pen() {
1048 assert_ser_de(&PointerType::Pen, json!("pen"));
1049 }
1050
1051 #[test]
test_json_pointer_type_touch()1052 fn test_json_pointer_type_touch() {
1053 assert_ser_de(&PointerType::Touch, json!("touch"));
1054 }
1055
1056 #[test]
test_json_pointer_type_invalid_type()1057 fn test_json_pointer_type_invalid_type() {
1058 assert!(serde_json::from_value::<PointerType>(json!("invalid")).is_err());
1059 }
1060 }
1061