1extern crate base64;
2
3use serde::{Serialize,Deserialize};
4use super::reqs::*;
5use std::collections::HashMap;
6use self::utils::*;
7use super::element::*;
8use super::actions::*;
9use super::specialkey::*;
10use super::chromeoptions::*;
11use super::firefoxoptions::*;
12use super::safarioptions::*;
13use super::capabilities::*;
14
15#[derive(Serialize,Deserialize)]
16struct Value{
17 value: Session,
18
19}
20#[allow(non_snake_case)]
21#[derive(Serialize,Deserialize)]
22struct Session{
23 sessionId: String,
24}
25
26pub enum BrowserName{
27 Chrome,
28 Firefox,
29 Safari
30}
31#[derive(Debug)]
36pub struct Browser{
37 ip: String,
38 port:String,
39 session_url: String, go_to_url: String, timeouts_url: String,
42 back_url: String,
43 forward_url: String,
44 refresh_url:String,
45 title_url:String,
46 window_url:String,
47 window_handles_url:String,
48 window_new_url:String,
49 window_rect_url:String,
50 frame_url:String,
51 frame_parent_url:String,
52 window_maximize_url:String,
53 window_minimize_url:String,
54 window_fullscreen_url:String,
55 element_url:String,
56 element_active_url:String,
57 elements_url:String,
58 source_url:String,
59 execute_sync_url:String,
60 execute_async_url:String,
61 cookie_url:String,
62 actions_url:String,
63 alert_dismiss_url:String,
64 alert_accept_url:String,
65 alert_text_url:String,
66 screenshot_url:String,
67 print_page_url:String,
68}
69
70impl Browser{
71 pub fn start_session(browser: BrowserName, args:Vec<&str>)->Browser{
82 let req_body = create_session_body_json(browser,args);
83 let response = send_request("127.0.0.1","4444",Method::POST, "wd/hub/session", cont_length_header(&req_body), &req_body).unwrap();
84 let resp_body = resp_body(response).unwrap();
85 let val: Value = serde_json::from_str(&resp_body).unwrap();
86 let sess_id = val.value.sessionId;
87 generate_browser_links("127.0.0.1","4444",&sess_id)
88 }
89 pub fn start_session_with_capabilities(capabilities: Capabilities)->Result<Browser,String>{
111 let body = capabilities.cap_string;
112 let response = send_request("127.0.0.1","4444",Method::POST, "wd/hub/session", cont_length_header(&body), &body).unwrap();
113 let resp_body = resp_body(response).unwrap();
114 let val: Value = serde_json::from_str(&resp_body).unwrap();
115 let sess_id = val.value.sessionId;
116 Ok(generate_browser_links("127.0.0.1","4444",&sess_id))
117 }
118 pub fn start_remote_session_with_capabilities(capabilities: Capabilities,ip:&str,port:&str)->Result<Browser,String>{
120 let body =capabilities.cap_string;
121 let response = send_request(ip,port,Method::POST, "wd/hub/session", cont_length_header(&body), &body).unwrap();
122 let resp_body = resp_body(response).unwrap();
123 let val: Value = serde_json::from_str(&resp_body).unwrap();
124 let sess_id = val.value.sessionId;
125 Ok(generate_browser_links(ip,port,&sess_id))
126 }
127 pub fn start_remote_session(browser: BrowserName,platform:&str,ip:&str,port:&str)->Result<Browser,String>{
129 let browser = match browser{
130 BrowserName::Chrome=>"chrome",
131 BrowserName::Firefox=>"firefox",
132 BrowserName::Safari=>"safari",
133 };
134 let req_body = format!(r#"{{
135 "capabilities": {{
136 "alwaysMatch": {{
137 "platformName": "{}"
138 }},
139 "firstMatch": [
140 {{"browserName": "{}"}}
141 ]
142 }}
143 }}
144 "#,platform,browser);
145 let response = send_request(ip,port,Method::POST, "wd/hub/session", cont_length_header(&req_body), &req_body).unwrap();
146 let resp_body = resp_body(response).unwrap();
147 let val: Value = serde_json::from_str(&resp_body).unwrap();
148 let sess_id = val.value.sessionId;
149 Ok(generate_browser_links(ip,port,&sess_id))
150 }
151 pub fn start_chrome_session_with_options(options:ChromeOptions)->Result<Browser,String>{
167 let body = create_json_body_for_session_with_chrome_options(options);
168 let resp = send_and_read_body ("127.0.0.1","4444",Method::POST, "wd/hub/session", cont_length_header(&body), &body);
169 if resp.contains("error"){return Err(resp);}
170 let val: Value = serde_json::from_str(&resp).unwrap();
171 let sess_id = val.value.sessionId;
172 Ok(generate_browser_links("127.0.0.1","4444",&sess_id))
173 }
174 pub fn start_firefox_session_with_options(options:FirefoxOptions)->Result<Browser,String>{
177 let body = create_json_body_for_session_with_firefox_options(options);
178 let resp = send_and_read_body ("127.0.0.1","4444",Method::POST, "wd/hub/session", cont_length_header(&body), &body);
179 if resp.contains("error"){return Err(resp);}
180 let val: Value = serde_json::from_str(&resp).unwrap();
181 let sess_id = val.value.sessionId;
182 Ok(generate_browser_links("127.0.0.1","4444",&sess_id))
183 }
184 pub fn start_safari_session_with_options(options:SafariOptions)->Result<Browser,String>{
187 let body = create_json_body_for_session_with_safari_options(options);
188 let resp = send_and_read_body("127.0.0.1","4444",Method::POST, "wd/hub/session", cont_length_header(&body), &body);
189 if resp.contains("error"){return Err(resp);}
190 let val: Value = serde_json::from_str(&resp).unwrap();
191 let sess_id = val.value.sessionId;
192 Ok(generate_browser_links("127.0.0.1","4444",&sess_id))
193 }
194 pub fn open(&self,uri:&str)->Result<(),String>{
196 let body = format!(r#"{{"url":"{}"}}"#,uri);
197 let resp = send_request(&self.ip,&self.port,Method::POST, &self.go_to_url, cont_length_header(&body), &body).unwrap();
198 if resp.contains("error"){return Err(resp);}
199 Ok(())
200 }
201 pub fn get_link(&self)->Result<String,String>{
203 let resp = resp_body(send_request(&self.ip,&self.port,Method::GET, &self.go_to_url, vec![], "").unwrap()).unwrap();
204 if resp.contains("error"){return Err(resp);}
205 Ok(parse_value(&resp).replace("\"",""))
206 }
207 pub fn close_browser(&mut self)->Result<(),String>{
210 let resp = send_request(&self.ip,&self.port,Method::DELETE, &self.session_url, vec![], "").unwrap();
211 if resp.contains("error"){return Err(resp);}
212 self.session_url = String::from("");
213 Ok(())
214 }
215 pub fn get_timeouts(&self)->Result<Timeouts,String>{
217 let resp = send_and_read_body(&self.ip,&self.port,Method::GET, &self.timeouts_url, vec![], "");
218 if resp.contains("error"){return Err(resp);}
219 Ok(serde_json::from_str(&parse_value(&resp)).unwrap())
220 }
221 pub fn set_timeouts(&self, timeouts: &Timeouts)->Result<(),&str>{
223 let timeouts_json = serde_json::to_string(timeouts).unwrap();
224 if let Ok(mess)= send_request(&self.ip,&self.port,Method::POST, &self.timeouts_url, cont_length_header(&timeouts_json), &timeouts_json){
225 if let Ok (body) = resp_body(mess){
226 if body.as_str() == r#"{"value":null}"#{
227 return Ok(())
228 }
229 }
230 }
231 Err("The timeouts were not set correctly")
232 }
233 pub fn back(&self)->Result<(),String>{
235 let body = r#"{"return":true}"#;
236 let resp = send_request(&self.ip,&self.port,Method::POST,&self.back_url, cont_length_header(&body), &body).unwrap();
237 if resp.contains("error"){return Err(resp);}
238 Ok(())
239 }
240 pub fn forward(&self)->Result<(),String>{
241 let body = r#"{"forward":true}"#;
242 let resp = send_request(&self.ip,&self.port,Method::POST,&self.forward_url, cont_length_header(&body), &body).unwrap();
243 if resp.contains("error"){return Err(resp);}
244 Ok(())
245 }
246 pub fn refresh(&self)->Result<(),&str>{
247 let body = r#"{"refresh":true}"#;
248 if let Ok (mess) = send_request(&self.ip,&self.port,Method::POST,&self.refresh_url, cont_length_header(&body), &body){
249 if let Ok (body) = resp_body(mess){
250 if body.as_str()!=r#"{"value":null}"#{
251 return Err("The refresh did not succeed")
252 }
253 }
254 }
255 Ok(())
256 }
257 pub fn get_title(&self)->Result<String,String>{
259 let json = resp_body(send_request(&self.ip,&self.port,Method::GET, &self.title_url, vec![], "").unwrap()).unwrap();
260 if json.contains("error"){return Err(json);}
261 Ok(parse_value(&json).replace("\"",""))
262 }
263 pub fn get_window_handle(&self)->Result<String,String>{
265 let resp = send_and_read_body(&self.ip,&self.port,Method::GET, &self.window_url, vec![], "");
266 if resp.contains("error"){return Err(resp);}
267 Ok(parse_value(&resp).replace("\"",""))
268 }
269 pub fn get_window_handles(&self)->Result<Vec<String>,String>{
271 let resp = send_and_read_body(&self.ip,&self.port,Method::GET, &self.window_handles_url, vec![], "");
272 if resp.contains("error"){return Err(resp);}
273 let resp = parse_value(&resp);
274 let res:Vec<String> = serde_json::from_str(&resp).unwrap();
275 Ok(res)
276 }
277 pub fn switch_to_window(&self, window_id: String)->Result<(),String>{
279 let body = format!(r#"{{"handle":"{}"}}"#,window_id);
280 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.window_url, cont_length_header(&body), &body);
281 if resp.as_str()==r#"{"value":null}"#{
282 Ok(())
283 }else{Err(resp)}
284 }
285 pub fn new_window(&self, window_type: NewWindowType)->Result<(String,String),String>{
287 let body = match window_type{
288 NewWindowType::Tab=>r#"{"type":"tab"}"#,
289 NewWindowType::Window=>r#"{"type":"window"}"#,
290 };
291 let resp=send_and_read_body(&self.ip,&self.port,Method::POST, &self.window_new_url, cont_length_header(&body), &body);
292 if resp.contains("error"){return Err(resp);}
293 let resp = parse_value(&resp);
294 let map: HashMap<&str,String> = serde_json::from_str(&resp).unwrap();
295 let handle = map.get("handle").unwrap().clone();
296 let wtype = map.get("type").unwrap().clone();
297 Ok((handle,wtype))
298 }
299 pub fn close_window(&self)->Result<Vec<String>,String>{
301 let resp = send_and_read_body(&self.ip,&self.port,Method::DELETE, &self.window_url, vec![], "");
302 if resp.contains("error"){return Err(resp);}
303 let resp = parse_value(&resp);
304 let res:Vec<String> = serde_json::from_str(&resp).unwrap();
305 Ok(res)
306 }
307 pub fn switch_to_frame_by_id(&self, id: u64)->Result<(),String>{
310 let body = format!(r#"{{"id":{}}}"#,id);
311 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.frame_url, cont_length_header(&body), &body);
312 if resp.as_str()!=r#"{"value":null}"#{
313 return Err(resp);
314 }
315 Ok(())
316 }
317 pub fn switch_to_frame_by_element(&self, element:Element)->Result<(),String>{
318 let body = format!(r#"{{"id":{{"{}":"{}"}}}}"#,element.element_gr_id,element.element_id);
319 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.frame_url, cont_length_header(&body), &body);
320 if resp.as_str()!=r#"{"value":null}"#{
321 return Err(resp);
322 }
323 Ok(())
324
325 }
326 pub fn switch_to_parent_frame(&self)->Result<(),String>{
327 let body = r#"{}"#;
328 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.frame_parent_url, cont_length_header(&body), &body);
329 if resp.as_str()!=r#"{"value":null}"#{
330 return Err(resp);
331 }
332 Ok(())
333 }
334 pub fn get_active_element(&self)->Result<Element,String>{
335 let resp = send_and_read_body(&self.ip,&self.port,Method::GET, &self.element_active_url, vec![], "");
336 if resp.contains("error"){return Err(resp);}
337 let resp = parse_value(&resp);
338 let map: HashMap<String,String> = serde_json::from_str(&resp).unwrap();
339 let res = map.iter().next().unwrap();
340 Ok(Element{
341 ip:self.ip.clone(),
342 port: self.port.clone(),
343 element_gr_id:res.0.clone(),
344 element_id:res.1.clone(),
345 element_url: format!("{}/element/{}",self.session_url,res.1.clone()),
346 })
347 }
348 pub fn find_element(&self,loc_strategy:LocatorStrategy)->Result<Element,String>{
362 let body = body_for_find_element(loc_strategy);
363 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.element_url, cont_length_header(&body), &body);
364 if resp.contains("error"){return Err(resp);}
365 let resp = parse_value(&resp);
366 let map: HashMap<String,String> = serde_json::from_str(&resp).unwrap();
367 let res = map.iter().next().unwrap();
368 Ok(Element{
369 ip:self.ip.clone(),
370 port: self.port.clone(),
371 element_gr_id:res.0.clone(),
372 element_id:res.1.clone(),
373 element_url: format!("{}/element/{}",self.session_url,res.1.clone()),
374 })
375 }
376 pub fn find_elements(&self,loc_strategy:LocatorStrategy)->Result<Vec<Element>,String>{
377 let mut result = vec![];
378 let body = body_for_find_element(loc_strategy);
379 let resp=send_and_read_body(&self.ip,&self.port,Method::POST, &self.elements_url, cont_length_header(&body), &body);
380 if resp.contains("error"){return Err(resp);}
381 let resp = parse_value(&resp);
382 let map: Vec<HashMap<String,String>> = serde_json::from_str(&resp).unwrap();
383 let element_ur = format!("{}/element",self.session_url);
384 for i in map{
385 let element_ur = element_ur.clone();
386 let res = i.iter().next().unwrap();
387 result.push(Element{
388 ip:self.ip.clone(),
389 port: self.port.clone(),
390 element_gr_id:res.0.clone(),
391 element_id:res.1.clone(),
392 element_url:format!("{}/{}",element_ur,res.1.clone()),
393 });
394 }
395 Ok(result)
396 }
397 pub fn get_window_rect(&self)->Result<WindowRect,String>{
399 let resp = send_and_read_body(&self.ip,&self.port,Method::GET, &self.window_rect_url, vec![], "");
400 if resp.contains("error"){return Err(resp);}
401 let map:HashMap<&str,WindowRect> = serde_json::from_str(&resp).unwrap();
402 Ok(map.get("value").unwrap().clone())
403 }
404 pub fn set_sindow_rect(&self, window_rect:&WindowRect)->Result<WindowRect,String>{
406 let body = serde_json::to_string(window_rect).unwrap();
407 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.window_rect_url, cont_length_header(&body), &body);
408 let resp = parse_value(&resp);
409 let map:Result<WindowRect,serde_json::Error> = serde_json::from_str(&resp);
410 match map{
411 Ok(cont)=>{
412 Ok(cont)
413 },
414 Err(message)=>Err(message.to_string()),
415 }
416
417 }
418 pub fn maximize_window(&self)->Result<WindowRect,String>{
419 let body = r#"{}"#;
420 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.window_maximize_url, cont_length_header(&body), &body);
421 let resp = parse_value(&resp);
422 if resp.contains("height")&&resp.contains("width"){
423 let res: WindowRect = serde_json::from_str(&resp).unwrap();
424 Ok(res)
425 }else{Err(resp)}
426
427 }
428 pub fn minimize_window(&self)->Result<WindowRect,String>{
429 let body = r#"{}"#;
430 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.window_minimize_url, cont_length_header(&body), &body);
431 let resp = parse_value(&resp);
432 if resp.contains("height")&&resp.contains("width"){
433 let res: WindowRect = serde_json::from_str(&resp).unwrap();
434 Ok(res)
435 }else{Err(resp)}
436 }
437 pub fn fullscreen(&self)->Result<WindowRect,String>{
438 let body = r#"{}"#;
439 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.window_fullscreen_url, cont_length_header(&body), &body);
440 let resp = parse_value(&resp);
441 if resp.contains("height"){
442 Ok(serde_json::from_str(&resp).unwrap())
443 } else {Err(resp)}
444 }
445 pub fn source(&self)->Result<String,String>{
447 let resp = send_and_read_body(&self.ip,&self.port,Method::GET, &self.source_url, vec![], "");
448 if resp.contains("error"){return Err(resp);}
449 let map:HashMap<&str,String> = serde_json::from_str(&resp).unwrap();
450 Ok(map.get("value").unwrap().clone())
451 }
452 pub fn get_all_cookies(&self)->Result<Vec<Cookie>,String>{
454 let mut result: Vec<Cookie> = vec![];
455 let resp = send_and_read_body(&self.ip,&self.port,Method::GET, &self.cookie_url, vec![], "");
456 if resp.contains("error"){return Err(resp);}
457 let map:HashMap<&str,Vec<serde_json::Value>> = serde_json::from_str(&resp).unwrap();
458 for v in map.get("value").unwrap(){
459 result.push(from_value_to_cookie(v));
460 }
461 Ok(result)
462 }
463 pub fn get_cookie(&self,cookie_name:&str)->Result<Cookie,String>{
465 let url = format!("{}/{}",self.cookie_url,cookie_name);
466 let resp = send_and_read_body(&self.ip,&self.port,Method::GET, &url, vec![], "");
467 if resp.contains("domain")&&resp.contains("expiry")&&resp.contains("name"){
468 let map:HashMap<&str,serde_json::Value> = serde_json::from_str(&resp).unwrap();
469 let v = map.get(&"value").unwrap();
470 return Ok(from_value_to_cookie(v));
471 }
472 Err(resp)
473 }
474 pub fn add_cookie(&self,cookie:Cookie)->Result<(),String>{
475 let cook = serde_json::to_string(&cookie).unwrap();
476 let body =format!(r#"{{"cookie": {} }}"#,cook);
477 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.cookie_url, cont_length_header(&body), &body);
478 if resp==r#"{"value":null}"#{
479 return Ok(());
480 }
481 Err(resp)
482 }
483 pub fn delete_cookie(&self,cookie_name:&str)->Result<(),String>{
484 let uri = format!("{}/{}",self.cookie_url,cookie_name);
485 let resp = send_and_read_body(&self.ip,&self.port,Method::DELETE, &uri, vec![], "");
486 if resp==r#"{"value":null}"#{
487 return Ok(());
488 }
489 Err(resp)
490 }
491 pub fn delete_all_cookies(&self)->Result<(),String>{
492 let resp = send_and_read_body(&self.ip,&self.port,Method::DELETE, &self.cookie_url, vec![], "");
493 if resp==r#"{"value":null}"#{
494 return Ok(());
495 }
496 Err(resp)
497 }
498 pub fn take_screenshot(&self,path:&str)->Result<(),String>{
510 if let Ok(resp) = send_request_screensh(Method::GET, &self.screenshot_url, vec![], ""){
511 if let Ok(new) = base64::decode(resp){
512 match std::fs::write(path,new){
513 Ok(())=>return Ok(()),
514 Err(message)=> return Err(message.to_string()),
515 }
516 }
517 }
518 Err(String::from("Could not take a screenshot"))
519 }
520 pub fn take_element_screenshot(&self,elem:&Element,path: &str)->Result<(),String>{
521 let uri = format!("{}/{}/screenshot",self.element_url,elem.element_id);
522 if let Ok(resp) = send_request_screensh(Method::GET, &uri, vec![], ""){
523 if let Ok(new) = base64::decode(resp){
524 match std::fs::write(path,new){
525 Ok(())=>return Ok(()),
526 Err(message)=>return Err(message.to_string())
527 }
528 }
529 }
530 Err(String::from("Could not take a screenshot"))
531 }
532 pub fn execute_sync(&self, script: &str, args: &Vec<&str>)->Result<String,String>{
535 let args = gen_script_args(args);
536 let body = format!(r#"{{"script":"{}","args":{}}}"#,script,args);
537 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.execute_sync_url, cont_length_header(&body), &body);
538 if resp.contains("error"){
539 return Err(resp);
540 }
541 Ok(resp)
542 }
543 pub fn execute_async(&self, script: &str, args: &Vec<&str>)->Result<String,String>{
545 let args = gen_script_args(args);
546 let body = format!(r#"{{"script":"{}","args":{}}}"#,script,args);
547 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.execute_async_url, cont_length_header(&body), &body);
548 if resp.contains("error"){
549 return Err(resp);
550 }
551 Ok(resp)
552 }
553 pub fn print(&self,print_settings:&PrintSettings,path:&str)->Result<(),String>{
555 let pr_set_body = serde_json::to_string(&print_settings).unwrap();
556 let resp = send_request_screensh(Method::POST, &self.print_page_url, cont_length_header(&pr_set_body), &pr_set_body).unwrap();
557 let new = base64::decode(resp).unwrap();
558 std::fs::write(path,new).unwrap();
559 Ok(())
560 }
561
562}
563
564impl Browser{
565 pub fn dismiss_alert(&self)->Result<(),String>{
566 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.alert_dismiss_url, cont_length_header("{}"), "{}");
567 if resp ==r#"{"value":null}"#{Ok(())}else{Err(resp)}
568 }
569 pub fn allow_alert(&self)->Result<(),String>{
570 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.alert_accept_url, cont_length_header("{}"), "{}");
571 if resp ==r#"{"value":null}"#{Ok(())}else{Err(resp)}
572 }
573 pub fn get_alert_text(&self)->Result<String,String>{
574 let resp = send_and_read_body(&self.ip,&self.port,Method::GET, &self.alert_text_url, vec![], "");
575 if resp.contains("error"){return Err(resp);}
576 let map:HashMap<&str,String> = serde_json::from_str(&resp).unwrap();
577 Ok((*map.get("value").unwrap()).to_string())
578 }
579 pub fn send_alert_text(&self,text:&str)->Result<(),String>{
580 let body =format!(r#"{{"text":{}}}"#,text) ;
581 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.alert_dismiss_url, cont_length_header(&body), &body);
582 if resp.contains("error"){return Err(resp);}
583 Ok(())
584 }
585 pub fn perform_actions(&self,actions:Actions)->Result<(),String>{
601 let mut actions = actions;
602 actions.set_ids();
603 let body = serde_json::to_string(&actions).unwrap();
604 let resp = send_and_read_body(&self.ip,&self.port,Method::POST, &self.actions_url, cont_length_header(&body), &body);
605 if resp.contains("error"){return Err(resp);}
606 Ok(())
607 }
608 pub fn release_actions(&self)->Result<(),String>{
612 let resp = send_and_read_body(&self.ip,&self.port,Method::DELETE, &self.actions_url, vec![], "");
613 if resp.contains("error"){return Err(resp);}
614 Ok(())
615 }
616}
617pub (self) mod utils{
618 use super::*;
619 pub (super) fn generate_browser_links(ip:&str,port:&str,sess_id:&str)->Browser{
620 Browser{
621 port:String::from(port),
622 ip:String::from(ip),
623 session_url:format!("wd/hub/session/{}",sess_id),
624 go_to_url: format!("wd/hub/session/{}/url",sess_id),
625 timeouts_url: format!("wd/hub/session/{}/timeouts",sess_id),
626 back_url: format!("wd/hub/session/{}/back",sess_id),
627 forward_url: format!("wd/hub/session/{}/forward",sess_id),
628 refresh_url:format!("wd/hub/session/{}/refresh",sess_id),
629 title_url:format!("wd/hub/session/{}/title",sess_id),
630 window_url:format!("wd/hub/session/{}/window",sess_id),
631 window_handles_url:format!("wd/hub/session/{}/window/handles",sess_id),
632 window_new_url:format!("wd/hub/session/{}/window/new",sess_id),
633 window_rect_url:format!("wd/hub/session/{}/window/rect",sess_id),
634 frame_url:format!("wd/hub/session/{}/frame",sess_id),
635 frame_parent_url:format!("wd/hub/session/{}/frame/parent",sess_id),
636 window_maximize_url:format!("wd/hub/session/{}/window/maximize",sess_id),
637 window_minimize_url:format!("wd/hub/session/{}/window/minimize",sess_id),
638 window_fullscreen_url:format!("wd/hub/session/{}/window/fullscreen",sess_id),
639 element_url:format!("wd/hub/session/{}/element",sess_id),
640 element_active_url:format!("wd/hub/session/{}/element/active",sess_id),
641 elements_url:format!("wd/hub/session/{}/elements",sess_id),
642 source_url:format!("wd/hub/session/{}/source",sess_id),
643 execute_sync_url:format!("wd/hub/session/{}/execute/sync",sess_id),
644 execute_async_url:format!("wd/hub/session/{}/execute/async",sess_id),
645 cookie_url:format!("wd/hub/session/{}/cookie",sess_id),
646 actions_url:format!("wd/hub/session/{}/actions",sess_id),
647 alert_dismiss_url:format!("wd/hub/session/{}/alert/dismiss",sess_id),
648 alert_accept_url:format!("wd/hub/session/{}/alert/accept",sess_id),
649 alert_text_url:format!("wd/hub/session/{}/alert/text",sess_id),
650 screenshot_url:format!("wd/hub/session/{}/screenshot",sess_id),
651 print_page_url:format!("wd/hub/session/{}/print",sess_id),
652 }
653 }
654 pub (super) fn create_session_body_json(browser:BrowserName,args:Vec<&str>)->String{
655 match browser{
656 BrowserName::Chrome=> create_chrome_session(args),
657 BrowserName::Firefox=>create_firefox_session(),
658 BrowserName::Safari=>create_safari_session(),
659 }
660 }
661 pub (super) fn create_chrome_session(args:Vec<&str>)->String{
662 let one=format!(r#"{{"capabilities": {{"alwaysMatch":{{"platformName":"{}"}}"#,std::env::consts::OS);
663 let args = gen_args(args);
664 let two=format!(r#"{},"firstMatch":[{{"browserName":"chrome","goog:chromeOptions":{{"args":{}}}}}]}}}}"#,one,args);
665 two
666 }
667 pub (super) fn create_firefox_session()->String{
668 let one=format!(r#"{{"capabilities": {{"alwaysMatch":{{"platformName":"{}"}}"#,std::env::consts::OS);
669 let two=format!(r#"{},"firstMatch":[{{"browserName":"firefox"}}]}}}}"#,one);
670 two
671 }
672 pub (super) fn create_safari_session()->String{
673 let one=format!(r#"{{"capabilities": {{"alwaysMatch":{{"platformName":"{}"}}"#,std::env::consts::OS);
674 let two=format!(r#"{},"firstMatch":[{{"browserName":"safari"}}]}}}}"#,one);
675 two
676 }
677 pub (super) fn create_json_body_for_session_with_chrome_options(chrome_options:ChromeOptions)->String{
678 let mut options = chrome_options.string_for_session;
679 options.pop();
680 options.pop();
681 options.push('}');
682 let base_string = format!(r#"{{
683 "capabilities": {{
684 "alwaysMatch": {{
685 "platformName": "{}"
686 }},
687 "firstMatch": [
688 {{"browserName": "chrome",
689 {}
690 }}
691 ]
692 }}
693 }}"#,std::env::consts::OS,options);
694 base_string
695 }
696 pub (super) fn create_json_body_for_session_with_firefox_options(ff_options:FirefoxOptions)->String{
697 let mut options = ff_options.string_for_session;
698 options.pop();
699 options.pop();
700 options.push('}');
701 let base_string = format!(r#"{{
702 "capabilities": {{
703 "alwaysMatch": {{
704 "platformName": "{}"
705 }},
706 "firstMatch": [
707 {{"browserName": "firefox",
708 {}
709 }}
710 ]
711 }}
712 }}"#,std::env::consts::OS,options);
713 base_string
714 }
715 pub (super) fn create_json_body_for_session_with_safari_options(saf_options:SafariOptions)->String{
716 let base_string = format!(r#"
717 {{
718 "capabilities":{{
719 "alwaysMatch":
720 {{
721 "platformName":"{}",
722 "browserName":"safari",
723 {}
724 }}
725 }}
726 }}"#,std::env::consts::OS,saf_options.base_string);
727 base_string
728 }
729 pub (super) fn gen_args(args:Vec<&str>)->String{
730 if args.len()==0{
731 return String::from("[]");
732 }
733 let mut result = String::from("[");
734 for arg in args{
735 result.push_str("\"");
736 result.push_str(arg);
737 result.push_str("\"");
738 result.push_str(",");
739 }
740 result.pop();
741 result.push_str("]");
742 result
743 }
744 pub (super) fn gen_script_args(args:&Vec<&str>)->String{
745 if args.len()==0{
746 return String::from("[]");
747 }
748 let mut result = String::from("[");
749 let temp_result = args.join(",");
750 result.push_str(&temp_result);
751 result.push_str("]");
752 result
753 }
754 pub (super) fn from_value_to_cookie(val: &serde_json::Value)->Cookie{
755 let name = String::from(val["name"].as_str().unwrap());
756 let value = String::from(val["value"].as_str().unwrap());
757 let mut domain = String::from("");
758 let mut expiry = 0;
759 let mut http_only = false;
760 let mut path = String::from("");
761 let mut secure = false;
762 let mut same_site = String::from("");
763 if let Some(dom) = val["domain"].as_str(){
764 domain=String::from(dom);
765 }
766 if let Some(exp) = val["expiry"].as_u64(){
767 expiry=exp;
768 }
769 if let Some(http) = val["httpOnly"].as_bool(){
770 http_only=http;
771 }
772 if let Some(pat) = val["path"].as_str(){
773 path=String::from(pat);
774 }
775 if let Some(sec) = val["secure"].as_bool(){
776 secure = sec;
777 }
778 if let Some(same) = val["sameSite"].as_str(){
779 same_site=String::from(same);
780 }
781 Cookie{name,value,path,expiry,secure,domain,httpOnly: http_only,sameSite:same_site}
782 }
783}
784
785pub enum NewWindowType{
787 Tab,
788 Window
789}
790#[derive(Serialize,Deserialize,Debug,PartialEq,Clone)]
792pub struct WindowRect{
793 pub(self)height:i32,
794 pub(self)width:i32,
795 pub(self)x:i32,
796 pub(self)y:i32
797}
798impl WindowRect{
799 pub fn new(height:i32,width:i32,x:i32,y:i32)->WindowRect{
800 WindowRect{ height, width, x, y}
801 }
802}
803#[allow(non_snake_case)]
807#[derive(Serialize,Deserialize,Debug,Clone)]
808pub struct Cookie{
809 pub(self)domain:String,
810 pub(self)expiry: u64,
811 pub(self)httpOnly:bool,
812 pub(self)name:String,
813 pub(self)path:String,
814 pub(self)secure:bool,
815 pub(self)value:String,
816 pub(self)sameSite:String,
817}
818
819impl Cookie{
820 pub fn new_all(domain:String, expiry:u64,same_site:String, http_only:bool,name:String,path:String,secure:bool,value:String)->Self{
822 Cookie{
823 domain,
824 expiry,
825 httpOnly: http_only,
826 name,
827 path,
828 sameSite:same_site,
829 secure,
830 value
831 }
832 }
833 pub fn new(name:String,value:String)->Self{
835 Cookie{name,value,..Default::default()}
836 }
837
838 pub fn get_domain(&self)->String{self.domain.clone()}
839 pub fn get_expiry(&self)->u64{self.expiry}
840 pub fn get_http_only(&self)->bool{self.httpOnly}
841 pub fn get_name(&self)->String{self.name.clone()}
842 pub fn get_path(&self)->String{self.path.clone()}
843 pub fn get_secure(&self)->bool{self.secure}
844 pub fn get_value(&self)->String{self.value.clone()}
845 pub fn get_same_site(&self)->String{self.sameSite.clone()}
846
847
848 pub fn set_domain(&mut self, domain:String){self.domain=domain;}
849 pub fn set_expiry(&mut self, expiry: u64){self.expiry=expiry;}
850 pub fn set_http_only(&mut self, http_only:bool){self.httpOnly=http_only;}
851 pub fn set_path(&mut self, path: String){self.path=path;}
852 pub fn set_secure(&mut self, secure: bool){self.secure=secure;}
853 pub fn set_same_site(&mut self, same_site:String){self.sameSite=same_site;}
854}
855impl Default for Cookie{
856 fn default()->Self{
857 Cookie{
858 domain:"".to_string(),
859 expiry: 0,
860 httpOnly: false,
861 name:"".to_string(),
862 path:"".to_string(),
863 secure:false,
864 value:"".to_string(),
865 sameSite:"None".to_string(),
866 }
867 }
868}
869#[allow(non_snake_case)]
871#[derive(Serialize,Deserialize,Debug,PartialEq)]
872pub struct Timeouts{
873 implicit:u32,
874 pageLoad:u32,
875 script:u32,
876}
877impl Timeouts{
878 pub fn set_all (implicit: u32, page_load: u32,script:u32)->Timeouts{
880 Timeouts{
881 implicit,
882 pageLoad: page_load,
883 script
884 }
885 }
886 pub fn new ()->Timeouts{
888 Timeouts{
889 implicit:0,
890 pageLoad: 300000,
891 script: 30000,
892 }
893 }
894 pub fn set_implicit(&mut self,implicit:u32){
895 self.implicit=implicit;
896 }
897 pub fn set_page_load(&mut self,page_load:u32){
898 self.pageLoad=page_load;
899 }
900 pub fn set_script(&mut self,script:u32){
901 self.script=script;
902 }
903
904}
905#[allow(non_snake_case)]
909#[derive(Serialize,Deserialize,Debug)]
910pub struct PrintSettings{
911 orientation:String,
912 scale: f32,
913 background: bool,
914 page: Page,
915 margin: Margin,
916 shrinkToFit: bool,
917 pages: Vec<u32>
918}
919impl PrintSettings{
920 pub fn new(orientation: Orientation,scale: f32,background:bool,page:Page,margin:Margin,shrink_tf:bool,pages:Vec<u32>)->Self{
921 if scale<0.1||scale>2.0{panic!("The condotion (0.1<=scale<= 2.0) is not fulfilled");}
922 let orientation = match orientation{
923 Orientation::PORTRAIT=>String::from("portrait"),
924 Orientation::LANDSCAPE=>String::from("landscape"),
925 };
926 PrintSettings{orientation,scale,background,page,margin,shrinkToFit: shrink_tf,pages}
927 }
928 pub fn set_orientation(&mut self,orientation: Orientation){
929 self.orientation = match orientation{
930 Orientation::PORTRAIT=>String::from("portrait"),
931 Orientation::LANDSCAPE=>String::from("landscape"),
932 };
933 }
934 pub fn set_scale(&mut self,scale:f32){
936 if scale<0.1||scale>2.0{panic!("The condotion (0.1<=scale<= 2.0) is not fulfilled");}
937 self.scale=scale;}
938 pub fn set_background(&mut self,background: bool){self.background=background;}
940 pub fn set_page(&mut self,page:Page){self.page=page;}
941 pub fn set_margin(&mut self,margin:Margin){self.margin=margin;}
942 pub fn set_shrink_to_fit(&mut self,shr_to_fit:bool){self.shrinkToFit = shr_to_fit;}
944 pub fn set_pages(&mut self,pages:Vec<u32>){self.pages=pages;}
946}
947
948impl Default for PrintSettings{
949 fn default()->Self{
950 PrintSettings{
951 orientation:String::from("portrait"),
952 scale: 1.0,
953 background: false,
954 page: Page::default(),
955 margin: Margin::default(),
956 shrinkToFit: true,
957 pages: vec![]
958 }
959 }
960}
961#[derive(Serialize,Deserialize,Debug)]
965pub struct Page{
966 width:f32,
967 height:f32,
968}
969impl Page{
970 pub fn new(width:f32, height: f32)->Self{
971 if width<0.0||height<0.0{panic!("Width and height can't be less then 0.0");}
972 Page{width,height}
973 }
974 pub fn set_width(&mut self,width:f32){
975 if width<0.0{panic!("Width cannot be less then 0.0");}
976 self.width = width;
977 }
978 pub fn set_height(&mut self,height:f32){
979 if height<0.0{panic!("Height cannot be less then 0.0");}
980 self.height = height;
981 }
982}
983impl Default for Page{
984 fn default()->Self{
985 Page{width:21.59,height:27.94}
986 }
987}
988#[derive(Serialize,Deserialize,Debug)]
992pub struct Margin{
993 top:u32,
994 bottom:u32,
995 left:u32,
996 right:u32,
997}
998impl Margin{
999 pub fn new(top:u32,bottom:u32,left:u32,right:u32)->Self{
1000 Margin{
1001 top,bottom,left,right
1002 }
1003 }
1004 pub fn set_top(&mut self,top:u32){self.top=top;}
1005 pub fn set_bottom(&mut self,bottom:u32){self.bottom=bottom}
1006 pub fn set_left(&mut self,left:u32){self.left=left;}
1007 pub fn set_right(&mut self,right:u32){self.right=right;}
1008}
1009impl Default for Margin{
1010 fn default()->Self{
1011 Margin{
1012 top:1,
1013 bottom:1,
1014 left:1,
1015 right:1,
1016 }
1017 }
1018}
1019pub enum Orientation{
1021 PORTRAIT,
1022 LANDSCAPE
1023}
1024
1025mod core_fns_tests{
1027
1028 use super::*;
1029 use super::Element;
1030 use std::env::*;
1031 #[test]
1032 fn create_session() {
1033 let mut browser = Browser::start_session(BrowserName::Chrome,vec!["--headless"]);
1034 let sess:String;
1035 {let mut iter = browser.session_url.split("/");
1036 iter.next();
1037 iter.next();
1038 iter.next();
1039 sess = iter.next().unwrap().to_string();}
1040 browser.close_browser().unwrap();
1041
1042 assert_eq!(32,sess.len());
1043 }
1044 #[test]
1045 fn go_to_vk() {
1046 let mut browser = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1047 browser.open("https://vk.com").unwrap();
1048 let link = browser.get_link().unwrap();
1049 browser.close_browser().unwrap();
1050 assert_eq!(link,"https://vk.com/");
1051 }
1052 #[test]
1053 #[should_panic]
1054 fn close_browser() {
1055 let mut browser = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1056 browser.open("http://localhost:4444/wd/hub/status").unwrap();
1057 browser.close_browser().unwrap();
1058 let a = browser.get_link().unwrap();
1059 if a.contains("invalid"){panic!("Invalid session id");}
1060 }
1061 #[test]
1062 fn args() {
1063 let a = vec!["--headless","--window-size=800,400"];
1064 assert!(gen_args(a)==String::from("[\"--headless\",\"--window-size=800,400\"]"));
1065 }
1066 #[test]
1067 fn get_timeouts() {
1068 let timeouts:Timeouts;
1069 {
1070 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1071 timeouts= br.get_timeouts().unwrap();
1072 br.close_browser().unwrap();
1073 }
1074 assert!(timeouts.implicit==0&&timeouts.script==30000);
1075 }
1076 #[test]
1077 fn set_timeouts() {
1078 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1079 let timeouts = Timeouts::set_all(1000, 3000, 300000);
1080 assert!(br.set_timeouts(&timeouts)==Ok(()));
1081 br.close_browser().unwrap();
1082 }
1083 #[test]
1084 fn check_timouts_init() {
1085 let mut t = Timeouts::new();
1086 assert_eq!(t,Timeouts{implicit:0,pageLoad:300000,script:30000});
1087 t.set_implicit(1);
1088 assert_eq!(t,Timeouts{implicit:1,pageLoad:300000,script:30000});
1089 t.set_page_load(1);
1090 assert_eq!(t,Timeouts{implicit:1,pageLoad:1,script:30000});
1091 t.set_script(1);
1092 assert_eq!(t,Timeouts{implicit:1,pageLoad:1,script:1});
1093 }
1094 #[test]
1095 fn back_test() {
1096 let link: String;
1097 {let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1098 br.open("https://vk.com/").unwrap();
1099 br.open("https://m.facebook.com/").unwrap();
1100 br.back().unwrap();
1101 link = br.get_link().unwrap();
1102 br.close_browser().unwrap();}
1103 assert_eq!(link.as_str(),"https://vk.com/");
1104 }
1105 #[test]
1106 fn forward_test() {
1107 let link: String;
1108 {let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1109 br.open("https://vk.com/").unwrap();
1110 br.open("https://m.facebook.com/").unwrap();
1111 br.back().unwrap();
1112 br.forward().unwrap();
1113 link = br.get_link().unwrap();
1114 br.close_browser().unwrap();}
1115 assert_eq!(&link,"https://m.facebook.com/");
1116 }
1117 #[test]
1118 fn refresh_test() {
1119 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1120 br.open("https://vk.com/").unwrap();
1121 assert_eq!(br.refresh(),Ok(()));
1122 br.close_browser().unwrap();
1123 }
1124 #[test]
1125 fn get_title_test() {
1126 let title:String;
1127 {let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1128 br.open("https://www.w3.org/TR/webdriver/").unwrap();
1129 title =br.get_title().unwrap();
1130 br.close_browser().unwrap();}
1131 assert_eq!(title,String::from("WebDriver"));
1132
1133 }
1134 #[test]
1135 fn window_handle() {
1136 let handle: String;
1137 {let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1138 br.open("https://vk.com").unwrap();
1139 handle = br.get_window_handle().unwrap();
1140 br.close_browser().unwrap();}
1141 assert!(handle.starts_with("CDwindow"));
1142
1143 }
1144 #[test]
1145 fn switch_window(){
1146 let res :Result<(),String>;
1147 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1148 br.open("https://vk.com").unwrap();
1149 let handle = br.get_window_handle().unwrap();
1150 res = br.switch_to_window(handle);assert_eq!(Ok(()),res);
1151 br.close_browser().unwrap();
1152 }
1153 #[test]
1154 fn get_handles() {
1155 let handles;
1156 {
1157 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1158 br.open("https://vk.com").unwrap();
1159 handles = br.get_window_handles();
1160 br.close_browser().unwrap();
1161 }
1162 let len = handles.unwrap().len();
1163 assert_eq!(len,1);
1164 }
1165 #[test]
1166 fn close_window() {
1167 let handles;
1168 {
1169 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1170 br.open("https://vk.com").unwrap();
1171 handles = br.close_window();
1172 br.close_browser().unwrap();
1173 }
1174 assert_eq!(handles.unwrap().len(),0);
1175 }
1176 #[test]
1177 fn new_window(){
1178 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1179 let wind = br.new_window(NewWindowType::Tab).unwrap();
1180 assert!(wind.1=="tab"&&br.get_window_handles().unwrap().len()==2);
1181 br.close_browser().unwrap();
1182 }
1183 #[test]
1184 fn sw_to_frame_by_id() {
1185 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1186 br.open("https://bash.im").unwrap();
1187 let res = br.switch_to_frame_by_id(0);
1188 br.close_browser().unwrap();
1189 assert_eq!(res,Ok(()));
1190
1191 }
1192 #[test]
1193 fn sw_t_fr_by_el() {
1194 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1195 br.open("https://vk.com").unwrap();
1196 let el = br.find_element(LocatorStrategy::CSS("#quick_login_frame")).unwrap();
1197 let res = br.switch_to_frame_by_element(el);
1198 br.close_browser().unwrap();
1199 assert_eq!(res,Ok(()));
1200 }
1201 #[test]
1202 fn find_element() {
1203 let el;
1204 {
1205 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1206 br.open("https://vk.com").unwrap();
1207 el = br.find_element(LocatorStrategy::CSS("#ts_input")).unwrap();
1208 br.close_browser().unwrap();
1209 }
1210 let tr =el.element_gr_id.contains("element");
1211 assert!(tr);
1212 }
1213 #[test]
1214 fn find_els() {
1215 let el;
1216 {
1217 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1218 br.open("https://vk.com").unwrap();
1219 el = br.find_elements(LocatorStrategy::CSS("div")).unwrap();
1220 br.close_browser().unwrap();
1221 }
1222 let len = el.len();
1223 assert!(len>2);
1224 }
1225 #[test]
1226 fn sw_to_par_fr() {
1227 let res;
1228 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1229 br.open("https://vk.com").unwrap();
1230 res = br.switch_to_parent_frame();
1231 br.close_browser().unwrap();
1232 assert_eq!(res, Ok(()));
1233 }
1234 #[test]
1235 fn get_wind_rect() {
1236 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1237 let wr = br.get_window_rect().unwrap();
1238 br.close_browser().unwrap();
1239 assert!(wr==WindowRect{height:200,width:400,x:0,y:0});
1240 }
1241 #[test]
1242 fn set_wind_rect(){
1243 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1244 let wr = WindowRect{height:600, width:1000,x:250,y:250};
1245 let wr_new = br.set_sindow_rect(&wr).unwrap();
1246 br.close_browser().unwrap();
1247 assert_eq!(wr,wr_new);
1248
1249 }
1250 #[test]
1251 fn maximize() {
1252 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1253 let a = br.maximize_window().unwrap();
1254 br.close_browser().unwrap();
1255 let wr = WindowRect{height:200, width:400,x:0,y:0};
1256 assert_eq!(a,wr);
1257 }
1258 #[test]
1259 fn parse_val_test() {
1260 let resp = r#"{
1261 "value": {
1262 "dftg43rert34tert-34trte-243f-4":
1263 {
1264 "id": 333
1265 }
1266 }
1267 }"#;
1268 let res = parse_value(resp);
1269 assert_eq!(res,"{\"dftg43rert34tert-34trte-243f-4\":{\"id\":333}}");
1270 }
1271 #[test]
1272 fn fullsize() {
1273 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1274 let a = br.fullscreen().unwrap();
1275 br.close_browser().unwrap();
1276 assert!(a.x==0&&a.y==0);
1277 }
1278
1279 #[test]
1280 fn src() {
1281 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1282 br.open("http://localhost:4444/wd/hub/status").unwrap();
1283 let a = br.source().unwrap();
1284 br.close_browser().unwrap();
1285 assert!(a.contains("html")&&a.contains("head"))
1286 }
1287
1288 #[test]
1289 fn script_test() {
1290 let script = "return 3+2";
1291 let res = vec!["5",r#""Hello""#];
1292 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1293 let res = br.execute_sync(script, &res).unwrap();
1294 br.close_browser().unwrap();
1295 assert!(res.contains("5"));
1296 }
1297
1298 #[test]
1299 fn cookies() {
1300 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1301 br.open("https://vk.com").unwrap();
1302 let cook = br.get_all_cookies().unwrap();
1303 br.close_browser().unwrap();
1304 assert!(cook.len()>1);
1305 }
1306
1307 #[test]
1308 fn get_cookie() {
1309 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1310 br.open("https://vk.com").unwrap();
1311 let c = br.get_cookie("tmr_lvidTS").unwrap();
1312 br.close_browser().unwrap();
1313 assert_eq!(c.httpOnly,false);
1314 }
1315
1316 #[test]
1317 fn add_cookie() {
1318 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1319 br.open("https://vk.com").unwrap();
1320 let cook = Cookie::new_all(String::from(""), 1000, String::from("Lax"), false, String::from("tmr_detect"), String::from(""), false, String::from("0%7C1604223632022"));
1321 assert_eq!(br.add_cookie(cook),Ok(()));
1322 br.close_browser().unwrap();
1323 }
1324
1325 #[test]
1326 fn z_del_all_cook() {
1327 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1328 br.open("https://vk.com").unwrap();
1329 br.delete_all_cookies().unwrap();
1330 let cook = br.get_all_cookies().unwrap();
1331 br.close_browser().unwrap();
1332 assert_eq!(cook.len(),0);
1333 }
1334 #[test]
1335 fn t_del_cookie() {
1336 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1337 br.open("https://vk.com").unwrap();
1338 let r = br.delete_cookie("remixjsp");
1339 br.close_browser().unwrap();
1340 assert!(r==Ok(()));
1341 }
1342 #[test]
1343 fn screensh() {
1344 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=7680,4320"]);
1345 br.open("https://vk.com").unwrap();
1346 br.take_screenshot("screen.png").unwrap();
1347 br.close_browser().unwrap();
1348 let arr=std::fs::read("screen.png").unwrap().len();
1349 assert!(arr>0);
1350 std::fs::remove_file("screen.png").unwrap();
1351 }
1352 #[test]
1353 fn el_screensh() {
1354 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=800,600"]);
1355 br.open("https://vk.com").unwrap();
1356 let el = br.find_element(LocatorStrategy::CSS("#ts_input")).unwrap();
1357 br.take_element_screenshot(&el,"element.png").unwrap();
1358 br.close_browser().unwrap();
1359 let arr=std::fs::read("element.png").unwrap().len();
1360 assert!(arr>0);
1361 std::fs::remove_file("element.png").unwrap();
1362 }
1363 #[test]
1364 fn pr_page() {
1365 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=2400,1200"]);
1366 br.open("https://vk.com").unwrap();
1367 let mut p = PrintSettings::default();
1368 p.set_orientation(Orientation::LANDSCAPE);
1369 p.set_pages(vec![1,2]);
1370 br.print(&p, "page.pdf").unwrap();
1371 br.close_browser().unwrap();
1372 let arr=std::fs::read("page.pdf").unwrap().len();
1373 assert!(arr>0);
1374 std::fs::remove_file("page.pdf").unwrap();
1375 }
1376
1377 #[test]
1378 fn alerts() {
1379 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1380 br.open("https://vk.com").unwrap();
1381 let resp = br.dismiss_alert().is_err();
1382 let resp2 = br.allow_alert().is_err();
1383 br.close_browser().unwrap();
1384 assert!(resp&&resp2);
1385 }
1386 #[test]
1387 fn get_send_alert_text() {
1388 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1389 br.open("https://vk.com").unwrap();
1390 let resp = br.get_alert_text().is_err();
1391 let resp2 = br.send_alert_text("I am the text").is_err();
1392 br.close_browser().unwrap();
1393 assert!(resp&&resp2);
1394 }
1395 #[test]
1396 fn active_el() {
1397 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless"]);
1398 br.open("https://vk.com").unwrap();
1399 let a = br.get_active_element().unwrap();
1400 br.close_browser().unwrap();
1401 assert!(a.element_gr_id.contains("element"));
1402 }
1403 #[test]
1404 fn find_sub_el() {
1405 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1406 br.open("https://vk.com").unwrap();
1407 let par_el= br.find_element(LocatorStrategy::CSS("#top_nav")).unwrap();
1408 let a = par_el.find_element_from_self(LocatorStrategy::CSS(".HeaderNav__item")).unwrap();
1409 br.close_browser().unwrap();
1410 assert!(a.element_gr_id.contains("element"));
1411 }
1412 #[test]
1413 fn sub_els() {
1414 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1415 br.open("https://bash.im").unwrap();
1416 let par_el= br.find_element(LocatorStrategy::CSS("section.quotes")).unwrap();
1417 let a = par_el.find_elements_from_self(LocatorStrategy::CSS(".quote")).unwrap();
1418 br.close_browser().unwrap();
1419 let len = a.len();
1420 assert!(len>2);
1421 }
1422 #[test]
1423 fn is_sel() {
1424 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1425 br.open("https://vk.com").unwrap();
1426 let el= br.find_element(LocatorStrategy::CSS("#ts_input")).unwrap();
1427 let res = el.is_selected().unwrap();
1428 br.close_browser().unwrap();
1429 assert!(res==false);
1430 }
1431 #[test]
1432 fn get_arrtib() {
1433 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1434 br.open("https://vk.com").unwrap();
1435 let el= br.find_element(LocatorStrategy::CSS(".placeholder_content")).unwrap();
1436 let res = el.get_attribute("aria-hidde").unwrap();
1437 let res2 = el.get_attribute("aria-hidden").unwrap();
1438 br.close_browser().unwrap();
1439 assert!(res.as_str()=="null");
1440 assert!(res2.as_str()=="true");
1441 }
1442 #[test]
1443 fn get_property() {
1444 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1445 br.open("https://vk.com").unwrap();
1446 let el= br.find_element(LocatorStrategy::CSS("#index_login_form")).unwrap();
1447 let res_len = el.get_property("attributes").unwrap().len();
1448 let res_null = el.get_property("attributes2").unwrap();
1449 br.close_browser().unwrap();
1450 assert!(res_len>5000&&res_null.as_str()=="null");
1451 }
1452 #[test]
1453 fn get_css_property() {
1454 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1455 br.open("https://vk.com").unwrap();
1456 let el= br.find_element(LocatorStrategy::CSS("#index_login_form")).unwrap();
1457 let res = el.get_css_value("color").unwrap().contains("rgba");
1458 br.close_browser().unwrap();
1459 assert!(res);
1460 }
1461 #[test]
1462 fn get_el_text() {
1463 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1464 br.open("https://vk.com").unwrap();
1465 let el= br.find_element(LocatorStrategy::CSS("#index_login_form")).unwrap();
1466 let res = el.get_element_text().unwrap().contains("error");
1467 br.close_browser().unwrap();
1468 assert!(!res);
1469 }
1470 #[test]
1471 fn get_el_tag() {
1472 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1473 br.open("https://vk.com").unwrap();
1474 let el= br.find_element(LocatorStrategy::CSS("#index_login_form")).unwrap();
1475 let res = el.get_tag_name().unwrap().contains("error");
1476 br.close_browser().unwrap();
1477 assert!(!res);
1478 }
1479 #[test]
1480 fn get_el_rect() {
1481 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1482 br.open("https://vk.com").unwrap();
1483 let el= br.find_element(LocatorStrategy::CSS("#index_login_form")).unwrap();
1484 let res = el.get_element_rect().unwrap();
1485 br.close_browser().unwrap();
1486 assert!(res.height==140);
1487 }
1488 #[test]
1489 fn el_is_enabled() {
1490 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1491 br.open("https://vk.com").unwrap();
1492 let el= br.find_element(LocatorStrategy::CSS("#index_login_form")).unwrap();
1493 let res = el.is_enabled().unwrap();
1494 br.close_browser().unwrap();
1495 assert!(res);
1496 }
1497 #[test]
1498 fn get_comp_role() {
1499 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1500 br.open("https://vk.com").unwrap();
1501 let el= br.find_element(LocatorStrategy::CSS("#index_login_form")).unwrap();
1502 let res = el.get_computed_role();
1503 let res2 = el.get_computed_label();
1504 dbg!(&res);
1505 dbg!(&res2);
1506 br.close_browser().unwrap();
1507 assert!(res.is_err()&&res2.is_err());
1508 }
1509 #[test]
1510 fn click_test() {
1511 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1512 br.open("https://vk.com").unwrap();
1513 let el= br.find_element(LocatorStrategy::CSS("#index_login_form")).unwrap();
1514 let res = el.click();
1515 br.close_browser().unwrap();
1516 assert_eq!(res,Ok(()))
1517 }
1518 #[test]
1519 fn el_send_k() {
1520 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1521 br.open("https://vk.com").unwrap();
1522 let el= br.find_element(LocatorStrategy::CSS("#ts_input")).unwrap();
1523 el.send_keys("Sup!").unwrap();
1524 br.close_browser().unwrap();
1525 }
1526 #[test]
1527 fn el_clear() {
1528 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1529 br.open("https://vk.com").unwrap();
1530 let el= br.find_element(LocatorStrategy::CSS("#ts_input")).unwrap();
1531 let _ = el.send_keys("Sup!");
1532 el.clear_element().unwrap();
1533 br.close_browser().unwrap();
1534 }
1535 #[test]
1536 fn rel_actions() {
1537 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=400,200"]);
1538 let res1 = br.release_actions();
1539 br.close_browser().unwrap();
1540 let res2 = br.release_actions();
1541 assert!(res1.is_ok()&&res2.is_err());
1542 }
1543 #[test]
1544 fn per_f_ac_with_keys() {
1545 let mut actions = Actions::new();
1546 let mut actions_keys = ActionsKeys::new();
1547 actions_keys.press_special_key(SpecialKey::ShiftLeft);
1548 actions_keys.press_key("a");
1549 actions_keys.release_special_key(SpecialKey::ShiftLeft);
1550 actions_keys.press_key("b");
1551 actions.add_key_actions(actions_keys);
1552 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=1000,500"]);
1553 br.open("https:vk.com/").unwrap();
1554 br.find_element(LocatorStrategy::CSS("#ts_input")).unwrap().click().unwrap();
1555 let res = br.perform_actions(actions);
1556 br.close_browser().unwrap();
1557 assert!(res.is_ok());
1558 }
1559 #[test]
1560 fn perf_mouse_act() {
1561 let mut actions = Actions::new();
1562 let mut actions_keys = ActionsMouse::new();
1563 actions_keys.press_mouse_button(MouseButton::Left);
1564 actions_keys.pause(10);
1565 actions_keys.move_mouse_to_point(200,300);
1566 actions_keys.press_mouse_button(MouseButton::Right);
1567 actions.add_mouse_actions(actions_keys);
1568 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=1000,500"]);
1569 br.open("https:vk.com/").unwrap();
1570 let res = br.perform_actions(actions);
1571 let res2 = br.release_actions();
1572 br.close_browser().unwrap();
1573 assert!(res.is_ok()&&res2.is_ok());
1574 }
1575 #[test]
1576 fn keys_and_mouse_acts() {
1577 let mut actions = Actions::new();
1578 let mut keys = ActionsKeys::new();
1579 let mut mouse = ActionsMouse::new();
1580 keys.press_special_key(SpecialKey::ShiftLeft);
1581 keys.press_key("a");
1582 keys.release_special_key(SpecialKey::ShiftLeft);
1583 keys.press_key("b");
1584 mouse.pause(0);
1585 mouse.pause(0);
1586 mouse.press_mouse_button(MouseButton::Left);
1587 mouse.move_mouse_to_point(200,300);
1588 mouse.press_mouse_button(MouseButton::Right);
1589 actions.add_key_actions(keys);
1590 actions.add_mouse_actions(mouse);
1591 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=1000,500"]);
1592 br.open("https:vk.com/").unwrap();
1593 let res = br.perform_actions(actions);
1594 let res2 = br.release_actions();
1595 br.close_browser().unwrap();
1596 assert!(res.is_ok()&&res2.is_ok());
1597 }
1598 #[test]
1599 fn wheel_ac() {
1600 let mut actions = Actions::new();
1601 let mut wheel = ActionsWheel::new();
1602 wheel.scroll(0, 0, 100, 100).scroll(100, 100, 100, 100);
1603 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=600,400"]);
1604 br.open("https://yandex.ru/").unwrap();
1605 actions.add_wheel_actions(wheel);
1606 let res = br.perform_actions(actions);
1607 br.close_browser().unwrap();
1608 assert!(res.is_ok());
1609 }
1610 #[test]
1611 fn move_mouse_to_el() {
1612 let mut actions = Actions::new();
1613 let mut mouse = ActionsMouse::new();
1614 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=600,400"]);
1615 br.open("https://vk.com").unwrap();
1616 let el = br.find_element(LocatorStrategy::CSS("#ts_input")).unwrap();
1617 mouse.move_mouse_to_element(&el).press_mouse_button(MouseButton::Left);
1618 actions.add_mouse_actions(mouse);
1619 let res = br.perform_actions(actions);
1620 let res2 = br.release_actions();
1621 br.close_browser().unwrap();
1622 assert!(res.is_ok());
1623 assert!(res2.is_ok());
1624 }
1625 #[test]
1626 fn dranddrop() {
1627 let mut br = Browser::start_session(BrowserName::Chrome, vec!["--headless","--window-size=1500,800"]);
1628 br.open("http://webdriveruniversity.com/Actions/index.html").unwrap();
1629 let mut actions = Actions::new();
1630 let mut mouse = ActionsMouse::new();
1631 let el = br.find_element(LocatorStrategy::CSS("div#draggable")).unwrap();
1632 let el_dest = br.find_element(LocatorStrategy::CSS("div#droppable")).unwrap();
1633 mouse.drag_n_drop(el, el_dest);
1634 actions.add_mouse_actions(mouse);
1635 let res = br.perform_actions(actions);
1636 let res2 = br.release_actions();
1637 br.close_browser().unwrap();
1638 assert!(res.is_ok());
1639 assert!(res2.is_ok());
1640 }
1641}
1642mod additional_tests{
1643 use super::*;
1644 #[test]
1645 fn brow_chrome_opts() {
1646 let mut ch = ChromeOptions::new();
1647 let mob = MobileDevice::standard_device("Nexus 6");
1648 ch.add_args(vec!["--headless","--window-size=400,600"]);
1649 ch.add_mobile_emulation(mob);
1650 let mut br = Browser::start_chrome_session_with_options(ch).unwrap();
1651 let res = br.open("https://vk.com");
1652 let res2 = br.close_browser();
1653 assert!(res.is_ok()&&res2.is_ok());
1654 }
1655 #[test]
1656 fn brow_firefox_opts() {
1657 let mut ff = FirefoxOptions::new();
1658 ff.add_args(vec!["-headless","-devtools"]);
1659 let mut map = HashMap::new();
1660 map.insert("MOZ_HEADLESS_WIDTH", "600");
1661 map.insert("MOZ_HEADLESS_HEIGHT", "400");
1662 ff.add_env(map);
1663 let mut br = Browser::start_firefox_session_with_options(ff).unwrap();
1664 let res = br.open("https://vk.com");
1665 let res2 = br.close_browser();
1666 assert!(res.is_ok()&&res2.is_ok());
1667 }
1668 #[test]
1669 fn rem_lin_chr() {
1670 let mut br = Browser::start_remote_session(BrowserName::Chrome, "linux", "192.168.1.67","4444").unwrap();
1671 br.open("https://vk.com").unwrap();
1672 br.back().unwrap();
1673 br.close_browser().unwrap();
1674 }
1675 #[test]
1676 fn brow_cap() {
1677 let mut ch_op = ChromeOptions::new();
1678 ch_op.add_args(vec!["--headless","--window-size=500,1000"]);
1679 ch_op.add_mobile_emulation(MobileDevice::standard_device("Nexus 6"));
1680 let mut c = Capabilities::new(BrowserName::Chrome, "windows");
1681 c.set_chrome_options(ch_op);
1682 let mut br = Browser::start_session_with_capabilities(c).unwrap();
1683 br.open("https://vk.com").unwrap();
1684 br.take_screenshot("vk.png").unwrap();
1685 br.close_browser().unwrap();
1686 let res = std::fs::read("vk.png");
1687 assert!(res.is_ok());
1688 std::fs::remove_file("vk.png").unwrap();
1689 }
1690 #[test]
1691 fn brow_cap_remote() {
1692 let mut ch_op = ChromeOptions::new();
1693 ch_op.add_args(vec!["--headless","--window-size=500,1000"]);
1694 ch_op.add_mobile_emulation(MobileDevice::standard_device("Nexus 6"));
1695 let mut c = Capabilities::new(BrowserName::Chrome, "linux");
1696 c.set_chrome_options(ch_op);
1697 let mut br = Browser::start_remote_session_with_capabilities(c,"192.168.1.67","4444").unwrap();
1698 br.open("https://vk.com").unwrap();
1699 br.open("https://github.com").unwrap();
1700 let link = br.get_link().unwrap();
1701 assert!(link.contains("hub"));
1702 br.close_browser().unwrap();
1703 }
1704}
1705mod safari_tests{
1706 use super::*;
1707 #[test]
1708 #[cfg(target_os="macos")]
1709 fn saf_open_vk() {
1710 let mut br = Browser::start_session(BrowserName::Safari, vec![]);
1711 br.open("https://vk.com").unwrap();
1712 br.close_browser().unwrap();
1713 }
1714 #[test]
1715 #[cfg(target_os="macos")]
1716 fn saf_forward() {
1717 let link: String;
1718 {let mut br = Browser::start_session(BrowserName::Safari,vec![]);
1719 br.open("https://vk.com/").unwrap();
1720 br.open("https://m.facebook.com/").unwrap();
1721 br.back().unwrap();
1722 br.forward().unwrap();
1723 link = br.get_link().unwrap();
1724 br.close_browser().unwrap();}
1725 assert!(link.contains("facebook"));
1726 }
1727 #[test]
1728 #[cfg(target_os="macos")]
1729 fn saf_diagn() {
1730 let mut saf_op = SafariOptions::new();
1731 saf_op.enable_diagnose();
1732 let mut br = Browser::start_safari_session_with_options(saf_op).unwrap();
1733 br.open("https://vk.com/").unwrap();
1734 br.close_browser().unwrap();
1735 }
1736 #[test]
1737 #[cfg(target_os="macos")]
1738 fn saf_inspe() {
1739 let mut saf_op = SafariOptions::new();
1740 saf_op.enable_automatic_inspection();
1741 let mut br = Browser::start_safari_session_with_options(saf_op).unwrap();
1742 br.open("https://vk.com/").unwrap();
1743 br.close_browser().unwrap();
1744 }
1745 #[test]
1746 #[cfg(target_os="macos")]
1747 fn saf_profi() {
1748 let mut saf_op = SafariOptions::new();
1749 saf_op.enable_automatic_profiling();
1750 let mut br = Browser::start_safari_session_with_options(saf_op).unwrap();
1751 br.open("https://vk.com/").unwrap();
1752 br.close_browser().unwrap();
1753 }
1754}