Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
ActionGroupObject.php
Go to the documentation of this file.
1 <?php
8 
13 use Magento\FunctionalTestingFramework\Test\Util\ObjectExtension;
14 
19 {
20  const ACTION_GROUP_ORIGIN_NAME = "actionGroupName";
21  const ACTION_GROUP_ORIGIN_TEST_REF = "testInvocationRef";
23  "executeJS",
24  "magentoCLI",
25  "generateDate",
26  "formatMoney",
27  "deleteData",
28  "getData",
29  "updateData",
30  "createData",
31  "grabAttributeFrom",
32  "grabCookie",
33  "grabFromCurrentUrl",
34  "grabMultiple",
35  "grabPageSource",
36  "grabTextFrom",
37  "grabValueFrom"
38  ];
39 
44  private $varAttributes;
45 
51  private $name;
52 
58  private $parsedActions = [];
59 
65  private $arguments;
66 
72  private $parentActionGroup;
73 
82  public function __construct($name, $arguments, $actions, $parentActionGroup)
83  {
84  $this->varAttributes = array_merge(
87  );
88  $this->varAttributes[] = ActionObject::ACTION_ATTRIBUTE_URL;
89  $this->name = $name;
90  $this->arguments = $arguments;
91  $this->parsedActions = $actions;
92  $this->parentActionGroup = $parentActionGroup;
93  }
94 
103  public function getSteps($arguments, $actionReferenceKey)
104  {
105  $mergeUtil = new ActionMergeUtil($this->name, "ActionGroup");
106 
107  $args = $this->resolveArguments($arguments);
108 
109  return $mergeUtil->resolveActionSteps($this->getResolvedActionsWithArgs($args, $actionReferenceKey), true);
110  }
111 
118  private function resolveArguments($arguments)
119  {
120  $resolvedArgumentList = [];
121  $emptyArguments = [];
122 
123  foreach ($this->arguments as $argumentObj) {
124  if ($arguments !== null && array_key_exists($argumentObj->getName(), $arguments)) {
125  $resolvedArgumentList[] = new ArgumentObject(
126  $argumentObj->getName(),
127  $arguments[$argumentObj->getName()],
128  $argumentObj->getDataType()
129  );
130  } elseif ($argumentObj->getValue() === null) {
131  $emptyArguments[] = $argumentObj->getName();
132  } else {
133  $resolvedArgumentList[] = $argumentObj;
134  }
135  }
136 
137  if (!empty($emptyArguments)) {
138  $error = 'Arguments missed (' . implode(", ", $emptyArguments) . ') for actionGroup "' . $this->name . '"';
139  throw new TestReferenceException($error);
140  }
141 
142  return $resolvedArgumentList;
143  }
144 
153  private function getResolvedActionsWithArgs($arguments, $actionReferenceKey)
154  {
155  $resolvedActions = [];
156  $replacementStepKeys = [];
157 
158  foreach ($this->parsedActions as $action) {
159  $replacementStepKeys[$action->getStepKey()] = $action->getStepKey() . ucfirst($actionReferenceKey);
160  $varAttributes = array_intersect($this->varAttributes, array_keys($action->getCustomActionAttributes()));
161 
162  // replace createDataKey attributes inside the action group
163  $resolvedActionAttributes = $this->replaceCreateDataKeys($action, $replacementStepKeys);
164 
165  $newActionAttributes = [];
166 
167  if (!empty($varAttributes)) {
168  $newActionAttributes = $this->resolveAttributesWithArguments(
169  $arguments,
170  $resolvedActionAttributes
171  );
172  }
173 
174  // translate 0/1 back to before/after
176  if ($action->getOrderOffset() === 1) {
178  }
179 
180  // we append the action reference key to any linked action and the action's merge key as the user might
181  // use this action group multiple times in the same test.
182  $resolvedActions[$action->getStepKey() . ucfirst($actionReferenceKey)] = new ActionObject(
183  $action->getStepKey() . ucfirst($actionReferenceKey),
184  $action->getType(),
185  array_replace_recursive($resolvedActionAttributes, $newActionAttributes),
186  $action->getLinkedAction() == null ? null : $action->getLinkedAction() . ucfirst($actionReferenceKey),
187  $orderOffset,
188  [self::ACTION_GROUP_ORIGIN_NAME => $this->name,
189  self::ACTION_GROUP_ORIGIN_TEST_REF => $actionReferenceKey]
190  );
191  }
192 
193  return $resolvedActions;
194  }
195 
202  private function resolveAttributesWithArguments($arguments, $attributes)
203  {
204  // $regexPattern match on: $matches[0] {{section.element(arg.field)}}
205  // $matches[1] = section.element
206  // $matches[2] = arg.field
207  $regexPattern = '/{{([^(}]+)\(*([^)}]+)*\)*}}/';
208 
209  $newActionAttributes = [];
210  foreach ($attributes as $attributeKey => $attributeValue) {
211  if (is_array($attributeValue)) {
212  // attributes with child elements are parsed as an array, need make recursive call to resolve children
213  $newActionAttributes[$attributeKey] = $this->resolveAttributesWithArguments(
214  $arguments,
215  $attributeValue
216  );
217  continue;
218  }
219 
220  preg_match_all($regexPattern, $attributeValue, $matches);
221 
222  if (empty($matches[0])) {
223  continue;
224  }
225 
226  //get rid of full match {{arg.field(arg.field)}}
227  array_shift($matches);
228 
229  $newActionAttributes[$attributeKey] = $this->replaceAttributeArguments(
230  $arguments,
231  $attributeValue,
232  $matches
233  );
234  }
235  return $newActionAttributes;
236  }
237 
247  private function replaceAttributeArguments($arguments, $attributeValue, $matches)
248  {
249  list($mainValueList, $possibleArgumentsList) = $matches;
250 
251  foreach ($mainValueList as $index => $mainValue) {
252  $possibleArguments = $possibleArgumentsList[$index];
253 
254  $attributeValue = $this->replaceAttributeArgumentInVariable($mainValue, $arguments, $attributeValue);
255 
256  // Split on commas, trim all values, and finally filter out all FALSE values
257  $argumentList = array_filter(array_map('trim', explode(',', $possibleArguments)));
258 
259  foreach ($argumentList as $argumentValue) {
260  $attributeValue = $this->replaceAttributeArgumentInVariable(
261  $argumentValue,
262  $arguments,
263  $attributeValue,
264  true
265  );
266  }
267  }
268 
269  return $attributeValue;
270  }
271 
281  private function replaceAttributeArgumentInVariable(
282  $variable,
283  $arguments,
284  $attributeValue,
285  $isInnerArgument = false
286  ) {
287  // Truncate arg.field into arg
288  $variableName = strstr($variable, '.', true);
289  // Check if arguments has a mapping for the given variableName
290 
291  if ($variableName === false) {
292  $variableName = trim($variable, "'");
293  }
294 
295  $matchedArgument = $this->findArgumentByName($variableName, $arguments);
296  if ($matchedArgument === null) {
297  return $attributeValue;
298  }
299 
300  if ($matchedArgument->getDataType() === ArgumentObject::ARGUMENT_DATA_STRING) {
301  return $this->replaceSimpleArgument(
302  $matchedArgument->getResolvedValue($isInnerArgument),
303  $variableName,
304  $attributeValue,
305  $isInnerArgument
306  );
307  }
308 
309  $isPersisted = preg_match('/\$[\w.\[\]() ]+\$/', $matchedArgument->getResolvedValue($isInnerArgument));
310  if ($isPersisted) {
311  return $this->replacePersistedArgument(
312  $matchedArgument->getResolvedValue($isInnerArgument),
313  $attributeValue,
314  $variable,
315  $variableName,
316  $isInnerArgument
317  );
318  }
319 
320  //replace argument ONLY when there is no letters attached before after (ex. category.name vs categoryTreeButton)
321  return preg_replace(
322  "/(?<![\w]){$variableName}(?![(\w])/",
323  $matchedArgument->getResolvedValue($isInnerArgument),
324  $attributeValue
325  );
326  }
327 
337  private function replaceSimpleArgument($argumentValue, $variableName, $attributeValue, $isInnerArgument)
338  {
339  if ($isInnerArgument) {
340  return preg_replace("/(?<![\w]){$variableName}(?![(\w])/", $argumentValue, $attributeValue);
341  } else {
342  return str_replace("{{{$variableName}}}", $argumentValue, $attributeValue);
343  }
344  }
345 
355  private function replacePersistedArgument($replacement, $attributeValue, $fullVariable, $variable, $isParameter)
356  {
357  //hookPersisted will be true if replacement passed in is $$arg.field$$, otherwise assume it's $arg.field$
358  $hookPersistedArgumentRegex = '/\$\$[\w.\[\]\',]+\$\$/';
359  $hookPersisted = (preg_match($hookPersistedArgumentRegex, $replacement));
360 
361  $newAttributeValue = $attributeValue;
362 
363  $scope = '$';
364  if ($hookPersisted) {
365  $scope = '$$';
366  }
367 
368  // parameter replacements require changing of (arg.field) to ($arg.field$)
369  if ($isParameter) {
370  $fullReplacement = str_replace($variable, trim($replacement, '$'), trim($fullVariable, "'"));
371  $newAttributeValue = str_replace($fullVariable, $scope . $fullReplacement . $scope, $newAttributeValue);
372  } else {
373  $fullReplacement = str_replace($variable, trim($replacement, '$'), $fullVariable);
374  $newAttributeValue = str_replace(
375  '{{' . $fullVariable . '}}',
376  $scope . $fullReplacement . $scope,
377  $newAttributeValue
378  );
379  }
380 
381  return $newAttributeValue;
382  }
383 
388  public function extractStepKeys()
389  {
390  $originalKeys = [];
391  foreach ($this->parsedActions as $action) {
392  //limit actions returned to list that are relevant
393  foreach (self::STEPKEY_REPLACEMENT_ENABLED_TYPES as $actionValue) {
394  if ($actionValue === $action->getType()) {
395  $originalKeys[] = $action->getStepKey();
396  }
397  }
398  }
399  return $originalKeys;
400  }
401 
407  public function getName()
408  {
409  return $this->name;
410  }
411 
417  public function getParentName()
418  {
419  return $this->parentActionGroup;
420  }
421 
427  public function getActions()
428  {
429  return $this->parsedActions;
430  }
431 
437  public function getArguments()
438  {
439  return $this->arguments;
440  }
441 
448  private function findArgumentByName($name, $argumentList)
449  {
450  $matchedArgument = array_filter(
451  $argumentList,
452  function ($e) use ($name) {
453  return $e->getName() == $name;
454  }
455  );
456  if (isset(array_values($matchedArgument)[0])) {
457  return array_values($matchedArgument)[0];
458  }
459  return null;
460  }
461 
469  private function replaceCreateDataKeys($action, $replacementStepKeys)
470  {
471  $resolvedActionAttributes = [];
472 
473  foreach ($action->getCustomActionAttributes() as $actionAttribute => $actionAttributeDetails) {
474  if (is_array($actionAttributeDetails) && array_key_exists('createDataKey', $actionAttributeDetails)) {
475  $actionAttributeDetails['createDataKey'] =
476  $replacementStepKeys[$actionAttributeDetails['createDataKey']] ??
477  $actionAttributeDetails['createDataKey'];
478  }
479  $resolvedActionAttributes[$actionAttribute] = $actionAttributeDetails;
480  }
481 
482  return $resolvedActionAttributes;
483  }
484 }
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
__construct($name, $arguments, $actions, $parentActionGroup)
$replacement
Definition: website.php:23
$variable
Definition: variable.php:7
$attributes
Definition: matrix.phtml:13
$index
Definition: list.phtml:44