1<?php 2 3namespace Facebook\WebDriver\Remote; 4 5use Facebook\WebDriver\Exception\UnsupportedOperationException; 6use Facebook\WebDriver\WebDriverAlert; 7use Facebook\WebDriver\WebDriverElement; 8use Facebook\WebDriver\WebDriverTargetLocator; 9 10/** 11 * Used to locate a given frame or window for RemoteWebDriver. 12 */ 13class RemoteTargetLocator implements WebDriverTargetLocator 14{ 15 /** @var RemoteExecuteMethod */ 16 protected $executor; 17 /** @var RemoteWebDriver */ 18 protected $driver; 19 /** @var bool */ 20 protected $isW3cCompliant; 21 22 public function __construct(RemoteExecuteMethod $executor, RemoteWebDriver $driver, $isW3cCompliant = false) 23 { 24 $this->executor = $executor; 25 $this->driver = $driver; 26 $this->isW3cCompliant = $isW3cCompliant; 27 } 28 29 /** 30 * @return RemoteWebDriver 31 */ 32 public function defaultContent() 33 { 34 $params = ['id' => null]; 35 $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, $params); 36 37 return $this->driver; 38 } 39 40 /** 41 * @param WebDriverElement|null|int|string $frame The WebDriverElement, the id or the name of the frame. 42 * When null, switch to the current top-level browsing context When int, switch to the WindowProxy identified 43 * by the value. When an Element, switch to that Element. 44 * @return RemoteWebDriver 45 */ 46 public function frame($frame) 47 { 48 if ($this->isW3cCompliant) { 49 if ($frame instanceof WebDriverElement) { 50 $id = [JsonWireCompat::WEB_DRIVER_ELEMENT_IDENTIFIER => $frame->getID()]; 51 } elseif ($frame === null) { 52 $id = null; 53 } elseif (is_int($frame)) { 54 $id = $frame; 55 } else { 56 throw new \InvalidArgumentException( 57 'In W3C compliance mode frame must be either instance of WebDriverElement, integer or null' 58 ); 59 } 60 } else { 61 if ($frame instanceof WebDriverElement) { 62 $id = ['ELEMENT' => $frame->getID()]; 63 } elseif ($frame === null) { 64 $id = null; 65 } elseif (is_int($frame)) { 66 $id = $frame; 67 } else { 68 $id = (string) $frame; 69 } 70 } 71 72 $params = ['id' => $id]; 73 $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, $params); 74 75 return $this->driver; 76 } 77 78 /** 79 * Switch to the parent iframe. 80 * 81 * @return RemoteWebDriver This driver focused on the parent frame 82 */ 83 public function parent() 84 { 85 $this->executor->execute(DriverCommand::SWITCH_TO_PARENT_FRAME, []); 86 87 return $this->driver; 88 } 89 90 /** 91 * @param string $handle The handle of the window to be focused on. 92 * @return RemoteWebDriver 93 */ 94 public function window($handle) 95 { 96 if ($this->isW3cCompliant) { 97 $params = ['handle' => (string) $handle]; 98 } else { 99 $params = ['name' => (string) $handle]; 100 } 101 102 $this->executor->execute(DriverCommand::SWITCH_TO_WINDOW, $params); 103 104 return $this->driver; 105 } 106 107 /** 108 * Creates a new browser window and switches the focus for future commands of this driver to the new window. 109 * 110 * @see https://w3c.github.io/webdriver/#new-window 111 * @param string $windowType The type of a new browser window that should be created. One of [tab, window]. 112 * The created window is not guaranteed to be of the requested type; if the driver does not support the requested 113 * type, a new browser window will be created of whatever type the driver does support. 114 * @throws UnsupportedOperationException 115 * @return RemoteWebDriver This driver focused on the given window 116 */ 117 public function newWindow($windowType = self::WINDOW_TYPE_TAB) 118 { 119 if ($windowType !== self::WINDOW_TYPE_TAB && $windowType !== self::WINDOW_TYPE_WINDOW) { 120 throw new \InvalidArgumentException('Window type must by either "tab" or "window"'); 121 } 122 123 if (!$this->isW3cCompliant) { 124 throw new UnsupportedOperationException('New window is only supported in W3C mode'); 125 } 126 127 $response = $this->executor->execute(DriverCommand::NEW_WINDOW, ['type' => $windowType]); 128 129 $this->window($response['handle']); 130 131 return $this->driver; 132 } 133 134 public function alert() 135 { 136 return new WebDriverAlert($this->executor); 137 } 138 139 /** 140 * @return RemoteWebElement 141 */ 142 public function activeElement() 143 { 144 $response = $this->driver->execute(DriverCommand::GET_ACTIVE_ELEMENT, []); 145 $method = new RemoteExecuteMethod($this->driver); 146 147 return new RemoteWebElement($method, JsonWireCompat::getElement($response), $this->isW3cCompliant); 148 } 149} 150