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',