diff --git a/dev/tests/verification/Resources/ActionGroupMergedViaInsertAfter.txt b/dev/tests/verification/Resources/ActionGroupMergedViaInsertAfter.txt
new file mode 100644
index 000000000..a62548ccc
--- /dev/null
+++ b/dev/tests/verification/Resources/ActionGroupMergedViaInsertAfter.txt
@@ -0,0 +1,38 @@
+fillField("#foo", "foo");
+ $I->fillField("#bar", "bar");
+ $I->click("#foo2");
+ $I->click("#bar2");
+ $I->click("#baz2");
+ $I->fillField("#baz", "baz");
+ }
+}
diff --git a/dev/tests/verification/Resources/ActionGroupMergedViaInsertBefore.txt b/dev/tests/verification/Resources/ActionGroupMergedViaInsertBefore.txt
new file mode 100644
index 000000000..504ca8120
--- /dev/null
+++ b/dev/tests/verification/Resources/ActionGroupMergedViaInsertBefore.txt
@@ -0,0 +1,38 @@
+fillField("#foo", "foo");
+ $I->click("#foo2");
+ $I->click("#bar2");
+ $I->click("#baz2");
+ $I->fillField("#bar", "bar");
+ $I->fillField("#baz", "baz");
+ }
+}
diff --git a/dev/tests/verification/Resources/MergeMassViaInsertAfter.txt b/dev/tests/verification/Resources/MergeMassViaInsertAfter.txt
new file mode 100644
index 000000000..9ffc3d452
--- /dev/null
+++ b/dev/tests/verification/Resources/MergeMassViaInsertAfter.txt
@@ -0,0 +1,38 @@
+fillField("#foo", "foo");
+ $I->fillField("#bar", "bar");
+ $I->click("#mergeOne");
+ $I->click("#mergeTwo");
+ $I->click("#mergeThree");
+ $I->fillField("#baz", "baz");
+ }
+}
diff --git a/dev/tests/verification/Resources/MergeMassViaInsertBefore.txt b/dev/tests/verification/Resources/MergeMassViaInsertBefore.txt
new file mode 100644
index 000000000..a830c218c
--- /dev/null
+++ b/dev/tests/verification/Resources/MergeMassViaInsertBefore.txt
@@ -0,0 +1,38 @@
+fillField("#foo", "foo");
+ $I->click("#mergeOne");
+ $I->click("#mergeTwo");
+ $I->click("#mergeThree");
+ $I->fillField("#bar", "bar");
+ $I->fillField("#baz", "baz");
+ }
+}
diff --git a/dev/tests/verification/Resources/MergedActionGroupTest.txt b/dev/tests/verification/Resources/MergedActionGroupTest.txt
index 59f2b2643..f6c8f2351 100644
--- a/dev/tests/verification/Resources/MergedActionGroupTest.txt
+++ b/dev/tests/verification/Resources/MergedActionGroupTest.txt
@@ -70,9 +70,9 @@ class MergedActionGroupTestCest
*/
public function MergedActionGroupTest(AcceptanceTester $I)
{
- $I->see("#element .Jane");
$I->see(".merge .Jane");
- $I->click(".merge .Dane");
+ $I->see("#element .Jane");
$I->amOnPage("/Jane/Dane.html");
+ $I->click(".merge .Dane");
}
}
diff --git a/dev/tests/verification/TestModule/ActionGroup/FunctionalActionGroup.xml b/dev/tests/verification/TestModule/ActionGroup/FunctionalActionGroup.xml
index 342299804..5e1a20f96 100644
--- a/dev/tests/verification/TestModule/ActionGroup/FunctionalActionGroup.xml
+++ b/dev/tests/verification/TestModule/ActionGroup/FunctionalActionGroup.xml
@@ -50,6 +50,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/tests/verification/TestModule/ActionGroup/MergeFunctionalActionGroup.xml b/dev/tests/verification/TestModule/ActionGroup/MergeFunctionalActionGroup.xml
index bd478e645..7d8585772 100644
--- a/dev/tests/verification/TestModule/ActionGroup/MergeFunctionalActionGroup.xml
+++ b/dev/tests/verification/TestModule/ActionGroup/MergeFunctionalActionGroup.xml
@@ -13,4 +13,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/tests/verification/TestModule/Test/ActionGroupFunctionalTest.xml b/dev/tests/verification/TestModule/Test/ActionGroupFunctionalTest.xml
index 6a0558628..63f800983 100644
--- a/dev/tests/verification/TestModule/Test/ActionGroupFunctionalTest.xml
+++ b/dev/tests/verification/TestModule/Test/ActionGroupFunctionalTest.xml
@@ -182,6 +182,12 @@
+
+
+
+
+
+
diff --git a/dev/tests/verification/TestModule/Test/BasicFunctionalTest.xml b/dev/tests/verification/TestModule/Test/BasicFunctionalTest.xml
index bd7c23522..92b04e0ad 100644
--- a/dev/tests/verification/TestModule/Test/BasicFunctionalTest.xml
+++ b/dev/tests/verification/TestModule/Test/BasicFunctionalTest.xml
@@ -119,4 +119,14 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dev/tests/verification/TestModule/Test/MergeFunctionalTest.xml b/dev/tests/verification/TestModule/Test/MergeFunctionalTest.xml
index 75c62b36f..553f3d251 100644
--- a/dev/tests/verification/TestModule/Test/MergeFunctionalTest.xml
+++ b/dev/tests/verification/TestModule/Test/MergeFunctionalTest.xml
@@ -45,4 +45,14 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/tests/verification/Tests/ActionGroupMergeGenerationTest.php b/dev/tests/verification/Tests/ActionGroupMergeGenerationTest.php
index 9176f3955..0361bec75 100644
--- a/dev/tests/verification/Tests/ActionGroupMergeGenerationTest.php
+++ b/dev/tests/verification/Tests/ActionGroupMergeGenerationTest.php
@@ -108,4 +108,26 @@ public function testArgumentWithSameNameAsElement()
{
$this->generateAndCompareTest('ArgumentWithSameNameAsElement');
}
+
+ /**
+ * Test an action group with a merge counterpart that's merged via insertBefore
+ *
+ * @throws \Exception
+ * @throws \Magento\FunctionalTestingFramework\Exceptions\TestReferenceException
+ */
+ public function testMergedActionGroupViaInsertBefore()
+ {
+ $this->generateAndCompareTest('ActionGroupMergedViaInsertBefore');
+ }
+
+ /**
+ * Test an action group with a merge counterpart that's merged via insertAfter
+ *
+ * @throws \Exception
+ * @throws \Magento\FunctionalTestingFramework\Exceptions\TestReferenceException
+ */
+ public function testMergedActionGroupViaInsertAfter()
+ {
+ $this->generateAndCompareTest('ActionGroupMergedViaInsertAfter');
+ }
}
diff --git a/dev/tests/verification/Tests/MergedGenerationTest.php b/dev/tests/verification/Tests/MergedGenerationTest.php
index fe2990b76..9ef22fe09 100644
--- a/dev/tests/verification/Tests/MergedGenerationTest.php
+++ b/dev/tests/verification/Tests/MergedGenerationTest.php
@@ -40,4 +40,26 @@ public function testParsedArray()
$entity = DataObjectHandler::getInstance()->getObject('testEntity');
$this->assertCount(3, $entity->getLinkedEntities());
}
+
+ /**
+ * Tests generation of a test merge file via insertBefore
+ *
+ * @throws \Exception
+ * @throws \Magento\FunctionalTestingFramework\Exceptions\TestReferenceException
+ */
+ public function testMergeMassViaInsertBefore()
+ {
+ $this->generateAndCompareTest('MergeMassViaInsertBefore');
+ }
+
+ /**
+ * Tests generation of a test merge file via insertBefore
+ *
+ * @throws \Exception
+ * @throws \Magento\FunctionalTestingFramework\Exceptions\TestReferenceException
+ */
+ public function testMergeMassViaInsertAfter()
+ {
+ $this->generateAndCompareTest('MergeMassViaInsertAfter');
+ }
}
diff --git a/src/Magento/FunctionalTestingFramework/Test/Config/ActionGroupDom.php b/src/Magento/FunctionalTestingFramework/Test/Config/ActionGroupDom.php
index 794007dde..bfe1c243f 100644
--- a/src/Magento/FunctionalTestingFramework/Test/Config/ActionGroupDom.php
+++ b/src/Magento/FunctionalTestingFramework/Test/Config/ActionGroupDom.php
@@ -30,9 +30,25 @@ public function initDom($xml, $filename = null, $exceptionCollector = null)
/** @var \DOMElement $actionGroupNode */
$actionGroupNode->setAttribute(self::TEST_META_FILENAME_ATTRIBUTE, $filename);
$this->validateDomStepKeys($actionGroupNode, $filename, 'Action Group', $exceptionCollector);
+ if ($actionGroupNode->getAttribute(self::TEST_MERGE_POINTER_AFTER) !== "") {
+ $this->appendMergePointerToActions(
+ $actionGroupNode,
+ self::TEST_MERGE_POINTER_AFTER,
+ $actionGroupNode->getAttribute(self::TEST_MERGE_POINTER_AFTER),
+ $filename,
+ $exceptionCollector
+ );
+ } elseif ($actionGroupNode->getAttribute(self::TEST_MERGE_POINTER_BEFORE) !== "") {
+ $this->appendMergePointerToActions(
+ $actionGroupNode,
+ self::TEST_MERGE_POINTER_BEFORE,
+ $actionGroupNode->getAttribute(self::TEST_MERGE_POINTER_BEFORE),
+ $filename,
+ $exceptionCollector
+ );
+ }
}
}
-
return $dom;
}
}
diff --git a/src/Magento/FunctionalTestingFramework/Test/Config/Dom.php b/src/Magento/FunctionalTestingFramework/Test/Config/Dom.php
index 24710243f..fb7b0a386 100644
--- a/src/Magento/FunctionalTestingFramework/Test/Config/Dom.php
+++ b/src/Magento/FunctionalTestingFramework/Test/Config/Dom.php
@@ -10,6 +10,7 @@
use Magento\FunctionalTestingFramework\Exceptions\XmlException;
use Magento\FunctionalTestingFramework\Config\Dom\NodeMergingConfig;
use Magento\FunctionalTestingFramework\Config\Dom\NodePathMatcher;
+use Magento\FunctionalTestingFramework\Test\Objects\ActionObject;
class Dom extends \Magento\FunctionalTestingFramework\Config\Dom
{
@@ -17,6 +18,8 @@ class Dom extends \Magento\FunctionalTestingFramework\Config\Dom
const TEST_META_FILENAME_ATTRIBUTE = 'filename';
const TEST_META_NAME_ATTRIBUTE = 'name';
const TEST_HOOK_NAMES = ["after", "before"];
+ const TEST_MERGE_POINTER_BEFORE = "insertBefore";
+ const TEST_MERGE_POINTER_AFTER = "insertAfter";
/**
* TestDom constructor.
@@ -63,6 +66,23 @@ public function initDom($xml, $filename = null, $exceptionCollector = null)
/** @var \DOMElement $testNode */
$testNode->setAttribute(self::TEST_META_FILENAME_ATTRIBUTE, $filename);
$this->validateDomStepKeys($testNode, $filename, 'Test', $exceptionCollector);
+ if ($testNode->getAttribute(self::TEST_MERGE_POINTER_AFTER) !== "") {
+ $this->appendMergePointerToActions(
+ $testNode,
+ self::TEST_MERGE_POINTER_AFTER,
+ $testNode->getAttribute(self::TEST_MERGE_POINTER_AFTER),
+ $filename,
+ $exceptionCollector
+ );
+ } elseif ($testNode->getAttribute(self::TEST_MERGE_POINTER_BEFORE) !== "") {
+ $this->appendMergePointerToActions(
+ $testNode,
+ self::TEST_MERGE_POINTER_BEFORE,
+ $testNode->getAttribute(self::TEST_MERGE_POINTER_BEFORE),
+ $filename,
+ $exceptionCollector
+ );
+ }
}
}
@@ -83,6 +103,41 @@ public function merge($xml, $filename = null, $exceptionCollector = null)
$this->mergeNode($dom->documentElement, '');
}
+ /**
+ * Parses DOM Structure's actions and appends a before/after attribute along with the parent's stepkey reference.
+ *
+ * @param \DOMElement $testNode
+ * @param string $insertType
+ * @param string $insertKey
+ * @param string $filename
+ * @param ExceptionCollector $exceptionCollector
+ * @return void
+ */
+ protected function appendMergePointerToActions($testNode, $insertType, $insertKey, $filename, $exceptionCollector)
+ {
+ $childNodes = $testNode->childNodes;
+ $previousStepKey = $insertKey;
+ $actionInsertType = ActionObject::MERGE_ACTION_ORDER_AFTER;
+ if ($insertType == self::TEST_MERGE_POINTER_BEFORE) {
+ $actionInsertType = ActionObject::MERGE_ACTION_ORDER_BEFORE;
+ }
+ for ($i = 0; $i < $childNodes->length; $i++) {
+ $currentNode = $childNodes->item($i);
+ if (!is_a($currentNode, \DOMElement::class) || !$currentNode->hasAttribute('stepKey')) {
+ continue;
+ }
+ if ($currentNode->hasAttribute($insertType) && $testNode->hasAttribute($insertType)) {
+ $errorMsg = "Actions cannot have merge pointers if contained in tests that has a merge pointer.";
+ $errorMsg .= "\n\tstepKey: {$currentNode->getAttribute('stepKey')}\tin file: {$filename}";
+ $exceptionCollector->addError($filename, $errorMsg);
+ }
+ $currentNode->setAttribute($actionInsertType, $previousStepKey);
+ $previousStepKey = $currentNode->getAttribute('stepKey');
+ // All actions after the first need to insert AFTER.
+ $actionInsertType = ActionObject::MERGE_ACTION_ORDER_AFTER;
+ }
+ }
+
/**
* Parses an individual DOM structure for repeated stepKey attributes
*
diff --git a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php
index 5c8b5bfb2..7cd73f120 100644
--- a/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php
+++ b/src/Magento/FunctionalTestingFramework/Test/Objects/ActionGroupObject.php
@@ -137,6 +137,12 @@ private function getResolvedActionsWithArgs($arguments, $actionReferenceKey)
);
}
+ // translate 0/1 back to before/after
+ $orderOffset = ActionObject::MERGE_ACTION_ORDER_BEFORE;
+ if ($action->getOrderOffset() === 1) {
+ $orderOffset = ActionObject::MERGE_ACTION_ORDER_AFTER;
+ }
+
// we append the action reference key to any linked action and the action's merge key as the user might
// use this action group multiple times in the same test.
$resolvedActions[$action->getStepKey() . ucfirst($actionReferenceKey)] = new ActionObject(
@@ -144,7 +150,7 @@ private function getResolvedActionsWithArgs($arguments, $actionReferenceKey)
$action->getType(),
array_replace_recursive($action->getCustomActionAttributes(), $newActionAttributes),
$action->getLinkedAction() == null ? null : $action->getLinkedAction() . ucfirst($actionReferenceKey),
- $action->getOrderOffset(),
+ $orderOffset,
[self::ACTION_GROUP_ORIGIN_NAME => $this->name,
self::ACTION_GROUP_ORIGIN_TEST_REF => $actionReferenceKey]
);
diff --git a/src/Magento/FunctionalTestingFramework/Test/Util/ActionGroupObjectExtractor.php b/src/Magento/FunctionalTestingFramework/Test/Util/ActionGroupObjectExtractor.php
index 32b54c3da..9fd912da3 100644
--- a/src/Magento/FunctionalTestingFramework/Test/Util/ActionGroupObjectExtractor.php
+++ b/src/Magento/FunctionalTestingFramework/Test/Util/ActionGroupObjectExtractor.php
@@ -19,6 +19,8 @@ class ActionGroupObjectExtractor extends BaseObjectExtractor
const DEFAULT_VALUE = 'defaultValue';
const ACTION_GROUP_ARGUMENTS = 'arguments';
const FILENAME = 'filename';
+ const ACTION_GROUP_INSERT_BEFORE = "insertBefore";
+ const ACTION_GROUP_INSERT_AFTER = "insertAfter";
/**
* Action Object Extractor for converting actions into objects
@@ -51,7 +53,9 @@ public function extractActionGroup($actionGroupData)
self::NODE_NAME,
self::ACTION_GROUP_ARGUMENTS,
self::NAME,
- self::FILENAME
+ self::FILENAME,
+ self::ACTION_GROUP_INSERT_BEFORE,
+ self::ACTION_GROUP_INSERT_AFTER
);
// TODO filename is now available to the ActionGroupObject, integrate this into debug and error statements
diff --git a/src/Magento/FunctionalTestingFramework/Test/Util/ActionMergeUtil.php b/src/Magento/FunctionalTestingFramework/Test/Util/ActionMergeUtil.php
index 4bc120f2e..b4188abe0 100644
--- a/src/Magento/FunctionalTestingFramework/Test/Util/ActionMergeUtil.php
+++ b/src/Magento/FunctionalTestingFramework/Test/Util/ActionMergeUtil.php
@@ -18,7 +18,7 @@ class ActionMergeUtil
{
const STEP_MISSING_ERROR_MSG =
"Merge Error - Step could not be found in either TestXML or DeltaXML.
- \t%s = '%s'\tTestStep='%s'\tLinkedStep'%s'";
+ \t%s: '%s'\tTestStep: '%s'\tLinkedStep: '%s'";
const WAIT_ATTR = 'timeout';
const WAIT_ACTION_NAME = 'waitForPageLoad';
diff --git a/src/Magento/FunctionalTestingFramework/Test/Util/TestObjectExtractor.php b/src/Magento/FunctionalTestingFramework/Test/Util/TestObjectExtractor.php
index 9dc4b0652..cd39753ba 100644
--- a/src/Magento/FunctionalTestingFramework/Test/Util/TestObjectExtractor.php
+++ b/src/Magento/FunctionalTestingFramework/Test/Util/TestObjectExtractor.php
@@ -21,6 +21,11 @@ class TestObjectExtractor extends BaseObjectExtractor
const TEST_BEFORE_HOOK = 'before';
const TEST_AFTER_HOOK = 'after';
const TEST_FAILED_HOOK = 'failed';
+ const TEST_BEFORE_ATTRIBUTE = 'before';
+ const TEST_AFTER_ATTRIBUTE = 'after';
+ const TEST_INSERT_BEFORE = 'insertBefore';
+ const TEST_INSERT_AFTER = 'insertAfter';
+ const TEST_FILENAME = 'filename';
/**
* Action Object Extractor object
@@ -80,7 +85,9 @@ public function extractTestData($testData)
self::TEST_BEFORE_HOOK,
self::TEST_AFTER_HOOK,
self::TEST_FAILED_HOOK,
- 'filename'
+ self::TEST_INSERT_BEFORE,
+ self::TEST_INSERT_AFTER,
+ self::TEST_FILENAME
);
if (array_key_exists(self::TEST_ANNOTATIONS, $testData)) {
@@ -91,7 +98,7 @@ public function extractTestData($testData)
$testAnnotations["features"] = [$module];
// extract before
- if (array_key_exists(self::TEST_BEFORE_HOOK, $testData)) {
+ if (array_key_exists(self::TEST_BEFORE_HOOK, $testData) && is_array($testData[self::TEST_BEFORE_HOOK])) {
$testHooks[self::TEST_BEFORE_HOOK] = $this->testHookObjectExtractor->extractHook(
$testData[self::NAME],
'before',
@@ -99,7 +106,7 @@ public function extractTestData($testData)
);
}
- if (array_key_exists(self::TEST_AFTER_HOOK, $testData)) {
+ if (array_key_exists(self::TEST_AFTER_HOOK, $testData) && is_array($testData[self::TEST_AFTER_HOOK])) {
// extract after
$testHooks[self::TEST_AFTER_HOOK] = $this->testHookObjectExtractor->extractHook(
$testData[self::NAME],
diff --git a/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd b/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd
index 74badd40c..5df793643 100644
--- a/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd
+++ b/src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd
@@ -33,6 +33,8 @@
+
+
diff --git a/src/Magento/FunctionalTestingFramework/Test/etc/mergedTestSchema.xsd b/src/Magento/FunctionalTestingFramework/Test/etc/mergedTestSchema.xsd
index 012083ab8..ecd058581 100644
--- a/src/Magento/FunctionalTestingFramework/Test/etc/mergedTestSchema.xsd
+++ b/src/Magento/FunctionalTestingFramework/Test/etc/mergedTestSchema.xsd
@@ -70,6 +70,8 @@
+
+