* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Behat\Mink\Element; use Behat\Mink\Driver\DriverInterface; use Behat\Mink\Exception\ElementNotFoundException; use Behat\Mink\Selector\SelectorsHandler; use Behat\Mink\Selector\Xpath\Manipulator; use Behat\Mink\Session; /** * Base element. * * @author Konstantin Kudryashov */ abstract class Element implements ElementInterface { /** * @var Session */ private $session; /** * Driver. * * @var DriverInterface */ private $driver; /** * @var SelectorsHandler */ private $selectorsHandler; /** * @var Manipulator */ private $xpathManipulator; /** * Initialize element. * * @param Session $session */ public function __construct(Session $session) { $this->xpathManipulator = new Manipulator(); $this->session = $session; $this->driver = $session->getDriver(); $this->selectorsHandler = $session->getSelectorsHandler(); } /** * Returns element session. * * @return Session * * @deprecated Accessing the session from the element is deprecated as of 1.6 and will be impossible in 2.0. */ public function getSession() { @trigger_error(sprintf('The method %s is deprecated as of 1.6 and will be removed in 2.0', __METHOD__), E_USER_DEPRECATED); return $this->session; } /** * Returns element's driver. * * @return DriverInterface */ protected function getDriver() { return $this->driver; } /** * Returns selectors handler. * * @return SelectorsHandler * * @deprecated Accessing the selectors handler in the element is deprecated as of 1.7 and will be impossible in 2.0. */ protected function getSelectorsHandler() { @trigger_error(sprintf('The method %s is deprecated as of 1.7 and will be removed in 2.0', __METHOD__), E_USER_DEPRECATED); return $this->selectorsHandler; } /** * {@inheritdoc} */ public function has($selector, $locator) { return null !== $this->find($selector, $locator); } /** * {@inheritdoc} */ public function isValid() { return 1 === count($this->getDriver()->find($this->getXpath())); } /** * {@inheritdoc} */ public function waitFor($timeout, $callback) { if (!is_callable($callback)) { throw new \InvalidArgumentException('Given callback is not a valid callable'); } $start = microtime(true); $end = $start + $timeout; do { $result = call_user_func($callback, $this); if ($result) { break; } usleep(100000); } while (microtime(true) < $end); return $result; } /** * {@inheritdoc} */ public function find($selector, $locator) { $items = $this->findAll($selector, $locator); return count($items) ? current($items) : null; } /** * {@inheritdoc} */ public function findAll($selector, $locator) { if ('named' === $selector) { $items = $this->findAll('named_exact', $locator); if (empty($items)) { $items = $this->findAll('named_partial', $locator); } return $items; } $xpath = $this->selectorsHandler->selectorToXpath($selector, $locator); $xpath = $this->xpathManipulator->prepend($xpath, $this->getXpath()); return $this->getDriver()->find($xpath); } /** * {@inheritdoc} */ public function getText() { return $this->getDriver()->getText($this->getXpath()); } /** * {@inheritdoc} */ public function getHtml() { return $this->getDriver()->getHtml($this->getXpath()); } /** * Returns element outer html. * * @return string */ public function getOuterHtml() { return $this->getDriver()->getOuterHtml($this->getXpath()); } /** * Builds an ElementNotFoundException. * * @param string $type * @param string|null $selector * @param string|null $locator * * @return ElementNotFoundException * * @deprecated as of 1.7, to be removed in 2.0 */ protected function elementNotFound($type, $selector = null, $locator = null) { @trigger_error(sprintf('The method %s is deprecated as of 1.7 and will be removed in 2.0', __METHOD__), E_USER_DEPRECATED); return new ElementNotFoundException($this->driver, $type, $selector, $locator); } }