Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
ConditionsElement.php
Go to the documentation of this file.
1 <?php
8 
9 use Magento\Mtf\ObjectManager;
10 use Magento\Mtf\Client\Locator;
11 use Magento\Mtf\Client\ElementInterface;
12 
40 class ConditionsElement extends SimpleElement
41 {
45  const TRY_COUNT = 3;
46 
52  protected $mainCondition = './/ul[contains(@id,"__1__children")]/..';
53 
59  protected $chooserLocator = '.rule-chooser-trigger';
60 
66  protected $addNew = './/*[contains(@class,"rule-param-new-child")]/a';
67 
73  protected $remove = './/*/a[@class="rule-param-remove"]';
74 
80  protected $newCondition = './ul/li/span[contains(@class,"rule-param-new-child")]/..';
81 
87  protected $typeNew = './/*[@class="element"]/select';
88 
94  protected $created = './ul/li[span[contains(@class,"rule-param-new-child")]]/preceding-sibling::li[1]';
95 
101  protected $children = './/ul[contains(@id,"conditions__")]';
102 
108  protected $param = './span[span[*[substring(@id,(string-length(@id)-%d+1))="%s"]]]';
109 
115  protected $ruleParamWait = './/*[@class="rule-param-wait"]';
116 
122  protected $ruleParamInput = '[name^="rule"]';
123 
129  protected $applyRuleParam = './/*[@class="rule-param-apply"]';
130 
136  protected $chooserGridLocator = 'div[id*=chooser]';
137 
143  protected $findKeyParam = 0;
144 
150  protected $mapParams = [
151  'attribute',
152  'operator',
153  'value_type',
154  'value',
155  'aggregator',
156  ];
157 
163  protected $encodeChars = [
164  '\{' => '&lbrace;',
165  '\}' => '&rbrace;',
166  '\[' => '&lbracket;',
167  '\]' => '&rbracket;',
168  '\:' => '&colon;',
169  ];
170 
176  protected $decodeChars = [
177  '&lbrace;' => '{',
178  '&rbrace;' => '}',
179  '&lbracket;' => '[',
180  '&rbracket;' => ']',
181  '&colon;' => ':',
182  ];
183 
189  protected $exception;
190 
197  public function setValue($value)
198  {
199  $this->eventManager->dispatchEvent(['set_value'], [__METHOD__, $this->getAbsoluteSelector()]);
200  $this->clear();
201  $conditions = $this->decodeValue($value);
202  $context = $this->find($this->mainCondition, Locator::SELECTOR_XPATH);
203  if (!empty($conditions[0]['TopLevelCondition'])) {
204  array_unshift($this->mapParams, 'aggregator');
205  $condition = $this->parseTopLevelCondition($conditions[0]['TopLevelCondition']);
206  $this->fillCondition($condition['rules'], $context);
207  unset($conditions[0]);
208  array_shift($this->mapParams);
209  }
210  $this->addMultipleCondition($conditions, $context);
211  }
212 
220  protected function addConditionsCombination($condition, ElementInterface $context)
221  {
222  $condition = $this->parseCondition($condition);
223  $this->addCondition($condition['type'], $context);
224  $createdCondition = $context->find($this->created, Locator::SELECTOR_XPATH);
225  $this->waitForCondition($createdCondition);
226  if (!empty($condition['rules'])) {
227  $this->fillCondition($condition['rules'], $createdCondition);
228  }
229  return $createdCondition;
230  }
231 
239  protected function addMultipleCondition(array $conditions, ElementInterface $context)
240  {
241  foreach ($conditions as $key => $condition) {
242  $elementContext = is_numeric($key) ? $context : $this->addConditionsCombination($key, $context);
243  if (is_string($condition)) {
244  $this->addSingleCondition($condition, $elementContext);
245  } else {
246  $this->addMultipleCondition($condition, $elementContext);
247  }
248  }
249  }
250 
258  protected function addSingleCondition($condition, ElementInterface $context)
259  {
260  $condition = $this->parseCondition($condition);
261  $this->addCondition($condition['type'], $context);
262  $createdCondition = $context->find($this->created, Locator::SELECTOR_XPATH);
263  $this->waitForCondition($createdCondition);
264  $this->fillCondition($condition['rules'], $createdCondition);
265  }
266 
275  protected function addCondition($type, ElementInterface $context)
276  {
277  $newCondition = $context->find($this->newCondition, Locator::SELECTOR_XPATH);
278  $count = 0;
279 
280  do {
281  $newCondition->find($this->addNew, Locator::SELECTOR_XPATH)->click();
282 
283  try {
284  $newCondition->find($this->typeNew, Locator::SELECTOR_XPATH, 'select')->setValue($type);
285  $isSetType = true;
286  } catch (\PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
287  $isSetType = false;
288  $this->exception = $e;
289  $this->eventManager->dispatchEvent(['exception'], [__METHOD__, $this->getAbsoluteSelector()]);
290  }
291  $count++;
292  } while (!$isSetType && $count < self::TRY_COUNT);
293 
294  if (!$isSetType) {
295  $exception = $this->exception ? $this->exception : (new \Exception("Can not add condition: {$type}"));
296  throw $exception;
297  }
298  }
299 
311  protected function fillCondition(array $rules, ElementInterface $element)
312  {
313  $this->resetKeyParam();
314  foreach ($rules as $rule) {
316  $param = $this->findNextParam($element);
317  $isSet = false;
318  $count = 0;
319 
320  do {
321  try {
322  $openParamLink = $param->find('a');
323  if ($openParamLink->isVisible()) {
324  $openParamLink->click();
325  }
326  $this->waitUntil(function () use ($param) {
327  return $param->find($this->ruleParamInput)->isVisible() ? true : null;
328  });
329 
330  if ($this->fillGrid($rule, $param)) {
331  $isSet = true;
332  } elseif ($this->fillSelect($rule, $param)) {
333  $isSet = true;
334  } elseif ($this->fillText($rule, $param)) {
335  $isSet = true;
336  }
337  } catch (\PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {
338  $isSet = false;
339  $this->exception = $e;
340  $this->eventManager->dispatchEvent(['exception'], [__METHOD__, $this->getAbsoluteSelector()]);
341  }
342  $count++;
343  } while (!$isSet && $count < self::TRY_COUNT);
344 
345  if (!$isSet) {
346  $exception = $this->exception ? $this->exception : (new \Exception('Can not set value: ' . $rule));
347  throw $exception;
348  }
349  }
350  }
351 
359  protected function fillGrid($rule, ElementInterface $param)
360  {
361  if (preg_match('`%(.*?)%`', $rule, $chooserGrid)) {
362  $chooserConfig = explode('#', $chooserGrid[1]);
363  $rule = preg_replace('`%(.*?)%`', '', $rule);
364 
365  $param->find($this->chooserLocator)->click();
366  $grid = ObjectManager::getInstance()->create(
367  str_replace('/', '\\', $chooserConfig[0]),
368  [
369  'element' => $this->find($this->chooserGridLocator)
370  ]
371  );
372  $grid->searchAndSelect([$chooserConfig[1] => $rule]);
373 
374  $apply = $param->find($this->applyRuleParam, Locator::SELECTOR_XPATH);
375  if ($apply->isVisible()) {
376  $apply->click();
377  }
378 
379  return true;
380  }
381  return false;
382  }
383 
391  protected function fillSelect($rule, ElementInterface $param)
392  {
393  $value = $param->find('select', Locator::SELECTOR_TAG_NAME, 'select');
394  if ($value->isVisible()) {
395  $value->setValue($rule);
396  $this->click();
397 
398  return true;
399  }
400  return false;
401  }
402 
410  protected function fillText($rule, ElementInterface $param)
411  {
412  $value = $param->find('input', Locator::SELECTOR_TAG_NAME);
413  if ($value->isVisible()) {
414  $value->setValue($rule);
415 
416  $apply = $param->find('.//*[@class="rule-param-apply"]', Locator::SELECTOR_XPATH);
417  if ($apply->isVisible()) {
418  $apply->click();
419  }
420 
421  return true;
422  }
423  return false;
424  }
425 
433  protected function decodeValue($value)
434  {
435  $value = str_replace(array_keys($this->encodeChars), $this->encodeChars, $value);
436  $value = preg_replace('/(\]|})({|\[)/', '$1,$2', $value);
437  $value = preg_replace('/{([^:]+):/', '{"$1":', $value);
438  $value = preg_replace('/\[([^\[{])/', '"$1', $value);
439  $value = preg_replace('/([^\]}])\]/', '$1"', $value);
440  $value = str_replace(array_keys($this->decodeChars), $this->decodeChars, $value);
441  $value = "[{$value}]";
442  $value = json_decode($value, true);
443  if (null === $value) {
444  throw new \Exception('Bad format value.');
445  }
446  return $value;
447  }
448 
456  protected function parseCondition($condition)
457  {
458  if (!preg_match_all('/([^|]+\|?)/', $condition, $match)) {
459  throw new \Exception('Bad format condition');
460  }
461  foreach ($match[1] as $key => $value) {
462  $match[1][$key] = rtrim($value, '|');
463  }
464 
465  return [
466  'type' => array_shift($match[1]),
467  'rules' => array_values($match[1]),
468  ];
469  }
470 
478  protected function parseTopLevelCondition($condition)
479  {
480  if (preg_match_all('/([^|]+)\|?/', $condition, $match) === false) {
481  throw new \Exception('Bad format condition');
482  }
483 
484  return [
485  'rules' => $match[1],
486  ];
487  }
488 
496  protected function findNextParam(ElementInterface $context)
497  {
498  do {
499  if (!isset($this->mapParams[$this->findKeyParam])) {
500  throw new \Exception("Empty map of params");
501  }
502  $param = $this->mapParams[$this->findKeyParam];
503  $element = $context->find(sprintf($this->param, strlen($param), $param), Locator::SELECTOR_XPATH);
504  $this->findKeyParam += 1;
505  } while (!$element->isVisible());
506 
507  return $element;
508  }
509 
515  protected function resetKeyParam()
516  {
517  $this->findKeyParam = 0;
518  }
519 
526  protected function waitForCondition(ElementInterface $element)
527  {
528  $this->waitUntil(
529  function () use ($element) {
530  return $element->getAttribute('class') == 'rule-param-wait' ? null : true;
531  }
532  );
533  }
534 
540  protected function clear()
541  {
542  $remote = $this->find($this->remove, Locator::SELECTOR_XPATH);
543  while ($remote->isVisible()) {
544  $remote->click();
545  $remote = $this->find($this->remove, Locator::SELECTOR_XPATH);
546  }
547  }
548 
554  public function getValue()
555  {
556  return null;
557  }
558 }
addMultipleCondition(array $conditions, ElementInterface $context)
addSingleCondition($condition, ElementInterface $context)
addCondition($type, ElementInterface $context)
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
fillSelect($rule, ElementInterface $param)
addConditionsCombination($condition, ElementInterface $context)
$count
Definition: recent.phtml:13
taxRateField find('.mselect-list') .on( 'click.mselect-edit'
Definition: edit.phtml:162
fillText($rule, ElementInterface $param)
$type
Definition: item.phtml:13
$value
Definition: gender.phtml:16
fillGrid($rule, ElementInterface $param)
$element
Definition: element.phtml:12