Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
ActionMergeUtil.php
Go to the documentation of this file.
1 <?php
8 
13 
18 {
20  "Merge Error - Step could not be found in either TestXML or DeltaXML.
21  \t%s: '%s'\tTestStep: '%s'\tLinkedStep: '%s'";
22 
23  const WAIT_ATTR = 'timeout';
24  const WAIT_ACTION_NAME = 'waitForPageLoad';
25  const WAIT_ACTION_SUFFIX = 'WaitForPageLoad';
26  const SKIP_READINESS_ACTION_NAME = 'skipReadinessCheck';
27  const SKIP_READINESS_OFF_SUFFIX = 'SkipReadinessOff';
28  const SKIP_READINESS_ON_SUFFIX = 'SkipReadinessOn';
29  const DEFAULT_SKIP_ON_ORDER = 'before';
30  const DEFAULT_SKIP_OFF_ORDER = 'after';
31  const DEFAULT_WAIT_ORDER = 'after';
32 
38  private $orderedSteps = [];
39 
45  private $stepsToMerge = [];
46 
52  private $name;
53 
59  private $type;
60 
67  public function __construct($contextName, $contextType)
68  {
69  $this->name = $contextName;
70  $this->type = $contextType;
71  }
72 
82  public function resolveActionSteps($parsedSteps, $skipActionGroupResolution = false)
83  {
84  $this->mergeActions($parsedSteps);
85  $this->insertWaits();
86  $this->insertReadinessSkips();
87 
88  if ($skipActionGroupResolution) {
89  return $this->orderedSteps;
90  }
91 
92  $resolvedActions = $this->resolveActionGroups($this->orderedSteps);
93  return $this->resolveSecretFieldAccess($resolvedActions);
94  }
95 
104  private function resolveSecretFieldAccess($resolvedActions)
105  {
106  $actions = [];
107  foreach ($resolvedActions as $resolvedAction) {
108  $action = $resolvedAction;
109  $hasSecretRef = $this->actionAttributeContainsSecretRef($resolvedAction->getCustomActionAttributes());
110 
111  if ($resolvedAction->getType() !== 'fillField' && $hasSecretRef) {
112  throw new TestReferenceException("You cannot reference secret data outside of fill field actions");
113  }
114 
115  if ($resolvedAction->getType() === 'fillField' && $hasSecretRef) {
116  $action = new ActionObject(
117  $action->getStepKey(),
118  'fillSecretField',
119  $action->getCustomActionAttributes(),
120  $action->getLinkedAction(),
121  $action->getActionOrigin()
122  );
123  }
124 
125  $actions[$action->getStepKey()] = $action;
126  }
127 
128  return $actions;
129  }
130 
137  private function actionAttributeContainsSecretRef($actionAttributes)
138  {
139  foreach ($actionAttributes as $actionAttribute) {
140  if (is_array($actionAttribute)) {
141  return $this->actionAttributeContainsSecretRef($actionAttribute);
142  }
143 
144  preg_match_all("/{{_CREDS\.([\w]+)}}/", $actionAttribute, $matches);
145 
146  if (!empty($matches[0])) {
147  return true;
148  }
149  }
150 
151  return false;
152  }
153 
161  private function resolveActionGroups($mergedSteps)
162  {
163  $newOrderedList = [];
164 
165  foreach ($mergedSteps as $key => $mergedStep) {
167  if ($mergedStep->getType() == ActionObjectExtractor::ACTION_GROUP_TAG) {
168  $actionGroupRef = $mergedStep->getCustomActionAttributes()[ActionObjectExtractor::ACTION_GROUP_REF];
169  $actionGroup = ActionGroupObjectHandler::getInstance()->getObject($actionGroupRef);
170  if ($actionGroup == null) {
171  throw new TestReferenceException("Could not find ActionGroup by ref \"{$actionGroupRef}\"");
172  }
173  $args = $mergedStep->getCustomActionAttributes()[ActionObjectExtractor::ACTION_GROUP_ARGUMENTS] ?? null;
174  $actionsToMerge = $actionGroup->getSteps($args, $key);
175  $newOrderedList = $newOrderedList + $actionsToMerge;
176  } else {
177  $newOrderedList[$key] = $mergedStep;
178  }
179  }
180 
181  return $newOrderedList;
182  }
183 
191  private function mergeActions($parsedSteps)
192  {
193  $this->sortActions($parsedSteps);
194 
195  foreach ($this->stepsToMerge as $stepName => $stepToMerge) {
196  if (!array_key_exists($stepName, $this->orderedSteps)) {
197  $this->mergeAction($stepToMerge);
198  }
199  }
200  unset($stepName);
201  unset($stepToMerge);
202  }
203 
209  private function insertWaits()
210  {
211  foreach ($this->orderedSteps as $step) {
212  if ($step->getTimeout()) {
213  $waitStepAttributes = [self::WAIT_ATTR => $step->getTimeout()];
214  $waitStep = new ActionObject(
215  $step->getStepKey() . self::WAIT_ACTION_SUFFIX,
217  $waitStepAttributes,
218  $step->getStepKey(),
220  );
221  $this->insertStep($waitStep);
222  }
223  }
224  }
225 
231  private function insertReadinessSkips()
232  {
233  foreach ($this->orderedSteps as $step) {
234  if (array_key_exists("skipReadiness", $step->getCustomActionAttributes())) {
235  if ($step->getCustomActionAttributes()['skipReadiness'] == "true") {
236  $skipReadinessOn = new ActionObject(
237  $step->getStepKey() . self::SKIP_READINESS_ON_SUFFIX,
239  ['state' => "true"],
240  $step->getStepKey(),
242  );
243 
244  $skipReadinessOff = new ActionObject(
245  $step->getStepKey() . self::SKIP_READINESS_OFF_SUFFIX,
247  ['state' => "false"],
248  $step->getStepKey(),
250  );
251 
252  $this->insertStep($skipReadinessOn);
253  $this->insertStep($skipReadinessOff);
254  }
255  }
256  }
257  }
258 
266  private function sortActions($parsedSteps)
267  {
268  foreach ($parsedSteps as $parsedStep) {
269  try {
270  $parsedStep->resolveReferences();
271 
272  if ($parsedStep->getLinkedAction()) {
273  $this->stepsToMerge[$parsedStep->getStepKey()] = $parsedStep;
274  } else {
275  $this->orderedSteps[$parsedStep->getStepKey()] = $parsedStep;
276  }
277  } catch (\Exception $e) {
278  throw new TestReferenceException(
279  $e->getMessage() .
280  ".\nException occurred parsing action at StepKey \"" . $parsedStep->getStepKey() . "\""
281  );
282  }
283  }
284  }
285 
293  private function mergeAction($stepToMerge)
294  {
295  $linkedStep = $stepToMerge->getLinkedAction();
296 
297  if (!array_key_exists($linkedStep, $this->orderedSteps)
298  and
299  !array_key_exists($linkedStep, $this->stepsToMerge)) {
300  throw new XmlException(sprintf(
301  self::STEP_MISSING_ERROR_MSG,
302  $this->type,
303  $this->name,
304  $stepToMerge->getStepKey(),
305  $linkedStep
306  ));
307  } elseif (!array_key_exists($linkedStep, $this->orderedSteps)) {
308  $this->mergeAction($this->stepsToMerge[$linkedStep]);
309  }
310 
311  $this->insertStep($stepToMerge);
312  }
313 
320  private function insertStep($stepToMerge)
321  {
322  $position = array_search(
323  $stepToMerge->getLinkedAction(),
324  array_keys($this->orderedSteps)
325  ) + $stepToMerge->getOrderOffset();
326  $previous_items = array_slice($this->orderedSteps, 0, $position, true);
327  $next_items = array_slice($this->orderedSteps, $position, null, true);
328  $this->orderedSteps = $previous_items + [$stepToMerge->getStepKey() => $stepToMerge] + $next_items;
329  }
330 }
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
resolveActionSteps($parsedSteps, $skipActionGroupResolution=false)