/dev/tests/functional/lib/Magento/Mtf/Client/Element/MultiselectgrouplistElement.php

https://gitlab.com/LisovyiEvhenii/ismextensions · PHP · 331 lines · 205 code · 20 blank · 106 comment · 6 complexity · 25cc815c3e9c42a828aece900e91ddac MD5 · raw file

  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magento.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magento.com for more information.
  20. *
  21. * @category Tests
  22. * @package Tests_Functional
  23. * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. namespace Magento\Mtf\Client\Element;
  27. use Magento\Mtf\Client\Locator;
  28. use Magento\Mtf\Client\ElementInterface;
  29. /**
  30. * Typified element class for multiselect with group.
  31. */
  32. class MultiselectgrouplistElement extends MultiselectElement
  33. {
  34. /**
  35. * Indent length.
  36. */
  37. const INDENT_LENGTH = 4;
  38. /**
  39. * Locator for search optgroup by label.
  40. *
  41. * @var string
  42. */
  43. protected $optgroupByLabel = './/optgroup[@label="%s"]';
  44. /**
  45. * Locator for search optgroup by number.
  46. *
  47. * @var string
  48. */
  49. protected $optgroupByNumber = './/optgroup[%d]';
  50. /**
  51. * Locator for search next optgroup.
  52. *
  53. * @var string
  54. */
  55. protected $nextOptgroup = './/following-sibling::optgroup[%d]';
  56. /**
  57. * Locator for search child optgroup.
  58. *
  59. * @var string
  60. */
  61. protected $childOptgroup = ".//following-sibling::optgroup[%d][@label='%s']";
  62. /**
  63. * Locator for search parent optgroup.
  64. *
  65. * @var string
  66. */
  67. protected $parentOptgroup = 'optgroup[option[text()="%s"]]';
  68. /**
  69. * Locator for search preceding sibling optgroup.
  70. *
  71. * @var string
  72. */
  73. protected $precedingOptgroup = '/preceding-sibling::optgroup[1][substring(@label,1,%d)="%s"]';
  74. /**
  75. * Locator for option.
  76. *
  77. * @var string
  78. */
  79. protected $option = './/option[text()="%s"]';
  80. /**
  81. * Locator search for option by number.
  82. *
  83. * @var string
  84. */
  85. protected $childOptionByNumber = './/optgroup[%d]/option[%d]';
  86. /**
  87. * Locator for search parent option.
  88. *
  89. * @var string
  90. */
  91. protected $optionByNumber = './option[%d]';
  92. /**
  93. * Indent, four symbols non breaking space.
  94. *
  95. * @var string
  96. */
  97. protected $indent = "\xC2\xA0\xC2\xA0\xC2\xA0\xC2\xA0";
  98. /**
  99. * Trim symbols.
  100. *
  101. * @var string
  102. */
  103. protected $trim = "\xC2\xA0 ";
  104. /**
  105. * Set values.
  106. *
  107. * @param array|string $values
  108. * @return void
  109. */
  110. public function setValue($values)
  111. {
  112. $this->deselectAll();
  113. $values = is_array($values) ? $values : [$values];
  114. foreach ($values as $value) {
  115. $this->selectOption($value);
  116. }
  117. }
  118. /**
  119. * Select option.
  120. *
  121. * @param string $option
  122. * @return void
  123. * @throws \Exception
  124. */
  125. protected function selectOption($option)
  126. {
  127. $isOptgroup = false;
  128. $optgroupIndent = '';
  129. $values = explode('/', $option);
  130. $context = $this;
  131. foreach ($values as $value) {
  132. $optionIndent = $isOptgroup ? $this->indent : '';
  133. $optionElement = $context->find(sprintf($this->option, $optionIndent . $value), Locator::SELECTOR_XPATH);
  134. if ($optionElement->isVisible()) {
  135. if (!$optionElement->isSelected()) {
  136. $optionElement->click();
  137. }
  138. return;
  139. }
  140. $value = $optgroupIndent . $value;
  141. $optgroupIndent .= $this->indent;
  142. if ($isOptgroup) {
  143. $context = $this->getChildOptgroup($value, $context);
  144. } else {
  145. $context = $this->getOptgroup($value, $context);
  146. $isOptgroup = true;
  147. }
  148. }
  149. throw new \Exception("Can't find option \"{$option}\".");
  150. }
  151. /**
  152. * Get optgroup.
  153. *
  154. * @param string $value
  155. * @param ElementInterface $context
  156. * @return ElementInterface
  157. * @throws \Exception
  158. */
  159. protected function getOptgroup($value, ElementInterface $context)
  160. {
  161. $optgroup = $context->find(sprintf($this->optgroupByLabel, $value), Locator::SELECTOR_XPATH);
  162. if (!$optgroup->isVisible()) {
  163. throw new \Exception("Can't find group \"{$value}\".");
  164. }
  165. return $optgroup;
  166. }
  167. /**
  168. * Get child optgroup.
  169. *
  170. * @param string $value
  171. * @param ElementInterface $context
  172. * @return ElementInterface
  173. * @throws \Exception
  174. */
  175. protected function getChildOptgroup($value, ElementInterface $context)
  176. {
  177. $childOptgroup = null;
  178. $count = 1;
  179. while (!$childOptgroup) {
  180. $optgroup = $context->find(sprintf($this->nextOptgroup, $count), Locator::SELECTOR_XPATH);
  181. if (!$optgroup->isVisible()) {
  182. throw new \Exception("Can't find child group \"{$value}\"");
  183. }
  184. $childOptgroup = $context->find(
  185. sprintf($this->childOptgroup, $count, $value),
  186. Locator::SELECTOR_XPATH
  187. );
  188. if (!$childOptgroup->isVisible()) {
  189. $childOptgroup = null;
  190. }
  191. ++$count;
  192. }
  193. return $childOptgroup;
  194. }
  195. /**
  196. * Get value.
  197. *
  198. * @return array
  199. * @SuppressWarnings(PHPMD.NPathComplexity)
  200. */
  201. public function getValue()
  202. {
  203. $values = [];
  204. $indentOption = str_repeat(' ', self::INDENT_LENGTH);
  205. foreach ($this->getSelectedOptions() as $option) {
  206. $value = [];
  207. /** @var ElementInterface $option */
  208. $optionText = $option->getText();
  209. $optionValue = trim($optionText, $this->trim);
  210. $value[] = $optionValue;
  211. if (0 !== strpos($optionText, $indentOption)) {
  212. $values[] = implode('/', $value);
  213. continue;
  214. }
  215. $pathOptgroup = sprintf($this->parentOptgroup, $this->indent . $optionValue);
  216. $optgroup = $this->find($pathOptgroup, Locator::SELECTOR_XPATH);
  217. $optgroupText = $optgroup->getAttribute('label');
  218. $optgroupValue = trim($optgroupText, $this->trim);
  219. $amountIndent = strlen($optgroupText) - strlen($optgroupValue);
  220. $amountIndent = $amountIndent ? ($amountIndent / strlen($this->indent)) : 0;
  221. $value[] = $optgroupValue;
  222. if (0 == $amountIndent) {
  223. $values[] = implode('/', $value);
  224. continue;
  225. }
  226. --$amountIndent;
  227. $indent = $amountIndent ? str_repeat($this->indent, $amountIndent) : '';
  228. $pathOptgroup .= sprintf($this->precedingOptgroup, $amountIndent * self::INDENT_LENGTH, $indent);
  229. while (0 <= $amountIndent && $this->find($pathOptgroup, Locator::SELECTOR_XPATH)->isVisible()) {
  230. $optgroup = $this->find($pathOptgroup, Locator::SELECTOR_XPATH);
  231. $optgroupText = $optgroup->getAttribute('label');
  232. $optgroupValue = trim($optgroupText, $this->trim);
  233. $value[] = $optgroupValue;
  234. --$amountIndent;
  235. $indent = (0 < $amountIndent) ? str_repeat($this->indent, $amountIndent) : '';
  236. $pathOptgroup .= sprintf($this->precedingOptgroup, $amountIndent * self::INDENT_LENGTH, $indent);
  237. }
  238. $values[] = implode('/', array_reverse($value));
  239. }
  240. return $values;
  241. }
  242. /**
  243. * Get options.
  244. *
  245. * @return ElementInterface[]
  246. */
  247. protected function getOptions()
  248. {
  249. $options = [];
  250. $countOption = 1;
  251. $option = $this->find(sprintf($this->optionByNumber, $countOption), Locator::SELECTOR_XPATH);
  252. while ($option->isVisible()) {
  253. $options[] = $option;
  254. ++$countOption;
  255. $option = $this->find(sprintf($this->optionByNumber, $countOption), Locator::SELECTOR_XPATH);
  256. }
  257. $countOptgroup = 1;
  258. $optgroup = $this->find(sprintf($this->optgroupByNumber, $countOptgroup), Locator::SELECTOR_XPATH);
  259. while ($optgroup->isVisible()) {
  260. $countOption = 1;
  261. $option = $this->find(
  262. sprintf($this->childOptionByNumber, $countOptgroup, $countOption),
  263. Locator::SELECTOR_XPATH
  264. );
  265. while ($option->isVisible()) {
  266. $options[] = $option;
  267. ++$countOption;
  268. $option = $this->find(
  269. sprintf($this->childOptionByNumber, $countOptgroup, $countOption),
  270. Locator::SELECTOR_XPATH
  271. );
  272. }
  273. ++$countOptgroup;
  274. $optgroup = $this->find(sprintf($this->optgroupByNumber, $countOptgroup), Locator::SELECTOR_XPATH);
  275. }
  276. return $options;
  277. }
  278. /**
  279. * Get selected options.
  280. *
  281. * @return array
  282. */
  283. protected function getSelectedOptions()
  284. {
  285. $options = [];
  286. foreach ($this->getOptions() as $option) {
  287. if ($option->isSelected()) {
  288. $options[] = $option;
  289. }
  290. }
  291. return $options;
  292. }
  293. }