1<?php 2 3namespace Facebook\WebDriver\Chrome; 4 5use Facebook\WebDriver\Remote\DesiredCapabilities; 6use JsonSerializable; 7use ReturnTypeWillChange; 8 9/** 10 * The class manages the capabilities in ChromeDriver. 11 * 12 * @see https://sites.google.com/a/chromium.org/chromedriver/capabilities 13 */ 14class ChromeOptions implements JsonSerializable 15{ 16 /** 17 * The key of chromeOptions in desired capabilities (in legacy OSS JsonWire protocol) 18 * @todo Replace value with 'goog:chromeOptions' after JsonWire protocol support is removed 19 */ 20 const CAPABILITY = 'chromeOptions'; 21 /** 22 * The key of chromeOptions in desired capabilities (in W3C compatible protocol) 23 */ 24 const CAPABILITY_W3C = 'goog:chromeOptions'; 25 /** 26 * @var array 27 */ 28 private $arguments = []; 29 /** 30 * @var string 31 */ 32 private $binary = ''; 33 /** 34 * @var array 35 */ 36 private $extensions = []; 37 /** 38 * @var array 39 */ 40 private $experimentalOptions = []; 41 42 /** 43 * Return a version of the class which can JSON serialized. 44 * 45 * @return array 46 */ 47 #[ReturnTypeWillChange] 48 public function jsonSerialize() 49 { 50 return $this->toArray(); 51 } 52 53 /** 54 * Sets the path of the Chrome executable. The path should be either absolute 55 * or relative to the location running ChromeDriver server. 56 * 57 * @param string $path 58 * @return ChromeOptions 59 */ 60 public function setBinary($path) 61 { 62 $this->binary = $path; 63 64 return $this; 65 } 66 67 /** 68 * @param array $arguments 69 * @return ChromeOptions 70 */ 71 public function addArguments(array $arguments) 72 { 73 $this->arguments = array_merge($this->arguments, $arguments); 74 75 return $this; 76 } 77 78 /** 79 * Add a Chrome extension to install on browser startup. Each path should be 80 * a packed Chrome extension. 81 * 82 * @param array $paths 83 * @return ChromeOptions 84 */ 85 public function addExtensions(array $paths) 86 { 87 foreach ($paths as $path) { 88 $this->addExtension($path); 89 } 90 91 return $this; 92 } 93 94 /** 95 * @param array $encoded_extensions An array of base64 encoded of the extensions. 96 * @return ChromeOptions 97 */ 98 public function addEncodedExtensions(array $encoded_extensions) 99 { 100 foreach ($encoded_extensions as $encoded_extension) { 101 $this->addEncodedExtension($encoded_extension); 102 } 103 104 return $this; 105 } 106 107 /** 108 * Sets an experimental option which has not exposed officially. 109 * 110 * @param string $name 111 * @param mixed $value 112 * @return ChromeOptions 113 */ 114 public function setExperimentalOption($name, $value) 115 { 116 $this->experimentalOptions[$name] = $value; 117 118 return $this; 119 } 120 121 /** 122 * @return DesiredCapabilities The DesiredCapabilities for Chrome with this options. 123 */ 124 public function toCapabilities() 125 { 126 $capabilities = DesiredCapabilities::chrome(); 127 $capabilities->setCapability(self::CAPABILITY, $this); 128 129 return $capabilities; 130 } 131 132 /** 133 * @return \ArrayObject|array 134 */ 135 public function toArray() 136 { 137 // The selenium server expects a 'dictionary' instead of a 'list' when 138 // reading the chrome option. However, an empty array in PHP will be 139 // converted to a 'list' instead of a 'dictionary'. To fix it, we work 140 // with `ArrayObject` 141 $options = new \ArrayObject($this->experimentalOptions); 142 143 if (!empty($this->binary)) { 144 $options['binary'] = $this->binary; 145 } 146 147 if (!empty($this->arguments)) { 148 $options['args'] = $this->arguments; 149 } 150 151 if (!empty($this->extensions)) { 152 $options['extensions'] = $this->extensions; 153 } 154 155 return $options; 156 } 157 158 /** 159 * Add a Chrome extension to install on browser startup. Each path should be a 160 * packed Chrome extension. 161 * 162 * @param string $path 163 * @return ChromeOptions 164 */ 165 private function addExtension($path) 166 { 167 $this->addEncodedExtension(base64_encode(file_get_contents($path))); 168 169 return $this; 170 } 171 172 /** 173 * @param string $encoded_extension Base64 encoded of the extension. 174 * @return ChromeOptions 175 */ 176 private function addEncodedExtension($encoded_extension) 177 { 178 $this->extensions[] = $encoded_extension; 179 180 return $this; 181 } 182} 183