diff --git a/dev/tests/verification/Resources/ActionGroupUsingNestedArgument.txt b/dev/tests/verification/Resources/ActionGroupUsingNestedArgument.txt new file mode 100644 index 000000000..b978a3188 --- /dev/null +++ b/dev/tests/verification/Resources/ActionGroupUsingNestedArgument.txt @@ -0,0 +1,33 @@ +grabMultiple("selector"); + $I->assertCount(99, $grabProductsActionGroup); + } +} diff --git a/dev/tests/verification/TestModule/ActionGroup/BasicActionGroup.xml b/dev/tests/verification/TestModule/ActionGroup/BasicActionGroup.xml index 1fec39772..94e7a6b60 100644 --- a/dev/tests/verification/TestModule/ActionGroup/BasicActionGroup.xml +++ b/dev/tests/verification/TestModule/ActionGroup/BasicActionGroup.xml @@ -48,4 +48,15 @@ + + + + + + + + {{count}} + grabProducts + + diff --git a/dev/tests/verification/TestModule/Test/ActionGroupTest.xml b/dev/tests/verification/TestModule/Test/ActionGroupTest.xml index 72617c858..94b9e74dd 100644 --- a/dev/tests/verification/TestModule/Test/ActionGroupTest.xml +++ b/dev/tests/verification/TestModule/Test/ActionGroupTest.xml @@ -114,4 +114,10 @@ + + + + + + diff --git a/dev/tests/verification/Tests/ActionGroupGenerationTest.php b/dev/tests/verification/Tests/ActionGroupGenerationTest.php index e62ea24a5..a26e9ad87 100644 --- a/dev/tests/verification/Tests/ActionGroupGenerationTest.php +++ b/dev/tests/verification/Tests/ActionGroupGenerationTest.php @@ -107,4 +107,15 @@ public function testActionGroupWithStepKeyReferences() { $this->generateAndCompareTest('ActionGroupWithStepKeyReferences'); } + + /** + * Test generation of a test referencing an action group that uses stepKey references (grabFrom/CreateData) + * + * @throws \Exception + * @throws \Magento\FunctionalTestingFramework\Exceptions\TestReferenceException + */ + public function testActionGroupWithNestedArgument() + { + $this->generateAndCompareTest('ActionGroupUsingNestedArgument'); + } } diff --git a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php index 90be0a643..fdef1107e 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php +++ b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php @@ -125,33 +125,15 @@ private function getResolvedActionsWithArgs($arguments, $actionReferenceKey) { $resolvedActions = []; - // $regexPattern match on: $matches[0] {{section.element(arg.field)}} - // $matches[1] = section.element - // $matches[2] = arg.field - $regexPattern = '/{{([\w.\[\]]+)\(*([\w.$\',\s\[\]]+)*\)*}}/'; - foreach ($this->parsedActions as $action) { $varAttributes = array_intersect($this->varAttributes, 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)}} - array_shift($matches); - - $newActionAttributes[$varAttribute] = $this->replaceAttributeArguments( - $arguments, - $attributeValue, - $matches - ); - } + $newActionAttributes = $this->resolveAttributesWithArguments( + $arguments, + $action->getCustomActionAttributes() + ); } // we append the action reference key to any linked action and the action's merge key as the user might @@ -159,7 +141,7 @@ private function getResolvedActionsWithArgs($arguments, $actionReferenceKey) $resolvedActions[$action->getStepKey() . ucfirst($actionReferenceKey)] = new ActionObject( $action->getStepKey() . ucfirst($actionReferenceKey), $action->getType(), - array_merge($action->getCustomActionAttributes(), $newActionAttributes), + array_replace_recursive($action->getCustomActionAttributes(), $newActionAttributes), $action->getLinkedAction() == null ? null : $action->getLinkedAction() . ucfirst($actionReferenceKey), $action->getOrderOffset(), [self::ACTION_GROUP_ORIGIN_NAME => $this->name, @@ -170,6 +152,50 @@ private function getResolvedActionsWithArgs($arguments, $actionReferenceKey) return $resolvedActions; } + /** + * Resolves all references to arguments in attributes, and subAttributes. + * @param array $arguments + * @param array $attributes + * @return array + */ + private function resolveAttributesWithArguments($arguments, $attributes) + { + // $regexPattern match on: $matches[0] {{section.element(arg.field)}} + // $matches[1] = section.element + // $matches[2] = arg.field + $regexPattern = '/{{([\w.\[\]]+)\(*([\w.$\',\s\[\]]+)*\)*}}/'; + + $newActionAttributes = []; + foreach ($attributes as $attributeKey => $attributeValue) { + + if (is_array($attributeValue)) { + // attributes with child elements are parsed as an array, need make recursive call to resolve children + $newActionAttributes[$attributeKey] = $this->resolveAttributesWithArguments( + $arguments, + $attributeValue + ); + continue; + } + + preg_match_all($regexPattern, $attributeValue, $matches); + + if (empty($matches[0])) { + continue; + } + + //get rid of full match {{arg.field(arg.field)}} + array_shift($matches); + + $newActionAttributes[$attributeKey] = $this->replaceAttributeArguments( + $arguments, + $attributeValue, + $matches + ); + } + return $newActionAttributes; + + } + /** * Function that takes an array of replacement arguments, and matches them with args in an actionGroup's attribute. * Determines if the replacement arguments are persisted data, and replaces them accordingly. diff --git a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionObject.php b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionObject.php index 84f073c04..9a55755cc 100644 --- a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionObject.php +++ b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionObject.php @@ -21,7 +21,16 @@ class ActionObject { const __ENV = "_ENV"; - const DATA_ENABLED_ATTRIBUTES = ["userInput", "parameterArray", "expected", "actual", "x", "y"]; + const DATA_ENABLED_ATTRIBUTES = [ + "userInput", + "parameterArray", + "expected", + "actual", + "x", + "y", + "expectedResult", + "actualResult" + ]; const SELECTOR_ENABLED_ATTRIBUTES = [ 'selector', 'dependentSelector',