Element.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <?php
  2. /*
  3. * This file is part of the Mink package.
  4. * (c) Konstantin Kudryashov <ever.zet@gmail.com>
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. namespace Behat\Mink\Element;
  10. use Behat\Mink\Driver\DriverInterface;
  11. use Behat\Mink\Exception\ElementNotFoundException;
  12. use Behat\Mink\Selector\SelectorsHandler;
  13. use Behat\Mink\Selector\Xpath\Manipulator;
  14. use Behat\Mink\Session;
  15. /**
  16. * Base element.
  17. *
  18. * @author Konstantin Kudryashov <ever.zet@gmail.com>
  19. */
  20. abstract class Element implements ElementInterface
  21. {
  22. /**
  23. * @var Session
  24. */
  25. private $session;
  26. /**
  27. * Driver.
  28. *
  29. * @var DriverInterface
  30. */
  31. private $driver;
  32. /**
  33. * @var SelectorsHandler
  34. */
  35. private $selectorsHandler;
  36. /**
  37. * @var Manipulator
  38. */
  39. private $xpathManipulator;
  40. /**
  41. * Initialize element.
  42. *
  43. * @param Session $session
  44. */
  45. public function __construct(Session $session)
  46. {
  47. $this->xpathManipulator = new Manipulator();
  48. $this->session = $session;
  49. $this->driver = $session->getDriver();
  50. $this->selectorsHandler = $session->getSelectorsHandler();
  51. }
  52. /**
  53. * Returns element session.
  54. *
  55. * @return Session
  56. *
  57. * @deprecated Accessing the session from the element is deprecated as of 1.6 and will be impossible in 2.0.
  58. */
  59. public function getSession()
  60. {
  61. @trigger_error(sprintf('The method %s is deprecated as of 1.6 and will be removed in 2.0', __METHOD__), E_USER_DEPRECATED);
  62. return $this->session;
  63. }
  64. /**
  65. * Returns element's driver.
  66. *
  67. * @return DriverInterface
  68. */
  69. protected function getDriver()
  70. {
  71. return $this->driver;
  72. }
  73. /**
  74. * Returns selectors handler.
  75. *
  76. * @return SelectorsHandler
  77. *
  78. * @deprecated Accessing the selectors handler in the element is deprecated as of 1.7 and will be impossible in 2.0.
  79. */
  80. protected function getSelectorsHandler()
  81. {
  82. @trigger_error(sprintf('The method %s is deprecated as of 1.7 and will be removed in 2.0', __METHOD__), E_USER_DEPRECATED);
  83. return $this->selectorsHandler;
  84. }
  85. /**
  86. * {@inheritdoc}
  87. */
  88. public function has($selector, $locator)
  89. {
  90. return null !== $this->find($selector, $locator);
  91. }
  92. /**
  93. * {@inheritdoc}
  94. */
  95. public function isValid()
  96. {
  97. return 1 === count($this->getDriver()->find($this->getXpath()));
  98. }
  99. /**
  100. * {@inheritdoc}
  101. */
  102. public function waitFor($timeout, $callback)
  103. {
  104. if (!is_callable($callback)) {
  105. throw new \InvalidArgumentException('Given callback is not a valid callable');
  106. }
  107. $start = microtime(true);
  108. $end = $start + $timeout;
  109. do {
  110. $result = call_user_func($callback, $this);
  111. if ($result) {
  112. break;
  113. }
  114. usleep(100000);
  115. } while (microtime(true) < $end);
  116. return $result;
  117. }
  118. /**
  119. * {@inheritdoc}
  120. */
  121. public function find($selector, $locator)
  122. {
  123. $items = $this->findAll($selector, $locator);
  124. return count($items) ? current($items) : null;
  125. }
  126. /**
  127. * {@inheritdoc}
  128. */
  129. public function findAll($selector, $locator)
  130. {
  131. if ('named' === $selector) {
  132. $items = $this->findAll('named_exact', $locator);
  133. if (empty($items)) {
  134. $items = $this->findAll('named_partial', $locator);
  135. }
  136. return $items;
  137. }
  138. $xpath = $this->selectorsHandler->selectorToXpath($selector, $locator);
  139. $xpath = $this->xpathManipulator->prepend($xpath, $this->getXpath());
  140. return $this->getDriver()->find($xpath);
  141. }
  142. /**
  143. * {@inheritdoc}
  144. */
  145. public function getText()
  146. {
  147. return $this->getDriver()->getText($this->getXpath());
  148. }
  149. /**
  150. * {@inheritdoc}
  151. */
  152. public function getHtml()
  153. {
  154. return $this->getDriver()->getHtml($this->getXpath());
  155. }
  156. /**
  157. * Returns element outer html.
  158. *
  159. * @return string
  160. */
  161. public function getOuterHtml()
  162. {
  163. return $this->getDriver()->getOuterHtml($this->getXpath());
  164. }
  165. /**
  166. * Builds an ElementNotFoundException.
  167. *
  168. * @param string $type
  169. * @param string|null $selector
  170. * @param string|null $locator
  171. *
  172. * @return ElementNotFoundException
  173. *
  174. * @deprecated as of 1.7, to be removed in 2.0
  175. */
  176. protected function elementNotFound($type, $selector = null, $locator = null)
  177. {
  178. @trigger_error(sprintf('The method %s is deprecated as of 1.7 and will be removed in 2.0', __METHOD__), E_USER_DEPRECATED);
  179. return new ElementNotFoundException($this->driver, $type, $selector, $locator);
  180. }
  181. }