use std::collections::HashMap;
use serde::Serialize;
use super::reqs::*;
pub struct ChromeOptions{
pub(crate) string_for_session:String,
}
impl ChromeOptions{
pub fn new()->Self{
ChromeOptions{
string_for_session: String::from(r#""goog:chromeOptions":{}"#),
}
}
pub fn add_args(&mut self,args:Vec<&str>)->&mut Self{
if self.string_for_session.contains("args"){panic!("The options already contain args");}
self.string_for_session.pop();
let mut inner_args = String::from("\"args\":");
let vec_to_str = from_str_vec_to_str(args);
inner_args.push_str(&vec_to_str);
self.string_for_session.push_str(&inner_args);
self.string_for_session.push('}');
self
}
pub fn add_binary(&mut self,path: &str)->&mut Self{
if self.string_for_session.contains("binary"){panic!("The options already contain path to binary");}
self.string_for_session.pop();
let bin = format!(r#""binary":"{}","#,path);
self.string_for_session.push_str(&bin);
self.string_for_session.push('}');
self
}
pub fn add_extensions(&mut self,extensions:Vec<&str>)->&mut Self{
if self.string_for_session.contains("extensions"){panic!("The options already contain extension");}
self.string_for_session.pop();
let mut inner_args = String::from("\"extensions\":");
let vec_to_str = from_str_vec_to_str(extensions);
inner_args.push_str(&vec_to_str);
self.string_for_session.push_str(&inner_args);
self.string_for_session.push('}');
self
}
pub fn add_local_state(&mut self,local_state: HashMap<&str,&str>)->&mut Self{
if self.string_for_session.contains("localState"){panic!("The options already contain local state");}
self.string_for_session.pop();
let mut temp_string = String::from("\"localState\":{");
for i in local_state{
let temp = format!(r#""{}":"{}","#,i.0,i.1);
temp_string.push_str(&temp);
}
temp_string.pop();
temp_string.push('}');
temp_string.push(',');
self.string_for_session.push_str(&temp_string);
self.string_for_session.push('}');
self
}
pub fn add_prefs(&mut self,prefs: HashMap<&str,&str>)->&mut Self{
if self.string_for_session.contains("prefs"){panic!("The options already contain prefs");}
self.string_for_session.pop();
let mut temp_string = String::from("\"prefs\":{");
for i in prefs{
let temp = format!(r#""{}":"{}","#,i.0,i.1);
temp_string.push_str(&temp);
}
temp_string.pop();
temp_string.push('}');
temp_string.push(',');
self.string_for_session.push_str(&temp_string);
self.string_for_session.push('}');
self
}
pub fn add_detach(&mut self,detach: bool)->&mut Self{
if self.string_for_session.contains("detach"){panic!("The options already contain detach");}
self.string_for_session.pop();
let text = format!(r#""detach":{},"#,detach);
self.string_for_session.push_str(&text);
self.string_for_session.push('}');
self
}
pub fn add_debugger_address(&mut self,address: &str)->&mut Self{
if self.string_for_session.contains("debuggerAddress"){panic!("The options already contain debugger address");}
self.string_for_session.pop();
let text = format!(r#""debuggerAddress":"{}","#,address);
self.string_for_session.push_str(&text);
self.string_for_session.push('}');
self
}
pub fn add_exclude_switches(&mut self,switches: Vec<&str>)->&mut Self{
if self.string_for_session.contains("excludeSwitches"){panic!("The options already contain switches to exclude");}
self.string_for_session.pop();
let mut temp_string = String::from("\"excludeSwitches\":");
let vec_to_str = from_str_vec_to_str(switches);
temp_string.push_str(&vec_to_str);
self.string_for_session.push_str(&temp_string);
self.string_for_session.push('}');
self
}
pub fn add_minidump_path(&mut self,path:&str)->&mut Self{
if self.string_for_session.contains("minidumpPath"){panic!("The options already contain the path to the minidump");}
self.string_for_session.pop();
let text = format!(r#""minidumpPath":"{}","#,path);
self.string_for_session.push_str(&text);
self.string_for_session.push('}');
self
}
pub fn add_mobile_emulation(&mut self,device:MobileDevice)->&mut Self{
if self.string_for_session.contains("mobileEmulation"){panic!("The options already contain the device to emulate");}
self.string_for_session.pop();
let text = format!(r#""mobileEmulation":{},"#,device.device_dict);
self.string_for_session.push_str(&text);
self.string_for_session.push('}');
self
}
pub fn add_perf_logging_prefs(&mut self, prefs:PerfLoggingPrefs)->&mut Self{
if self.string_for_session.contains("perfLoggingPrefs"){panic!("The options already contain the device to emulate");}
self.string_for_session.pop();
let perf_to_json = serde_json::to_string(&prefs).unwrap();
let text = format!(r#""perfLoggingPrefs":{},"#,perf_to_json);
self.string_for_session.push_str(&text);
self.string_for_session.push('}');
self
}
pub fn add_window_types(&mut self,window_types:Vec<&str>)->&mut Self{
if self.string_for_session.contains("windowTypes"){panic!("The options already contain window types");}
self.string_for_session.pop();
let mut temp_string = String::from("\"windowTypes\":");
let vec_to_str = from_str_vec_to_str(window_types);
temp_string.push_str(&vec_to_str);
self.string_for_session.push_str(&temp_string);
self.string_for_session.push('}');
self
}
}
pub struct MobileDevice{
pub(crate) device_dict:String,
}
impl MobileDevice{
pub fn standard_device(device_name:&str)->Self{
let device_dict = format!(r#"{{"deviceName":"{}"}}"#,device_name);
MobileDevice{
device_dict
}
}
pub fn custom_device(width:u32,
height:u32,
pixel_ratio:f32,
touch: bool,
user_agent: &str)->Self{
let device_dict = format!(
r#"{{"deviceMetrics":{{
"width":{},
"height":{},
"pixel_ratio":{},
"touch":{}}},
"userAgent":"{}"}}"#,width,height,pixel_ratio,touch,user_agent).
replace("\n","").
replace(" ","");
MobileDevice{device_dict}
}
}
#[allow(non_snake_case)]
#[derive(Serialize,Debug)]
pub struct PerfLoggingPrefs{
enableNetwork:bool,
enablePage:bool,
traceCategories:String,
bufferUsageReportingInterval:u32,
}
impl PerfLoggingPrefs{
pub fn set_enable_network(&mut self, en_network:bool){
self.enableNetwork = en_network;
}
pub fn set_enable_page(&mut self,en_page:bool ){
self.enablePage = en_page;
}
pub fn set_trace_categories(&mut self,trace_cat:String){
self.traceCategories = trace_cat;
}
pub fn set_buffer_usage_rep_interval(&mut self,buff: u32){
self.bufferUsageReportingInterval = buff;
}
}
impl Default for PerfLoggingPrefs{
fn default()->Self{
PerfLoggingPrefs{
enableNetwork: true,
enablePage: true,
traceCategories: String::from(""),
bufferUsageReportingInterval: 1000,
}
}
}
pub (crate) mod chr_opt_tests{
use super::*;
#[test]
fn chro_mob_em() {
let mut ch = ChromeOptions::new();
let mob = MobileDevice::standard_device("Nexus 6");
ch.add_mobile_emulation(mob);
let x = r#""goog:chromeOptions":{"mobileEmulation":{"deviceName":"Nexus 6"},}"#;
assert_eq!(x,ch.string_for_session);
}
#[test]
fn chro_cust_mob_em() {
let mut ch = ChromeOptions::new();
let mob = MobileDevice::custom_device(300,150,3.0,true,"Custom Agent");
ch.add_mobile_emulation(mob);
let x = r#""goog:chromeOptions":{"mobileEmulation":{"deviceMetrics":{"width":300,"height":150,"pixel_ratio":3,"touch":true},"userAgent":"CustomAgent"},}"#;
assert_eq!(x,ch.string_for_session);
}
#[test]
fn chro_gen_str() {
let v = vec![];
let string = from_str_vec_to_str(v);
assert_eq!(&string, "[]");
let args = vec!["--headless","--window-size=800,600"];
let string = from_str_vec_to_str(args);
assert_eq!(string,"[\"--headless\",\"--window-size=800,600\"],");
}
#[test]
fn chro_gen_str_for_ext() {
let v = vec!["ext_one","ext_two"];
let mut ch = ChromeOptions::new();
ch.add_extensions(v);
assert_eq!(r#""goog:chromeOptions":{"extensions":["ext_one","ext_two"],}"#,ch.string_for_session);
}
#[test]
fn chro_gen_str_for_args() {
let args = vec!["--headless","--window-size=800,600"];
let mut ch = ChromeOptions::new();
ch.add_args(args);
assert_eq!(r#""goog:chromeOptions":{"args":["--headless","--window-size=800,600"],}"#,ch.string_for_session);
}
#[test]
fn chro_gen_str_for_window_types() {
let types = vec!["type_one","type_two"];
let mut ch = ChromeOptions::new();
ch.add_window_types(types);
assert_eq!(r#""goog:chromeOptions":{"windowTypes":["type_one","type_two"],}"#,ch.string_for_session);
}
#[test]
fn chro_perf_log() {
let pr = PerfLoggingPrefs::default();
let mut ch = ChromeOptions::new();
ch.add_perf_logging_prefs(pr);
assert!(ch.string_for_session.contains("perfLoggingPrefs"));
}
}