chiark / gitweb /
wdt-hand: Use initial_vpid_by_desc_glob
[otter.git] / wdriver / wdt-hand.rs
1 // Copyright 2020-2021 Ian Jackson and contributors to Otter
2 // SPDX-License-Identifier: AGPL-3.0-or-later
3 // There is NO WARRANTY.
4
5 use crate::*;
6
7 #[derive(Deref)]
8 struct Ctx {
9   #[deref] su: Setup,
10   alice: Window,
11   bob: Window,
12 }
13 usual_wanted_tests!{Ctx, su}
14
15 const ALICE: &str = "1#1";
16
17 #[throws(Explode)]
18 pub fn player_dasharray(player: &'static str) -> String {
19   let player: PlayerId = player.try_into().context(player)?;
20   let player: slotmap::KeyData = player.into();
21   let (player,_) = player.get_idx_version();
22   let player: usize = player.try_into().unwrap();
23   let player = player.try_into().unwrap();
24   let dasharray = player_num_dasharray(player);
25   dasharray.into_html_string()
26 }
27
28 impl Ctx {
29   #[throws(Explode)]
30   fn claim(&mut self){
31     let su = &mut self.su;
32
33     let hand_vpid = su.initial_vpid_by_desc_glob("a hand repository")?;
34     let pawn_vpid = su.initial_vpid_by_desc_glob("a white pawn")?;
35
36     let chk = |
37         w: &mut WindowGuard<'_>, pc: &str,
38         player: Option<&'static str>
39     | {
40       w.synch()?;
41
42       let dasharray = player.map(player_dasharray).transpose()?;
43       let euse = w.find_element(By::Id(&w.vpidelem("piece", pc)?))?;
44       let epath = euse.find_element(By::Tag("path"))?;
45       let attr = epath.get_attribute("stroke-dasharray")?;
46
47       assert_eq!(attr, dasharray);
48       Ok::<_,AE>(())
49     };
50
51     let hand_posg = {
52       let mut w = su.w(&self.alice)?;
53       w.synch()?;
54
55       let hand = w.find_piece(&hand_vpid)?;
56       let hand_pieceid = hand.pieceid.to_string();
57
58       let hand_posg = hand.posg()?;
59       w.action_chain()
60         .move_pos(&hand)?
61         .send_keys("W")
62         .click()
63         .send_keys("tW")
64         .click()
65         .perform()
66         .did("select hand")?;
67       w.synch()?;
68
69       let top = w.execute_script(&format!(r##"
70           return defs_marker.previousElementSibling.dataset.piece;
71       "##))?;
72       assert_eq!( top.value().as_str().unwrap(),
73                   hand_pieceid );
74
75       w.action_chain()
76         .send_keys('C')
77         .perform()
78         .did("claim hand")?;
79       w.synch()?;
80
81       let top = w.execute_script(&format!(r##"
82           return pieces_marker.nextElementSibling.dataset.piece;
83       "##))?;
84       assert_eq!( top.value().as_str().unwrap(),
85                   hand_pieceid );
86
87       w.action_chain()
88         .click()
89         .perform()
90         .did("deselect")?;
91
92       chk(&mut w, &hand_pieceid, Some(ALICE))?;
93
94       hand_posg
95     };
96
97     {
98       let mut w = su.w(&self.bob)?;
99       chk(&mut w, &hand_vpid, Some(ALICE))?;
100
101       w.get(w.current_url()?)?;
102       chk(&mut w, &hand_vpid, Some(ALICE))?;
103     }
104
105     {
106       let mut w = su.w(&self.alice)?;
107       let pawn = w.find_piece(&pawn_vpid)?;
108       w.action_chain()
109         .move_pos(&pawn)?
110         .click_and_hold()
111         .move_w(&w, (hand_posg + PosC::new(20,0))?)?
112         .release()
113         .perform()?;
114       w.synch()?;
115     }
116
117     for side in &[&self.alice, &self.bob] {
118       let mut w = su.w(side)?;
119       w.synch()?;
120       let log = w.retrieve_log((&mut |_: &'_ _| false) as LogIgnoreBeforeFn)?;
121       log.assert_no_conflicts();
122     }
123
124     {
125       let mut w = su.w(&self.alice)?;
126
127       let hand = w.find_piece(&hand_vpid)?;
128       w.action_chain()
129         .move_pos(&hand)?
130         .click()
131         .perform()
132         .did("select hand")?;
133       w.synch()?;
134
135       w.action_chain()
136         .send_keys('C')
137         .perform()
138         .did("unclaim hand")?;
139
140       w.action_chain()
141         .click()
142         .perform()
143         .did("deselect")?;
144
145       chk(&mut w, &hand_vpid, None)?;
146     }
147     {
148       let mut w = su.w(&self.bob)?;
149       chk(&mut w, &hand_vpid, None)?;
150     }
151   }
152
153   #[throws(Explode)]
154   fn ungrab_race(&mut self){
155     let su = &mut self.su;
156  
157     let p_alice = su.initial_vpid_by_desc_glob("a white pawn")?;
158     let p_bob =   su.initial_vpid_by_desc_glob("a black pawn")?;
159     const DEST: Pos = PosC::new(50, 20);
160
161     {
162       let mut w = su.w(&self.alice)?;
163
164       w.action_chain()
165         .move_pc(&w, &p_alice)?
166         .click()
167
168         .click_and_hold()
169         .move_w(&w, DEST)?
170         .release()
171
172         .perform()
173         .did("alice, drag pawn over target")?;
174       w.synch()?;
175     }
176
177     {
178       let mut w = su.w(&self.bob)?;
179
180       w.action_chain()
181         .move_pc(&w, &p_bob)?
182         .click_and_hold()
183         .move_w(&w, (DEST + PosC::new(2,0))?)?
184         .release()
185         .perform()
186         .did("bob, drag pawn to target")?;
187       w.synch()?;
188     }
189
190     {
191       let mut w = su.w(&self.alice)?;
192
193       w.action_chain()
194         .move_pc(&w, &p_alice)?
195         .click()
196         .perform()
197         .did("alice, drop pawn on target")?;
198       w.synch()?;
199     }
200
201     let mut chk_alice_on_top = |pl|{
202       let mut w = su.w(pl)?;
203       w.synch()?;
204       let pcs = w.pieces()?;
205       let find = |pc| {
206         let vpid = w.piece_vpid(pc).unwrap();
207         pcs.iter().enumerate()
208           .find_map(|(ix, wp)| if wp.piece == vpid { Some(ix) } else { None })
209           .unwrap()
210       };
211       assert!(
212         dbgc!( find(&p_alice) ) > dbgc!( find(&p_bob) )
213       );
214       Ok::<_,AE>(())
215     };
216
217
218     chk_alice_on_top(&self.alice).did("chk alice")?;
219     chk_alice_on_top(&self.bob  ).did("chk bob"  )?;
220   }
221
222   #[throws(Explode)]
223   fn regrab_race(&mut self){
224     let su = &mut self.su;
225     let pawn_vpid = su.initial_vpid_by_desc_glob("a white pawn")?;
226     const MIDHAND: Pos = PosC::new(40, 40);
227     const OUTHAND: Pos = PosC::new(20, 20);
228
229     let bob_gen = {
230       let mut w = su.w(&self.bob)?;
231
232       w.action_chain()
233         
234         .move_pc(&w, &pawn_vpid)?
235         .click_and_hold()
236         .move_w(&w, (MIDHAND + Pos::new(-20,0))?)?
237         .release()
238
239         .move_w(&w, MIDHAND)?
240         .click()
241
242         .send_keys('C')
243
244         .perform()
245         .did("bob, setup")?;
246
247       w.synch()?
248     };
249
250     let alice_gen = {
251       let pauseable = su.otter_pauseable();
252       
253       let mut w = su.w(&self.alice)?;
254       w.synch()?;
255       let pawn = w.find_piece(&pawn_vpid)?;
256       let start = pawn.posw()?;
257
258       let paused = pauseable.pause()?;
259
260       w.action_chain()
261         .move_pos(start)?
262         .click_and_hold()
263         .move_w(&w, OUTHAND)?
264         .release()
265
266         .click()
267
268         .perform()
269         .did("alice, drag out, and re-select")?;
270
271       paused.resume()?;
272
273       w.synch()?
274     };
275
276     for (who, gen) in &[(&self.alice, alice_gen),
277                         (&self.bob,   bob_gen  )] {
278       dbgc!(&who.name);
279       let w = su.w(who)?;
280
281       let held = w.piece_held(&pawn_vpid)?;
282       assert_eq!( held.unwrap(), ALICE );
283
284       let log = w.retrieve_log(*gen)?;
285       assert_eq!( log.find_conflicts(), Vec::<String>::new() );
286     }
287
288     {
289       let mut w = su.w(&self.alice)?;
290       w.action_chain()
291         .click()
292         .perform()
293         .did("alice, ungrasp for tidy up")?;
294       w.synch()?;
295     }
296   }
297 }
298
299 #[throws(Explode)]
300 fn tests(UsualSetup { su, alice, bob, ..}: UsualSetup) {
301   let mut c = Ctx { su, alice, bob };
302
303   test!(c, "claim",       c.claim()       ?);
304   test!(c, "ungrab-race", c.ungrab_race() ?);
305   test!(c, "regrab-race", c.regrab_race() ?);
306
307   debug!("finishing");
308 }
309
310 #[throws(Explode)]
311 pub fn main() { as_usual(tests, module_path!())? }