1: <?php
2: namespace Peridot\WebDriverManager;
3:
4: use Peridot\WebDriverManager\Binary\BinaryInterface;
5: use Peridot\WebDriverManager\Binary\BinaryResolver;
6: use Peridot\WebDriverManager\Binary\BinaryResolverInterface;
7: use Peridot\WebDriverManager\Binary\ChromeDriver;
8: use Peridot\WebDriverManager\Binary\DriverInterface;
9: use Peridot\WebDriverManager\Binary\IEDriver;
10: use Peridot\WebDriverManager\Binary\SeleniumStandalone;
11: use Peridot\WebDriverManager\Event\EventEmitterInterface;
12: use Peridot\WebDriverManager\Event\EventEmitterTrait;
13: use Peridot\WebDriverManager\Process\SeleniumProcessInterface;
14: use Peridot\WebDriverManager\Process\SeleniumProcess;
15: use RuntimeException;
16:
17: 18: 19: 20: 21: 22:
23: class Manager implements EventEmitterInterface
24: {
25: use EventEmitterTrait;
26:
27: 28: 29:
30: protected $binaries;
31:
32: 33: 34:
35: protected $resolver;
36:
37: 38: 39:
40: protected $process;
41:
42: 43: 44:
45: protected $installPath = '';
46:
47: 48: 49: 50:
51: public function __construct(BinaryResolverInterface $resolver = null, SeleniumProcessInterface $process = null) {
52: $this->resolver = $resolver;
53: $this->process = $process;
54: $this->binaries = [];
55:
56: $resolver = $this->getBinaryResolver();
57: $this->addBinary(new SeleniumStandalone($resolver));
58: $this->addBinary(new ChromeDriver($resolver));
59: $this->addBinary(new IEDriver($resolver));
60: $this->setBinaryResolver($resolver);
61: }
62:
63: 64: 65: 66: 67:
68: public function addBinary(BinaryInterface $binary)
69: {
70: $this->binaries[$binary->getName()] = $binary;
71: }
72:
73: 74: 75: 76: 77:
78: public function removeBinary($binaryName)
79: {
80: if (isset($this->binaries[$binaryName])) {
81: unset($this->binaries[$binaryName]);
82: }
83: }
84:
85: 86: 87: 88: 89:
90: public function getBinaryResolver()
91: {
92: if ($this->resolver === null) {
93: $this->resolver = new BinaryResolver();
94: }
95:
96: return $this->resolver;
97: }
98:
99: 100: 101: 102: 103:
104: public function setBinaryResolver(BinaryResolverInterface $resolver)
105: {
106: $this->resolver = $resolver;
107: $this->inherit(['progress', 'request.start', 'complete'], $resolver);
108: }
109:
110: 111: 112: 113: 114: 115:
116: public function getSeleniumProcess()
117: {
118: if ($this->process === null) {
119: $this->process = new SeleniumProcess();
120: }
121:
122: return $this->process;
123: }
124:
125: 126: 127: 128: 129: 130:
131: public function getBinaries(callable $predicate = null)
132: {
133: $binaries = $this->binaries;
134: if ($predicate !== null) {
135: return array_filter($binaries, $predicate);
136: }
137: return $binaries;
138: }
139:
140: 141: 142: 143: 144:
145: public function getDrivers()
146: {
147: return $this->getBinaries(function ($binary) {
148: return $binary instanceof DriverInterface;
149: });
150: }
151:
152: 153: 154: 155: 156:
157: public function getPendingBinaries()
158: {
159: return $this->getBinaries(function (BinaryInterface $binary) {
160: $exists = $binary->exists($this->getInstallPath());
161: $supported = $binary->isSupported();
162: return $supported && !$exists;
163: });
164: }
165:
166: 167: 168: 169: 170:
171: public function update($binaryName = '')
172: {
173: if ($binaryName) {
174: $this->updateSingle($binaryName);
175: return;
176: }
177:
178: foreach ($this->binaries as $binary) {
179: $binary->fetchAndSave($this->getInstallPath());
180: }
181: }
182:
183: 184: 185: 186: 187: 188:
189: public function updateSingle($binaryName)
190: {
191: if (! array_key_exists($binaryName, $this->binaries)) {
192: throw new RuntimeException("Binary named $binaryName does not exist");
193: }
194:
195: $binary = $this->binaries[$binaryName];
196: $binary->fetchAndSave($this->getInstallPath());
197: }
198:
199: 200: 201: 202: 203: 204: 205: 206:
207: public function start($background = false, $port = 4444, array $args = [])
208: {
209: $selenium = $this->binaries['selenium'];
210: $this->assertStartConditions($selenium);
211:
212: $process = $this->getSeleniumProcess();
213: $this->registerBinaries($process, $selenium);
214:
215: if ($port != 4444) {
216: $process->addArg('-port', $port);
217: }
218:
219: if (!empty($args)) {
220: $process->addArgs($args);
221: }
222:
223: return $process->start($background);
224: }
225:
226: 227: 228: 229: 230: 231:
232: public function startInForeground($port = 4444, array $args = [])
233: {
234: return $this->start(false, $port, $args);
235: }
236:
237: 238: 239: 240: 241: 242:
243: public function startInBackground($port = 4444, array $args = [])
244: {
245: return $this->start(true, $port, $args);
246: }
247:
248: 249: 250: 251: 252:
253: public function clean()
254: {
255: $files = glob($this->getInstallPath() . '/*');
256: foreach ($files as $file) {
257: unlink($file);
258: }
259: }
260:
261: 262: 263: 264: 265:
266: public function getInstallPath()
267: {
268: if ($this->installPath === '') {
269: $this->installPath = realpath(__DIR__ . '/../binaries');
270: }
271:
272: return $this->installPath;
273: }
274:
275: 276: 277: 278: 279:
280: public function setInstallPath($path)
281: {
282: $this->installPath = $path;
283: }
284:
285: 286: 287: 288: 289: 290: 291:
292: protected function assertStartConditions(SeleniumStandalone $selenium)
293: {
294: if (!$selenium->exists($this->getInstallPath())) {
295: throw new RuntimeException("Selenium Standalone binary not installed");
296: }
297:
298: if (!$this->getSeleniumProcess()->isAvailable()) {
299: throw new RuntimeException('java is not available');
300: }
301: }
302:
303: 304: 305: 306: 307: 308: 309:
310: protected function registerBinaries(SeleniumProcessInterface $process, SeleniumStandalone $selenium)
311: {
312: $process->addBinary($selenium, $this->getInstallPath());
313: $drivers = $this->getDrivers();
314: foreach ($drivers as $driver) {
315: $process->addBinary($driver, $this->getInstallPath());
316: }
317: }
318: }
319: