From f2138fb05d6d78dcd72519251db20d3d9950e057 Mon Sep 17 00:00:00 2001 From: Ji Lu Date: Fri, 27 Oct 2017 15:01:32 -0500 Subject: [PATCH 1/6] MQE-496: Allow passing multiple ActionGroup arguments into parameterized selector. (Patch from Anthoula) --- .../Test/Objects/ActionGroupObject.php | 90 ++++++++++++------- 1 file changed, 60 insertions(+), 30 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php index c5beb1236..277faba40 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php +++ b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php @@ -84,23 +84,22 @@ 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 +131,67 @@ 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 - $variableName = strstr($variable, '.', true); - // Check if arguments has a mapping for the given variableName - if (!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); + + $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); } /** From 0885226eddca3f0586320d8a5aaa5720c246c3c9 Mon Sep 17 00:00:00 2001 From: KevinBKozan Date: Mon, 30 Oct 2017 13:20:32 -0500 Subject: [PATCH 2/6] MQE-496: Allow passing multiple ActionGroup arguments into parameterized selector. - persisted Data fixes to Anthoula's patch. --- .../Test/Objects/ActionGroupObject.php | 6 ++++-- .../Util/TestGenerator.php | 15 +++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php index 277faba40..c1f501ed8 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php +++ b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php @@ -172,6 +172,7 @@ private function replaceAttributeArgumentInVariable( $variableName = strstr($variable, '.', true); // Check if arguments has a mapping for the given variableName + if ($variableName === false) { $variableName = $variable; } @@ -218,11 +219,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..981dc28b0 100644 --- a/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php +++ b/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php @@ -913,6 +913,7 @@ private function resolveTestVariable($inputString, $args) */ private function replaceMatchesIntoArg($matches, &$outputArg, $delimiter) { + $matches = array_unique($matches); foreach ($matches as $match) { $replacement = null; $variable = $this->stripAndSplitReference($match, $delimiter); @@ -953,22 +954,24 @@ private function processQuoteBreaks($match, $argument, $replacement) $quoteBefore = true; $quoteAfter = true; - // Prepare replacement with quote breaks if needed - if ($argument[$beforeIndex] != "\"") { - $replacement = '" . ' . $replacement; + // Determine if there is a Single quote before/after the $match, and if there is only 1 quote before/after. + if ($argument[$beforeIndex] != '"' || substr_count($argument, '"', 0, $beforeIndex+1)>1) { $quoteBefore = false; } - if ($argument[$afterIndex] != "\"") { - $replacement = $replacement . ' . "'; + if ($argument[$afterIndex] != '"' || substr_count($argument, '"', $afterIndex)>1) { $quoteAfter = false; } - //Remove quotes at either end of argument if they aren't necessary. + //Remove quotes at either end of argument if they aren't necessary. Add quote breaking 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; From 8343794dded291462da28a8e1e7e0987c5693903 Mon Sep 17 00:00:00 2001 From: KevinBKozan Date: Mon, 30 Oct 2017 13:54:02 -0500 Subject: [PATCH 3/6] MQE-496: Allow passing multiple ActionGroup arguments into parameterized selector. - Codesniffer fix. --- .../Test/Objects/ActionGroupObject.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php index c1f501ed8..1279ad94b 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php +++ b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php @@ -172,7 +172,6 @@ private function replaceAttributeArgumentInVariable( $variableName = strstr($variable, '.', true); // Check if arguments has a mapping for the given variableName - if ($variableName === false) { $variableName = $variable; } From 656cf29caf5e226a1aa3ad70274aa50843342c8d Mon Sep 17 00:00:00 2001 From: KevinBKozan Date: Wed, 1 Nov 2017 09:13:30 -0500 Subject: [PATCH 4/6] MQE-496: Allow passing multiple ActionGroup arguments into parameterized selector. - Fixing bad merge. --- .../Test/Objects/ActionGroupObject.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php index adb51a542..f145e7a71 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php +++ b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php @@ -84,7 +84,7 @@ 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())); From 365bf6ba9f6ccac7ca2f3b158c42f85a3497bd21 Mon Sep 17 00:00:00 2001 From: KevinBKozan Date: Wed, 1 Nov 2017 11:00:10 -0500 Subject: [PATCH 5/6] MQE-496: Allow passing multiple ActionGroup arguments into parameterized selector. - CR Changes. --- .../Test/Objects/ActionGroupObject.php | 1 + .../Util/TestGenerator.php | 16 ++++++---------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php index f145e7a71..4f533aaab 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php +++ b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php @@ -139,6 +139,7 @@ private function replaceAttributeArguments($arguments, $attributeValue, $matches $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) { diff --git a/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php b/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php index 981dc28b0..7e8a7bb2a 100644 --- a/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php +++ b/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php @@ -913,6 +913,7 @@ 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; @@ -951,17 +952,12 @@ private function processQuoteBreaks($match, $argument, $replacement) $outputArg = $argument; $beforeIndex = strpos($outputArg, $match) - 1; $afterIndex = $beforeIndex + strlen($match) + 1; - $quoteBefore = true; - $quoteAfter = true; - // Determine if there is a Single quote before/after the $match, and if there is only 1 quote before/after. - if ($argument[$beforeIndex] != '"' || substr_count($argument, '"', 0, $beforeIndex+1)>1) { - $quoteBefore = false; - } - if ($argument[$afterIndex] != '"' || substr_count($argument, '"', $afterIndex)>1) { - $quoteAfter = false; - } - //Remove quotes at either end of argument if they aren't necessary. Add quote breaking if needed + // 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)<1; + $quoteAfter = $argument[$afterIndex] == '"' && substr_count($argument, '"', $afterIndex)<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--; From 85372e86e111ca9c9ff267042000e1c6a3732b63 Mon Sep 17 00:00:00 2001 From: KevinBKozan Date: Wed, 1 Nov 2017 11:14:24 -0500 Subject: [PATCH 6/6] MQE-496: Allow passing multiple ActionGroup arguments into parameterized selector. - Fixing quote logic, caught via verification tests. --- src/Magento/FunctionalTestingFramework/Util/TestGenerator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php b/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php index 7e8a7bb2a..264bc7a26 100644 --- a/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php +++ b/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php @@ -954,8 +954,8 @@ private function processQuoteBreaks($match, $argument, $replacement) $afterIndex = $beforeIndex + strlen($match) + 1; // 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)<1; - $quoteAfter = $argument[$afterIndex] == '"' && substr_count($argument, '"', $afterIndex)<1; + $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) {