Files
farmOS-dev/vendor/instaclick/php-webdriver/lib/WebDriver/Container.php
2024-12-10 15:08:16 +01:00

253 lines
6.9 KiB
PHP

<?php
/**
* Copyright 2004-2017 Facebook. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @package WebDriver
*
* @author Justin Bishop <jubishop@gmail.com>
* @author Anthon Pang <apang@softwaredevelopment.ca>
* @author Fabrizio Branca <mail@fabrizio-branca.de>
*/
namespace WebDriver;
use WebDriver\Exception as WebDriverException;
/**
* Abstract WebDriver\Container class
*
* @package WebDriver
*/
abstract class Container extends AbstractWebDriver
{
const LEGACY_ELEMENT_ID = 'ELEMENT';
const WEBDRIVER_ELEMENT_ID = 'element-6066-11e4-a52e-4f735466cecf';
/**
* @var array
*/
private $strategies;
/**
* {@inheritdoc}
*/
public function __construct($url)
{
parent::__construct($url);
$locatorStrategy = new \ReflectionClass('WebDriver\LocatorStrategy');
$this->strategies = $locatorStrategy->getConstants();
}
/**
* Find element: /session/:sessionId/element (POST)
* Find child element: /session/:sessionId/element/:id/element (POST)
* Search for element on page, starting from the document root.
*
* @param string $using the locator strategy to use
* @param string $value the search target
*
* @return \WebDriver\Element
*
* @throws \WebDriver\Exception if element not found, or invalid XPath
*/
public function element($using = null, $value = null)
{
$locatorJson = $this->parseArgs('element', func_get_args());
try {
$result = $this->curl(
'POST',
'/element',
$locatorJson
);
} catch (WebDriverException\NoSuchElement $e) {
throw WebDriverException::factory(
WebDriverException::NO_SUCH_ELEMENT,
sprintf(
"Element not found with %s, %s\n\n%s",
$locatorJson['using'],
$locatorJson['value'],
$e->getMessage()
),
$e
);
}
$element = $this->webDriverElement($result['value']);
if ($element === null) {
throw WebDriverException::factory(
WebDriverException::NO_SUCH_ELEMENT,
sprintf(
"Element not found with %s, %s\n",
$locatorJson['using'],
$locatorJson['value']
)
);
}
return $element;
}
/**
* Find elements: /session/:sessionId/elements (POST)
* Find child elements: /session/:sessionId/element/:id/elements (POST)
* Search for multiple elements on page, starting from the document root.
*
* @param string $using the locator strategy to use
* @param string $value the search target
*
* @return array
*
* @throws \WebDriver\Exception if invalid XPath
*/
public function elements($using = null, $value = null)
{
$locatorJson = $this->parseArgs('elements', func_get_args());
$result = $this->curl(
'POST',
'/elements',
$locatorJson
);
if (!is_array($result['value'])) {
return array();
}
return array_filter(
array_map(
array($this, 'webDriverElement'),
$result['value']
)
);
}
/**
* Parse arguments allowing either separate $using and $value parameters, or
* as an array containing the JSON parameters
*
* @param string $method method name
* @param array $argv arguments
*
* @return array
*
* @throws \WebDriver\Exception if invalid number of arguments to the called method
*/
private function parseArgs($method, $argv)
{
$argc = count($argv);
switch ($argc) {
case 2:
$using = $argv[0];
$value = $argv[1];
break;
case 1:
$arg = $argv[0];
if (is_array($arg)) {
$using = $arg['using'];
$value = $arg['value'];
break;
}
// fall through
default:
throw WebDriverException::factory(
WebDriverException::JSON_PARAMETERS_EXPECTED,
sprintf('Invalid arguments to %s method: %s', $method, print_r($argv, true))
);
}
return $this->locate($using, $value);
}
/**
* Return JSON parameter for element / elements command
*
* @param string $using locator strategy
* @param string $value search target
*
* @return array
*
* @throws \WebDriver\Exception if invalid locator strategy
*/
public function locate($using, $value)
{
if (!in_array($using, $this->strategies)) {
throw WebDriverException::factory(
WebDriverException::UNKNOWN_LOCATOR_STRATEGY,
sprintf('Invalid locator strategy %s', $using)
);
}
return array(
'using' => $using,
'value' => $value,
);
}
/**
* Return WebDriver\Element wrapper for $value
*
* @param mixed $value
*
* @return \WebDriver\Element|null
*/
protected function webDriverElement($value)
{
if (array_key_exists(self::LEGACY_ELEMENT_ID, (array) $value)) {
return new Element(
$this->getElementPath($value[self::LEGACY_ELEMENT_ID]), // url
$value[self::LEGACY_ELEMENT_ID] // id
);
}
if (array_key_exists(self::WEBDRIVER_ELEMENT_ID, (array) $value)) {
return new Element(
$this->getElementPath($value[self::WEBDRIVER_ELEMENT_ID]), // url
$value[self::WEBDRIVER_ELEMENT_ID] // id
);
}
return null;
}
/**
* {@inheritdoc}
*/
public function __call($name, $arguments)
{
if (count($arguments) === 1 && in_array(str_replace('_', ' ', $name), $this->strategies)) {
return $this->locate($name, $arguments[0]);
}
// fallback to executing WebDriver commands
return parent::__call($name, $arguments);
}
/**
* Get wire protocol URL for an element
*
* @param string $elementId
*
* @return string
*/
abstract protected function getElementPath($elementId);
}