1212use Magento \AcceptanceTestFramework \Page \Objects \SectionObject ;
1313use Magento \AcceptanceTestFramework \Page \Handlers \PageObjectHandler ;
1414use Magento \AcceptanceTestFramework \Page \Handlers \SectionObjectHandler ;
15+ use Magento \AcceptanceTestFramework \Test \Managers \CestArrayProcessor ;
1516
1617/**
1718 * Class ActionObject
@@ -22,7 +23,9 @@ class ActionObject
2223 const MERGE_ACTION_ORDER_AFTER = 'after ' ;
2324 const ACTION_ATTRIBUTE_URL = 'url ' ;
2425 const ACTION_ATTRIBUTE_SELECTOR = 'selector ' ;
26+ const ACTION_ATTRIBUTE_VARIABLE_REGEX_PARAMETER = '/\(.+\)/ ' ;
2527 const ACTION_ATTRIBUTE_VARIABLE_REGEX_PATTERN = '/{{[\w.\[\]]+}}/ ' ;
28+ const ACTION_ATTRIBUTE_VARIABLE_REGEX_NESTED = '/{{[\w.\[\]() \',${} ]+}}/ ' ;
2629
2730 /**
2831 * The unique identifier for the action
@@ -246,16 +249,39 @@ private function resolveDataInputReferences()
246249
247250 /**
248251 * Return an array containing the name (before the period) and key (after the period) in a {{reference.foo}}.
252+ * Also truncates variables inside parenthesis.
249253 *
250254 * @param string $reference
251255 * @return string[] The name and key that is referenced.
252256 */
253257 private function stripAndSplitReference ($ reference )
254258 {
255259 $ strippedReference = str_replace ('}} ' , '' , str_replace ('{{ ' , '' , $ reference ));
260+ $ strippedReference = preg_replace (
261+ ActionObject::ACTION_ATTRIBUTE_VARIABLE_REGEX_PARAMETER ,
262+ '' ,
263+ $ strippedReference
264+ );
256265 return explode ('. ' , $ strippedReference );
257266 }
258267
268+ /**
269+ * Returns an array containing all parameters found inside () block of test input.
270+ * Returns null if no parameters were found.
271+ *
272+ * @param string $reference
273+ * @return array|null
274+ */
275+ private function stripAndReturnParameters ($ reference )
276+ {
277+ preg_match (ActionObject::ACTION_ATTRIBUTE_VARIABLE_REGEX_PARAMETER , $ reference , $ matches );
278+ if (!empty ($ matches )) {
279+ $ strippedReference = str_replace (') ' , '' , str_replace ('( ' , '' , $ matches [0 ]));
280+ return explode (', ' , $ strippedReference );
281+ }
282+ return null ;
283+ }
284+
259285 /**
260286 * Return a string based on a reference to a page, section, or data field (e.g. {{foo.ref}} resolves to 'data')
261287 *
@@ -266,16 +292,24 @@ private function stripAndSplitReference($reference)
266292 */
267293 private function findAndReplaceReferences ($ objectHandler , $ inputString )
268294 {
269- preg_match_all (ActionObject::ACTION_ATTRIBUTE_VARIABLE_REGEX_PATTERN , $ inputString , $ matches );
295+ //Determine if there are Parethesis and parameters. If not, use strict regex. If so, use nested regex.
296+ preg_match_all (ActionObject::ACTION_ATTRIBUTE_VARIABLE_REGEX_PATTERN , $ inputString , $ variableMatches );
297+ if (!empty ($ variableMatches [0 ])) {
298+ $ regex = ActionObject::ACTION_ATTRIBUTE_VARIABLE_REGEX_PATTERN ;
299+ } else {
300+ $ regex = ActionObject::ACTION_ATTRIBUTE_VARIABLE_REGEX_NESTED ;
301+ }
302+ preg_match_all ($ regex , $ inputString , $ matches );
270303
271304 if (empty ($ matches [0 ])) {
272- return null ;
305+ return $ inputString ;
273306 }
274307
275308 $ outputString = $ inputString ;
276309
277310 foreach ($ matches [0 ] as $ match ) {
278311 $ replacement = null ;
312+ $ parameterized = false ;
279313 list ($ objName ) = $ this ->stripAndSplitReference ($ match );
280314
281315 $ obj = $ objectHandler ->getObject ($ objName );
@@ -284,11 +318,12 @@ private function findAndReplaceReferences($objectHandler, $inputString)
284318 switch (get_class ($ obj )) {
285319 case PageObject::class:
286320 $ replacement = $ obj ->getUrl ();
321+ $ parameterized = $ obj ->isParameterized ();
287322 break ;
288323 case SectionObject::class:
289324 list (,$ objField ) = $ this ->stripAndSplitReference ($ match );
325+ $ parameterized = $ obj ->getElement ($ objField )->isParameterized ();
290326 $ replacement = $ obj ->getElement ($ objField )->getLocator ();
291- $ this ->timeout = $ obj ->getElement ($ objField )->getTimeout ();
292327 break ;
293328 case (get_class ($ obj ) == EntityDataObject::class):
294329 list (,$ objField ) = $ this ->stripAndSplitReference ($ match );
@@ -315,10 +350,13 @@ private function findAndReplaceReferences($objectHandler, $inputString)
315350 throw new \Exception ("Could not resolve entity reference " . $ inputString );
316351 }
317352
353+ //If Page or Section's Element is has parameterized = true attribute, attempt to do parameter replacement.
354+ if ($ parameterized ) {
355+ $ parameterList = $ this ->stripAndReturnParameters ($ match );
356+ $ replacement = $ this ->matchParameterReferences ($ replacement , $ parameterList );
357+ }
318358 $ outputString = str_replace ($ match , $ replacement , $ outputString );
319-
320359 }
321-
322360 return $ outputString ;
323361 }
324362
@@ -343,4 +381,44 @@ private function resolveEntityDataUniquenessReference($reference, $entityDataObj
343381 }
344382 return $ reference ;
345383 }
384+
385+ /**
386+ * Finds all {{var}} occurrences in reference, and replaces them in sequence with parameters list given.
387+ * Parameter list given is also resolved, attempting to match {{data.field}} references.
388+ *
389+ * @param string $reference
390+ * @param array $parameters
391+ * @return string
392+ * @throws \Exception
393+ */
394+ private function matchParameterReferences ($ reference , $ parameters )
395+ {
396+ preg_match_all ('/{{[\w.]+}}/ ' , $ reference , $ varMatches );
397+ if (count ($ varMatches [0 ]) > count ($ parameters )) {
398+ throw new \Exception (
399+ "Parameter Resolution Failed: Not enough parameters given for reference " .
400+ $ reference . ". Parameters Given: " . implode (", " , $ parameters )
401+ );
402+ } elseif (count ($ varMatches [0 ]) < count ($ parameters )) {
403+ throw new \Exception (
404+ "Parameter Resolution Failed: Too many parameters given for reference " .
405+ $ reference . ". Parameters Given: " . implode (", " , $ parameters )
406+ );
407+ }
408+
409+ //Attempt to Resolve {{data}} references to actual output.
410+ $ resolvedParameters = [];
411+ foreach ($ parameters as $ parameter ) {
412+ $ resolvedParameters [] = $ this ->findAndReplaceReferences (
413+ DataObjectHandler::getInstance (),
414+ $ parameter
415+ );
416+ }
417+
418+ $ resolveIndex = 0 ;
419+ foreach ($ varMatches [0 ] as $ var ) {
420+ $ reference = str_replace ($ var , $ resolvedParameters [$ resolveIndex ++], $ reference );
421+ }
422+ return $ reference ;
423+ }
346424}
0 commit comments