diff --git a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php index 58d832c43..4f533aaab 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php +++ b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php @@ -84,23 +84,23 @@ private function getResolvedActionsWithArgs($arguments, $actionReferenceKey) // $regexPattern match on: $matches[0] {{section.element(arg.field)}} // $matches[1] = section.element // $matches[2] = arg.field - $regexPattern = '/{{([\w.\[\]]+)\(*([\w.$\']+)*\)*}}/'; + $regexPattern = '/{{([\w.\[\]]+)\(*([\w.$\',\s]+)*\)*}}/'; foreach ($this->parsedActions as $action) { $varAttributes = array_intersect(self::VAR_ATTRIBUTES, array_keys($action->getCustomActionAttributes())); $newActionAttributes = []; + if (!empty($varAttributes)) { // 1 check to see if we have pertinent var foreach ($varAttributes as $varAttribute) { $attributeValue = $action->getCustomActionAttributes()[$varAttribute]; preg_match_all($regexPattern, $attributeValue, $matches); - if (empty($matches[0])) { continue; } //get rid of full match {{arg.field(arg.field)}} - unset($matches[0]); + array_shift($matches); $newActionAttributes[$varAttribute] = $this->replaceAttributeArguments( $arguments, @@ -132,36 +132,68 @@ private function getResolvedActionsWithArgs($arguments, $actionReferenceKey) */ private function replaceAttributeArguments($arguments, $attributeValue, $matches) { - $matchParametersKey = 2; - $newAttributeVal = $attributeValue; + list($mainValueList, $possibleArgumentsList) = $matches; - foreach ($matches as $key => $match) { - foreach ($match as $variable) { - if (empty($variable)) { - continue; - } - // Truncate arg.field into arg. If 'Literal' was passed, variableName will be null. - $variableName = strstr($variable, '.', true); - // Check if arguments has a mapping for the given variableName - if ($variableName == null || !array_key_exists($variableName, $arguments)) { - continue; - } - $isPersisted = strstr($arguments[$variableName], '$'); - if ($isPersisted) { - $newAttributeVal = $this->replacePersistedArgument( - $arguments[$variableName], - $attributeValue, - $variable, - $variableName, - $key == $matchParametersKey ? true : false - ); - } else { - $newAttributeVal = str_replace($variableName, $arguments[$variableName], $attributeValue); - } + foreach ($mainValueList as $index => $mainValue) { + $possibleArguments = $possibleArgumentsList[$index]; + + $attributeValue = $this->replaceAttributeArgumentInVariable($mainValue, $arguments, $attributeValue); + + // Split on commas, trim all values, and finally filter out all FALSE values + $argumentList = array_filter(array_map('trim', explode(',', $possibleArguments))); + + foreach ($argumentList as $argumentValue) { + $attributeValue = $this->replaceAttributeArgumentInVariable( + $argumentValue, + $arguments, + $attributeValue, + true + ); } } - return $newAttributeVal; + return $attributeValue; + } + + /** + * Replace attribute arguments in variable. + * + * @param string $variable + * @param array $arguments + * @param string $attributeValue + * @param bool $isInnerArgument + * @return string + */ + private function replaceAttributeArgumentInVariable( + $variable, + $arguments, + $attributeValue, + $isInnerArgument = false + ) { + // Truncate arg.field into arg + $variableName = strstr($variable, '.', true); + // Check if arguments has a mapping for the given variableName + + if ($variableName === false) { + $variableName = $variable; + } + + if (!array_key_exists($variableName, $arguments)) { + return $attributeValue; + } + + $isPersisted = strstr($arguments[$variableName], '$'); + if ($isPersisted) { + return $this->replacePersistedArgument( + $arguments[$variableName], + $attributeValue, + $variable, + $variableName, + $isInnerArgument + ); + } + + return str_replace($variableName, $arguments[$variableName], $attributeValue); } /** @@ -188,11 +220,12 @@ private function replacePersistedArgument($replacement, $attributeValue, $fullVa // parameter replacements require changing of (arg.field) to ($arg.field$) if ($isParameter) { - $newAttributeValue = str_replace($fullVariable, $scope . $fullVariable . $scope, $newAttributeValue); + $fullReplacement = str_replace($variable, trim($replacement, '$'), $fullVariable); + $newAttributeValue = str_replace($fullVariable, $scope . $fullReplacement . $scope, $newAttributeValue); } else { $newAttributeValue = str_replace('{{', $scope, str_replace('}}', $scope, $newAttributeValue)); + $newAttributeValue = str_replace($variable, trim($replacement, '$'), $newAttributeValue); } - $newAttributeValue = str_replace($variable, trim($replacement, '$'), $newAttributeValue); return $newAttributeValue; } diff --git a/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php b/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php index f1c2b630a..264bc7a26 100644 --- a/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php +++ b/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php @@ -913,6 +913,8 @@ private function resolveTestVariable($inputString, $args) */ private function replaceMatchesIntoArg($matches, &$outputArg, $delimiter) { + // Remove Duplicate $matches from array. Duplicate matches are replaced all in one go. + $matches = array_unique($matches); foreach ($matches as $match) { $replacement = null; $variable = $this->stripAndSplitReference($match, $delimiter); @@ -950,25 +952,22 @@ private function processQuoteBreaks($match, $argument, $replacement) $outputArg = $argument; $beforeIndex = strpos($outputArg, $match) - 1; $afterIndex = $beforeIndex + strlen($match) + 1; - $quoteBefore = true; - $quoteAfter = true; - // Prepare replacement with quote breaks if needed - if ($argument[$beforeIndex] != "\"") { - $replacement = '" . ' . $replacement; - $quoteBefore = false; - } - if ($argument[$afterIndex] != "\"") { - $replacement = $replacement . ' . "'; - $quoteAfter = false; - } - //Remove quotes at either end of argument if they aren't necessary. + // Determine if there is a " before/after the $match, and if there is only one " before/after match. + $quoteBefore = $argument[$beforeIndex] == '"' && substr_count($argument, '"', 0, $beforeIndex)<1; + $quoteAfter = $argument[$afterIndex] == '"' && substr_count($argument, '"', $afterIndex+1)<1; + + //Remove quotes at either end of argument if they aren't necessary. Add double-quote concatenation if needed. if ($quoteBefore) { $outputArg = substr($outputArg, 0, $beforeIndex) . substr($outputArg, $beforeIndex+1); $afterIndex--; + } else { + $replacement = '" . ' . $replacement; } if ($quoteAfter) { $outputArg = substr($outputArg, 0, $afterIndex) . substr($outputArg, $afterIndex+1); + } else { + $replacement = $replacement . ' . "'; } $outputArg = str_replace($match, $replacement, $outputArg); return $outputArg;