diff --git a/lib/WebDriver/Session.php b/lib/WebDriver/Session.php index e11cab4..497c10b 100644 --- a/lib/WebDriver/Session.php +++ b/lib/WebDriver/Session.php @@ -425,83 +425,96 @@ public function log() } /** - * {@inheritdoc} + * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. (synchronous) + * + * @param array{script: string, args: array} $jsonScript + * + * @return mixed */ - protected function getElementPath($elementId) + public function execute(array $jsonScript) { - return sprintf('%s/element/%s', $this->url, $elementId); + if (isset($jsonScript['args'])) { + $jsonScript['args'] = $this->serializeArguments($jsonScript['args']); + } + + $result = $this->curl('POST', '/execute', $jsonScript); + + return $this->unserializeResult($result); } /** - * @param array $args + * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. (asynchronous) * - * @return array + * @param array{script: string, args: array} $jsonScript + * + * @return mixed */ - private function prepareScriptArguments(array $args) + public function execute_async(array $jsonScript) { - foreach ($args as $k => $v) { - if ($v instanceof Element) { - $args[$k] = [Container::WEBDRIVER_ELEMENT_ID => $v->getID()]; - } elseif (is_array($v)) { - $args[$k] = $this->prepareScriptArguments($v); - } + if (isset($jsonScript['args'])) { + $jsonScript['args'] = $this->serializeArguments($jsonScript['args']); } - return $args; + $result = $this->curl('POST', '/execute_async', $jsonScript); + + return $this->unserializeResult($result); } /** - * @param mixed $data - * - * @return mixed + * {@inheritdoc} */ - private function webDriverElementRecursive($data) + protected function getElementPath($elementId) { - $element = $this->webDriverElement($data); - if ($element !== null) { - return $element; - } elseif (is_array($data)) { - foreach ($data as $k => $v) { - $data[$k] = $this->webDriverElementRecursive($v); - } - } - - return $data; + return sprintf('%s/element/%s', $this->url, $elementId); } /** - * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. (synchronous) + * Serialize script arguments (containing web elements) * - * @param array{script: string, args: array} $jsonScript + * @see https://w3c.github.io/webdriver/#executing-script * - * @return mixed + * @param array $arguments + * + * @return array */ - public function execute(array $jsonScript) + private function serializeArguments(array $arguments) { - if (isset($jsonScript['args'])) { - $jsonScript['args'] = $this->prepareScriptArguments($jsonScript['args']); - } + foreach ($arguments as $key => $value) { + // Potential compat-buster, i.e., W3C-specific + if ($value instanceof Element) { + $arguments[$key] = [Container::WEBDRIVER_ELEMENT_ID => $value->getID()]; + continue; + } - $result = parent::execute($jsonScript); + if (is_array($value)) { + $arguments[$key] = $this->serializeArguments($value); + } + } - return $this->webDriverElementRecursive($result); + return $arguments; } /** - * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. (asynchronous) + * Unserialize result (containing web elements) * - * @param array{script: string, args: array} $jsonScript + * @param mixed $result * * @return mixed */ - public function execute_async(array $jsonScript) + private function unserializeResult($result) { - if (isset($jsonScript['args'])) { - $jsonScript['args'] = $this->prepareScriptArguments($jsonScript['args']); + $element = $this->webDriverElement($result); + + if ($element !== null) { + return $element; } - $result = parent::execute_async($jsonScript); + if (is_array($result)) { + foreach ($result as $key => $value) { + $result[$key] = $this->unserializeResult($value); + } + } - return $this->webDriverElementRecursive($result); + return $result; } }