diff --git a/dev/tests/verification/Resources/ActionGroupReturningValueTest.txt b/dev/tests/verification/Resources/ActionGroupReturningValueTest.txt
new file mode 100644
index 000000000..08e0b44f8
--- /dev/null
+++ b/dev/tests/verification/Resources/ActionGroupReturningValueTest.txt
@@ -0,0 +1,75 @@
+Test filesverification/TestModule/Test/ActionGroupFunctionalTest/ActionGroupReturningValueTest.xml
")
+ */
+class ActionGroupReturningValueTestCest
+{
+ /**
+ * @param AcceptanceTester $I
+ * @throws \Exception
+ */
+ public function _before(AcceptanceTester $I)
+ {
+ $I->createEntity("createPersonParam", "hook", "ReplacementPerson", [], []); // stepKey: createPersonParam
+ $I->comment("Entering Action Group [beforeGroup] FunctionalActionGroup");
+ $I->fillField("#foo", "myData1"); // stepKey: fillField1BeforeGroup
+ $I->fillField("#bar", "myData2"); // stepKey: fillField2BeforeGroup
+ $I->comment("Exiting Action Group [beforeGroup] FunctionalActionGroup");
+ }
+
+ /**
+ * @param AcceptanceTester $I
+ * @throws \Exception
+ */
+ public function _after(AcceptanceTester $I)
+ {
+ $I->comment("Entering Action Group [afterGroup] FunctionalActionGroup");
+ $I->fillField("#foo", "myData1"); // stepKey: fillField1AfterGroup
+ $I->fillField("#bar", "myData2"); // stepKey: fillField2AfterGroup
+ $I->comment("Exiting Action Group [afterGroup] FunctionalActionGroup");
+ }
+
+ /**
+ * @param AcceptanceTester $I
+ * @throws \Exception
+ */
+ public function _failed(AcceptanceTester $I)
+ {
+ $I->saveScreenshot(); // stepKey: saveScreenshot
+ }
+
+ /**
+ * @Severity(level = SeverityLevel::CRITICAL)
+ * @Features({"TestModule"})
+ * @Stories({"MQE-433"})
+ * @Parameter(name = "AcceptanceTester", value="$I")
+ * @param AcceptanceTester $I
+ * @return void
+ * @throws \Exception
+ */
+ public function ActionGroupReturningValueTest(AcceptanceTester $I)
+ {
+ $I->amOnPage("/someUrl"); // stepKey: step1
+ $I->comment("Entering Action Group [actionGroupWithReturnValue1] FunctionalActionGroupWithReturnValueActionGroup");
+ $grabTextFrom1ActionGroupWithReturnValue1 = $I->grabTextFrom("#foo"); // stepKey: grabTextFrom1ActionGroupWithReturnValue1
+ $actionGroupWithReturnValue1 = $I->return($grabTextFrom1ActionGroupWithReturnValue1); // stepKey: returnActionGroupWithReturnValue1
+ $I->comment("Exiting Action Group [actionGroupWithReturnValue1] FunctionalActionGroupWithReturnValueActionGroup");
+ $I->comment("Entering Action Group [actionGroupWithStringUsage1] actionGroupWithStringUsage");
+ $I->see($actionGroupWithReturnValue1, "#element .{$actionGroupWithReturnValue1}"); // stepKey: see1ActionGroupWithStringUsage1
+ $I->comment("Exiting Action Group [actionGroupWithStringUsage1] actionGroupWithStringUsage");
+ }
+}
diff --git a/dev/tests/verification/Resources/ExtendedActionGroupReturningValueTest.txt b/dev/tests/verification/Resources/ExtendedActionGroupReturningValueTest.txt
new file mode 100644
index 000000000..2f26a6463
--- /dev/null
+++ b/dev/tests/verification/Resources/ExtendedActionGroupReturningValueTest.txt
@@ -0,0 +1,40 @@
+Test filesverification/TestModule/Test/ActionGroupTest/ExtendedActionGroupReturningValueTest.xml
")
+ */
+class ExtendedActionGroupReturningValueTestCest
+{
+ /**
+ * @Severity(level = SeverityLevel::CRITICAL)
+ * @Features({"TestModule"})
+ * @Parameter(name = "AcceptanceTester", value="$I")
+ * @param AcceptanceTester $I
+ * @return void
+ * @throws \Exception
+ */
+ public function ExtendedActionGroupReturningValueTest(AcceptanceTester $I)
+ {
+ $I->comment("Entering Action Group [actionGroupReturningValue] ActionGroupReturningValueActionGroup");
+ $grabProducts1ActionGroupReturningValue = $I->grabMultiple("selector"); // stepKey: grabProducts1ActionGroupReturningValue
+ $I->assertCount(99, $grabProducts1ActionGroupReturningValue); // stepKey: assertCountActionGroupReturningValue
+ $actionGroupReturningValue = $I->return($grabProducts1ActionGroupReturningValue); // stepKey: returnProducts1ActionGroupReturningValue
+ $I->comment("Exiting Action Group [actionGroupReturningValue] ActionGroupReturningValueActionGroup");
+ $I->comment("Entering Action Group [actionGroupWithStringUsage1] actionGroupWithStringUsage");
+ $I->see($actionGroupReturningValue, "#element .{$actionGroupReturningValue}"); // stepKey: see1ActionGroupWithStringUsage1
+ $I->comment("Exiting Action Group [actionGroupWithStringUsage1] actionGroupWithStringUsage");
+ }
+}
diff --git a/dev/tests/verification/Resources/ExtendedChildActionGroupReturningValueTest.txt b/dev/tests/verification/Resources/ExtendedChildActionGroupReturningValueTest.txt
new file mode 100644
index 000000000..d043a5c04
--- /dev/null
+++ b/dev/tests/verification/Resources/ExtendedChildActionGroupReturningValueTest.txt
@@ -0,0 +1,43 @@
+Test filesverification/TestModule/Test/ActionGroupTest/ExtendedChildActionGroupReturningValueTest.xml
")
+ */
+class ExtendedChildActionGroupReturningValueTestCest
+{
+ /**
+ * @Severity(level = SeverityLevel::CRITICAL)
+ * @Features({"TestModule"})
+ * @Parameter(name = "AcceptanceTester", value="$I")
+ * @param AcceptanceTester $I
+ * @return void
+ * @throws \Exception
+ */
+ public function ExtendedChildActionGroupReturningValueTest(AcceptanceTester $I)
+ {
+ $I->comment("Entering Action Group [extendedActionGroupReturningValue] ExtendedActionGroupReturningValueActionGroup");
+ $grabProducts1ExtendedActionGroupReturningValue = $I->grabMultiple("selector"); // stepKey: grabProducts1ExtendedActionGroupReturningValue
+ $I->assertCount(99, $grabProducts1ExtendedActionGroupReturningValue); // stepKey: assertCountExtendedActionGroupReturningValue
+ $extendedActionGroupReturningValue = $I->return($grabProducts1ExtendedActionGroupReturningValue); // stepKey: returnProducts1ExtendedActionGroupReturningValue
+ $grabProducts2ExtendedActionGroupReturningValue = $I->grabMultiple("otherSelector"); // stepKey: grabProducts2ExtendedActionGroupReturningValue
+ $I->assertCount(8000, $grabProducts2ExtendedActionGroupReturningValue); // stepKey: assertSecondCountExtendedActionGroupReturningValue
+ $extendedActionGroupReturningValue = $I->return($grabProducts2ExtendedActionGroupReturningValue); // stepKey: returnProducts2ExtendedActionGroupReturningValue
+ $I->comment("Exiting Action Group [extendedActionGroupReturningValue] ExtendedActionGroupReturningValueActionGroup");
+ $I->comment("Entering Action Group [actionGroupWithStringUsage1] actionGroupWithStringUsage");
+ $I->see($extendedActionGroupReturningValue, "#element .{$extendedActionGroupReturningValue}"); // stepKey: see1ActionGroupWithStringUsage1
+ $I->comment("Exiting Action Group [actionGroupWithStringUsage1] actionGroupWithStringUsage");
+ }
+}
diff --git a/dev/tests/verification/Resources/MergedActionGroupReturningValueTest.txt b/dev/tests/verification/Resources/MergedActionGroupReturningValueTest.txt
new file mode 100644
index 000000000..a4689779b
--- /dev/null
+++ b/dev/tests/verification/Resources/MergedActionGroupReturningValueTest.txt
@@ -0,0 +1,77 @@
+Test filesverification/TestModule/Test/MergeFunctionalTest/MergedActionGroupReturningValueTest.xml
")
+ */
+class MergedActionGroupReturningValueTestCest
+{
+ /**
+ * @param AcceptanceTester $I
+ * @throws \Exception
+ */
+ public function _before(AcceptanceTester $I)
+ {
+ $I->createEntity("createPersonParam", "hook", "ReplacementPerson", [], []); // stepKey: createPersonParam
+ $I->comment("Entering Action Group [beforeGroup] FunctionalActionGroup");
+ $I->fillField("#foo", "myData1"); // stepKey: fillField1BeforeGroup
+ $I->fillField("#bar", "myData2"); // stepKey: fillField2BeforeGroup
+ $I->comment("Exiting Action Group [beforeGroup] FunctionalActionGroup");
+ }
+
+ /**
+ * @param AcceptanceTester $I
+ * @throws \Exception
+ */
+ public function _after(AcceptanceTester $I)
+ {
+ $I->comment("Entering Action Group [afterGroup] FunctionalActionGroup");
+ $I->fillField("#foo", "myData1"); // stepKey: fillField1AfterGroup
+ $I->fillField("#bar", "myData2"); // stepKey: fillField2AfterGroup
+ $I->comment("Exiting Action Group [afterGroup] FunctionalActionGroup");
+ }
+
+ /**
+ * @param AcceptanceTester $I
+ * @throws \Exception
+ */
+ public function _failed(AcceptanceTester $I)
+ {
+ $I->saveScreenshot(); // stepKey: saveScreenshot
+ }
+
+ /**
+ * @Severity(level = SeverityLevel::CRITICAL)
+ * @Features({"TestModule"})
+ * @Stories({"MQE-433"})
+ * @Parameter(name = "AcceptanceTester", value="$I")
+ * @param AcceptanceTester $I
+ * @return void
+ * @throws \Exception
+ */
+ public function MergedActionGroupReturningValueTest(AcceptanceTester $I)
+ {
+ $I->amOnPage("/someUrl"); // stepKey: step1
+ $I->comment("Entering Action Group [actionGroupWithReturnValue1] MergeActionGroupReturningValueActionGroup");
+ $I->amOnPage("/Jane/Dane.html"); // stepKey: amOnPage1ActionGroupWithReturnValue1
+ $I->click(".merge .Jane"); // stepKey: myMergedClickActionGroupWithReturnValue1
+ $grabMultiple1ActionGroupWithReturnValue1 = $I->grabMultiple("#foo"); // stepKey: grabMultiple1ActionGroupWithReturnValue1
+ $actionGroupWithReturnValue1 = $I->return($grabMultiple1ActionGroupWithReturnValue1); // stepKey: returnValueActionGroupWithReturnValue1
+ $I->comment("Exiting Action Group [actionGroupWithReturnValue1] MergeActionGroupReturningValueActionGroup");
+ $I->comment("Entering Action Group [actionGroupWithStringUsage1] actionGroupWithStringUsage");
+ $I->see($actionGroupWithReturnValue1, "#element .{$actionGroupWithReturnValue1}"); // stepKey: see1ActionGroupWithStringUsage1
+ $I->comment("Exiting Action Group [actionGroupWithStringUsage1] actionGroupWithStringUsage");
+ }
+}
diff --git a/dev/tests/verification/Resources/functionalSuiteHooks.txt b/dev/tests/verification/Resources/functionalSuiteHooks.txt
index 3b5f6bae0..041b088b1 100644
--- a/dev/tests/verification/Resources/functionalSuiteHooks.txt
+++ b/dev/tests/verification/Resources/functionalSuiteHooks.txt
@@ -53,14 +53,33 @@ class functionalSuiteHooks extends \Codeception\GroupObject
$webDriver->_initializeSession();
}
$webDriver->amOnPage("some.url"); // stepKey: before
- $createFields['someKey'] = "dataHere";
+ $createOneFields['someKey'] = "dataHere";
PersistedObjectHandler::getInstance()->createEntity(
- "create",
+ "createOne",
"suite",
- "createThis",
- $createFields
+ "createEntityOne",
+ [],
+ $createOneFields
);
- $webDriver->click(PersistedObjectHandler::getInstance()->retrieveEntityField('create', 'data', 'suite')); // stepKey: clickWithData
+ PersistedObjectHandler::getInstance()->createEntity(
+ "createTwo",
+ "suite",
+ "createEntityTwo",
+ ["createEntityOne"]
+ );
+ PersistedObjectHandler::getInstance()->createEntity(
+ "createThree",
+ "suite",
+ "createEntityThree",
+ []
+ );
+ PersistedObjectHandler::getInstance()->createEntity(
+ "createFour",
+ "suite",
+ "createEntityFour",
+ ["createEntityTwo", "createEntityThree"]
+ );
+ $webDriver->click(PersistedObjectHandler::getInstance()->retrieveEntityField('createTwo', 'data', 'suite')); // stepKey: clickWithData
print("Entering Action Group [AC] actionGroupWithTwoArguments");
$webDriver->see("John", msq("uniqueData") . "John"); // stepKey: seeFirstNameAC
print("Exiting Action Group [AC] actionGroupWithTwoArguments");
diff --git a/dev/tests/verification/Resources/functionalSuiteWithComments.txt b/dev/tests/verification/Resources/functionalSuiteWithComments.txt
index c8523d0c1..6c646dd18 100644
--- a/dev/tests/verification/Resources/functionalSuiteWithComments.txt
+++ b/dev/tests/verification/Resources/functionalSuiteWithComments.txt
@@ -59,7 +59,8 @@ class functionalSuiteWithComments extends \Codeception\GroupObject
"create",
"suite",
"createThis",
- $createFields
+ [],
+ $createFields
);
print("");
$webDriver->click(PersistedObjectHandler::getInstance()->retrieveEntityField('create', 'data', 'suite')); // stepKey: clickWithData
diff --git a/dev/tests/verification/TestModule/ActionGroup/BasicActionGroup/ActionGroupReturningValueActionGroup.xml b/dev/tests/verification/TestModule/ActionGroup/BasicActionGroup/ActionGroupReturningValueActionGroup.xml
new file mode 100644
index 000000000..ddb93c0c1
--- /dev/null
+++ b/dev/tests/verification/TestModule/ActionGroup/BasicActionGroup/ActionGroupReturningValueActionGroup.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+ {{count}}
+ grabProducts1
+
+
+
+
diff --git a/dev/tests/verification/TestModule/ActionGroup/BasicActionGroup/ExtendedActionGroupReturningValueActionGroup.xml b/dev/tests/verification/TestModule/ActionGroup/BasicActionGroup/ExtendedActionGroupReturningValueActionGroup.xml
new file mode 100644
index 000000000..18933a2f2
--- /dev/null
+++ b/dev/tests/verification/TestModule/ActionGroup/BasicActionGroup/ExtendedActionGroupReturningValueActionGroup.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+ {{otherCount}}
+ grabProducts2
+
+
+
+
diff --git a/dev/tests/verification/TestModule/ActionGroup/FunctionalActionGroup/FunctionalActionGroupWithReturnValueActionGroup.xml b/dev/tests/verification/TestModule/ActionGroup/FunctionalActionGroup/FunctionalActionGroupWithReturnValueActionGroup.xml
new file mode 100644
index 000000000..77900efd3
--- /dev/null
+++ b/dev/tests/verification/TestModule/ActionGroup/FunctionalActionGroup/FunctionalActionGroupWithReturnValueActionGroup.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/dev/tests/verification/TestModule/ActionGroup/FunctionalActionGroup/MergeActionGroupReturningValueActionGroup.xml b/dev/tests/verification/TestModule/ActionGroup/FunctionalActionGroup/MergeActionGroupReturningValueActionGroup.xml
new file mode 100644
index 000000000..83afbce0c
--- /dev/null
+++ b/dev/tests/verification/TestModule/ActionGroup/FunctionalActionGroup/MergeActionGroupReturningValueActionGroup.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/tests/verification/TestModule/ActionGroup/MergeFunctionalActionGroup/MergeActionGroupReturningValueActionGroup.xml b/dev/tests/verification/TestModule/ActionGroup/MergeFunctionalActionGroup/MergeActionGroupReturningValueActionGroup.xml
new file mode 100644
index 000000000..d952fdddf
--- /dev/null
+++ b/dev/tests/verification/TestModule/ActionGroup/MergeFunctionalActionGroup/MergeActionGroupReturningValueActionGroup.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/dev/tests/verification/TestModule/Suite/functionalSuiteHooks.xml b/dev/tests/verification/TestModule/Suite/functionalSuiteHooks.xml
index 4fc459e7d..b4dca7f8d 100644
--- a/dev/tests/verification/TestModule/Suite/functionalSuiteHooks.xml
+++ b/dev/tests/verification/TestModule/Suite/functionalSuiteHooks.xml
@@ -13,10 +13,18 @@
-
+
dataHere
-
+
+
+
+
+
+
+
+
+
diff --git a/dev/tests/verification/TestModule/Test/ActionGroupFunctionalTest/ActionGroupReturningValueTest.xml b/dev/tests/verification/TestModule/Test/ActionGroupFunctionalTest/ActionGroupReturningValueTest.xml
new file mode 100644
index 000000000..ade1f51db
--- /dev/null
+++ b/dev/tests/verification/TestModule/Test/ActionGroupFunctionalTest/ActionGroupReturningValueTest.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/tests/verification/TestModule/Test/ActionGroupTest/ExtendedActionGroupReturningValueTest.xml b/dev/tests/verification/TestModule/Test/ActionGroupTest/ExtendedActionGroupReturningValueTest.xml
new file mode 100644
index 000000000..68042344c
--- /dev/null
+++ b/dev/tests/verification/TestModule/Test/ActionGroupTest/ExtendedActionGroupReturningValueTest.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/tests/verification/TestModule/Test/ActionGroupTest/ExtendedChildActionGroupReturningValueTest.xml b/dev/tests/verification/TestModule/Test/ActionGroupTest/ExtendedChildActionGroupReturningValueTest.xml
new file mode 100644
index 000000000..ecd46c3c4
--- /dev/null
+++ b/dev/tests/verification/TestModule/Test/ActionGroupTest/ExtendedChildActionGroupReturningValueTest.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/tests/verification/TestModule/Test/MergeFunctionalTest/MergedActionGroupReturningValueTest.xml b/dev/tests/verification/TestModule/Test/MergeFunctionalTest/MergedActionGroupReturningValueTest.xml
new file mode 100644
index 000000000..baf7c0ded
--- /dev/null
+++ b/dev/tests/verification/TestModule/Test/MergeFunctionalTest/MergedActionGroupReturningValueTest.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/tests/verification/Tests/ActionGroupWithReturnGenerationTest.php b/dev/tests/verification/Tests/ActionGroupWithReturnGenerationTest.php
new file mode 100644
index 000000000..e369a797d
--- /dev/null
+++ b/dev/tests/verification/Tests/ActionGroupWithReturnGenerationTest.php
@@ -0,0 +1,52 @@
+generateAndCompareTest('ActionGroupReturningValueTest');
+ }
+ /**
+ * Test generation of a test referencing a merged action group that returns a value.
+ *
+ * @throws \Exception
+ * @throws \Magento\FunctionalTestingFramework\Exceptions\TestReferenceException
+ */
+ public function testMergedActionGroupReturningValue()
+ {
+ $this->generateAndCompareTest('MergedActionGroupReturningValueTest');
+ }
+ /**
+ * Test generation of a test referencing an extended action group that returns a value.
+ *
+ * @throws \Exception
+ * @throws \Magento\FunctionalTestingFramework\Exceptions\TestReferenceException
+ */
+ public function testExtendedActionGroupReturningValue()
+ {
+ $this->generateAndCompareTest('ExtendedActionGroupReturningValueTest');
+ }
+ /**
+ * Test generation of a test referencing an extending child action group that returns a value.
+ *
+ * @throws \Exception
+ * @throws \Magento\FunctionalTestingFramework\Exceptions\TestReferenceException
+ */
+ public function testExtendedChildActionGroupReturningValue()
+ {
+ $this->generateAndCompareTest('ExtendedChildActionGroupReturningValueTest');
+ }
+}
diff --git a/docs/data.md b/docs/data.md
index 8b0a86e3d..d642763d0 100644
--- a/docs/data.md
+++ b/docs/data.md
@@ -78,6 +78,8 @@ A test can also reference data that was returned as a result of [test actions][]
Further in the test, the data grabbed by the `someSelector` selector can be referenced using the `stepKey` value. In this case, it is `grabStepKey`.
+The `stepKey` value can only be referenced within the test scope that it is defined in (`test`, `before/after`).
+
The following example shows the usage of `grabValueFrom` in testing, where the returned value is used by action's `stepKey`:
```xml
diff --git a/docs/test/action-groups.md b/docs/test/action-groups.md
index 70af0621a..05adf795e 100644
--- a/docs/test/action-groups.md
+++ b/docs/test/action-groups.md
@@ -180,6 +180,34 @@ MFTF resolves `{{myCustomEntity.field1}}` the same as it would in a `selector` o
```
+## Return a value
+
+Action groups can return a value using a `return` tag.
+
+```xml
+
+
+
+
+
+```
+
+The value returned can be accessed in later steps using action group step key `{$getOrderId}`.
+```xml
+
+
+
+
+
+```
+### Convention to return a value
+
+The following conventions apply to action groups returning a value:
+- Only action groups can return value. Use of `return` tag is dis-allowed in tests and suites.
+- An action group does not support multiple `return` tags.
+- For [merging action groups](../merging.md#merge-action-groups), `return` is allowed only in one of the merging action groups.
+- Value returned by an action group can only be referenced within the scope that the action group is defined in (`test`, `before/after`).
+
## Optimizing action group structures
Structuring properly an action group increases code reusability and readability.
diff --git a/docs/test/actions.md b/docs/test/actions.md
index 1d2f83802..562f6e8ff 100644
--- a/docs/test/actions.md
+++ b/docs/test/actions.md
@@ -151,6 +151,7 @@ The following test actions return a variable:
* [grabValueFrom](#grabvaluefrom)
* [executeJS](#executejs)
* [getOTP](#getotp)
+* [return](#return)
Learn more in [Using data returned by test actions](../data.md#use-data-returned-by-test-actions).
@@ -1240,6 +1241,21 @@ To access this value, use `{$grabInputName}` in later actions. -->
```
+### return
+
+Specifies what value is returned by an action group. The value can be then accessed in later steps using the action group stepKey. See [Action groups returning a value](./action-groups.md#return-a-value) for usage information.
+
+Attribute|Type|Use|Description
+---|---|---|---
+`value`|string|required| value returned by action group.
+`stepKey`|string|required| A unique identifier of the action.
+
+#### Example
+```xml
+
+
]>
diff --git a/src/Magento/FunctionalTestingFramework/Module/MagentoPwaWebDriver.php b/src/Magento/FunctionalTestingFramework/Module/MagentoPwaWebDriver.php
index 9b75cb10d..272f4206d 100644
--- a/src/Magento/FunctionalTestingFramework/Module/MagentoPwaWebDriver.php
+++ b/src/Magento/FunctionalTestingFramework/Module/MagentoPwaWebDriver.php
@@ -17,37 +17,57 @@
*/
class MagentoPwaWebDriver extends MagentoWebDriver
{
+ /**
+ * List of known PWA loading masks by selector
+ *
+ * Overriding the MagentoWebDriver array to contain applicable PWA locators.
+ *
+ * @var array
+ */
+ protected $loadingMasksLocators = [
+ '//div[contains(@class, "indicator-global-")]',
+ '//div[contains(@class, "indicator-root-")]',
+ '//img[contains(@class, "indicator-indicator-")]',
+ '//span[contains(@class, "indicator-message-")]'
+ ];
+
/**
* Go to the page.
*
* Overriding the MagentoWebDriver version because it contains 'waitForPageLoad'.
* The AJAX check in 'waitForPageLoad' does NOT work with a PWA.
*
- * @param string $page
+ * @param string $page
+ * @param integer $timeout
* @throws \Exception
* @return void
*/
- public function amOnPage($page)
+ public function amOnPage($page, $timeout = null)
{
WebDriver::amOnPage($page);
+ $this->waitForLoadingMaskToDisappear($timeout);
}
/**
* Wait for a PWA Element to NOT be visible using JavaScript.
* Add the WAIT_TIMEOUT variable to your .env file for this action.
*
- * @param null $selector
- * @param null $timeout
+ * @param string $selector
+ * @param integer $timeout
* @throws \Exception
* @return void
*/
public function waitForPwaElementNotVisible($selector, $timeout = null)
{
+ $timeout = $timeout ?? $this->_getConfig()['pageload_timeout'];
+
// Determine what type of Selector is used.
// Then use the correct JavaScript to locate the Element.
if (\Codeception\Util\Locator::isXPath($selector)) {
+ $this->waitForLoadingMaskToDisappear($timeout);
$this->waitForJS("return !document.evaluate(`$selector`, document);", $timeout);
} else {
+ $this->waitForLoadingMaskToDisappear($timeout);
$this->waitForJS("return !document.querySelector(`$selector`);", $timeout);
}
}
@@ -56,18 +76,22 @@ public function waitForPwaElementNotVisible($selector, $timeout = null)
* Wait for a PWA Element to be visible using JavaScript.
* Add the WAIT_TIMEOUT variable to your .env file for this action.
*
- * @param null $selector
- * @param null $timeout
+ * @param string $selector
+ * @param integer $timeout
* @throws \Exception
* @return void
*/
public function waitForPwaElementVisible($selector, $timeout = null)
{
+ $timeout = $timeout ?? $this->_getConfig()['pageload_timeout'];
+
// Determine what type of Selector is used.
// Then use the correct JavaScript to locate the Element.
if (\Codeception\Util\Locator::isXPath($selector)) {
+ $this->waitForLoadingMaskToDisappear($timeout);
$this->waitForJS("return !!document && !!document.evaluate(`$selector`, document);", $timeout);
} else {
+ $this->waitForLoadingMaskToDisappear($timeout);
$this->waitForJS("return !!document && !!document.querySelector(`$selector`);", $timeout);
}
}
diff --git a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php
index 984881e4e..944735677 100644
--- a/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php
+++ b/src/Magento/FunctionalTestingFramework/Module/MagentoWebDriver.php
@@ -63,7 +63,7 @@ class MagentoWebDriver extends WebDriver
*
* @var array
*/
- public static $loadingMasksLocators = [
+ protected $loadingMasksLocators = [
'//div[contains(@class, "loading-mask")]',
'//div[contains(@class, "admin_data-grid-loading-mask")]',
'//div[contains(@class, "admin__data-grid-loading-mask")]',
@@ -439,7 +439,9 @@ public function waitForPageLoad($timeout = null)
*/
public function waitForLoadingMaskToDisappear($timeout = null)
{
- foreach (self::$loadingMasksLocators as $maskLocator) {
+ $timeout = $timeout ?? $this->_getConfig()['pageload_timeout'];
+
+ foreach ($this->loadingMasksLocators as $maskLocator) {
// Get count of elements found for looping.
// Elements are NOT useful for interaction, as they cannot be fed to codeception actions.
$loadingMaskElements = $this->_findElements($maskLocator);
@@ -1120,4 +1122,16 @@ public function switchToIFrame($locator = null)
$this->webDriver->switchTo()->frame($els[0]);
}
}
+
+ /**
+ * Returns a value to origin of the action.
+ * TODO: move this function to MagentoActionProxies after MQE-1904
+ *
+ * @param mixed $value
+ * @return mixed
+ */
+ public function return($value)
+ {
+ return $value;
+ }
}
diff --git a/src/Magento/FunctionalTestingFramework/Suite/Generators/GroupClassGenerator.php b/src/Magento/FunctionalTestingFramework/Suite/Generators/GroupClassGenerator.php
index 67930f09a..bb0157152 100644
--- a/src/Magento/FunctionalTestingFramework/Suite/Generators/GroupClassGenerator.php
+++ b/src/Magento/FunctionalTestingFramework/Suite/Generators/GroupClassGenerator.php
@@ -225,16 +225,16 @@ private function buildPersistenceMustacheArray($action, $entityArray)
$action->getCustomActionAttributes()[TestGenerator::REQUIRED_ENTITY_REFERENCE];
// append entries for any required entities to this entry
- if (array_key_exists('requiredEntities', $action->getCustomActionAttributes())) {
- $entityArray[self::REQUIRED_ENTITY_KEY] =
- $this->buildReqEntitiesMustacheArray($action->getCustomActionAttributes());
+ $requiredEntities = $this->buildReqEntitiesMustacheArray($action->getCustomActionAttributes());
+ if (!array_key_exists(-1, $requiredEntities)) {
+ $entityArray[self::REQUIRED_ENTITY_KEY] = $requiredEntities;
}
// append entries for customFields if specified by the user.
if (array_key_exists('customFields', $action->getCustomActionAttributes())) {
$entityArray['customFields'] = $action->getStepKey() . 'Fields';
}
-
+
return $entityArray;
}
diff --git a/src/Magento/FunctionalTestingFramework/Suite/views/partials/testActions.mustache b/src/Magento/FunctionalTestingFramework/Suite/views/partials/testActions.mustache
index 73079f169..eaa0959cb 100644
--- a/src/Magento/FunctionalTestingFramework/Suite/views/partials/testActions.mustache
+++ b/src/Magento/FunctionalTestingFramework/Suite/views/partials/testActions.mustache
@@ -13,9 +13,9 @@ if ($webDriver->webDriver != null) {
PersistedObjectHandler::getInstance()->createEntity(
"{{stepKey}}",
"suite",
- "{{entityName}}"{{#requiredEntities}},
- [$this->{{entityName}}{{^last}}, {{/last}}]{{/requiredEntities}}{{#customFields}},
- ${{customFields}}{{/customFields}}
+ "{{entityName}}",
+ [{{#requiredEntities}}"{{entityName}}"{{^last}}, {{/last}}{{/requiredEntities}}]{{#customFields}},
+ ${{customFields}}{{/customFields}}
);
{{/createData}}
{{#deleteData}}
diff --git a/src/Magento/FunctionalTestingFramework/Test/etc/Actions/customActions.xsd b/src/Magento/FunctionalTestingFramework/Test/etc/Actions/customActions.xsd
index 2aad30c75..b1d6e1b02 100644
--- a/src/Magento/FunctionalTestingFramework/Test/etc/Actions/customActions.xsd
+++ b/src/Magento/FunctionalTestingFramework/Test/etc/Actions/customActions.xsd
@@ -29,6 +29,12 @@
+
+
+
+
+
+
@@ -346,6 +352,26 @@
+
+
+
+ Used in an action group to return a value. Must be used only once in action group. Do not use in tests or suites.
+
+
+
+
+
+
+
+ Value or variable to be returned.
+
+
+
+
+
+
+
+
diff --git a/src/Magento/FunctionalTestingFramework/Test/etc/actionTypeTags.xsd b/src/Magento/FunctionalTestingFramework/Test/etc/actionTypeTags.xsd
index def2964af..d68cf43db 100644
--- a/src/Magento/FunctionalTestingFramework/Test/etc/actionTypeTags.xsd
+++ b/src/Magento/FunctionalTestingFramework/Test/etc/actionTypeTags.xsd
@@ -68,6 +68,12 @@
+
+
+
+
+
+
diff --git a/src/Magento/FunctionalTestingFramework/Test/etc/mergedActionGroupSchema.xsd b/src/Magento/FunctionalTestingFramework/Test/etc/mergedActionGroupSchema.xsd
index bd32ba879..f45c33acd 100644
--- a/src/Magento/FunctionalTestingFramework/Test/etc/mergedActionGroupSchema.xsd
+++ b/src/Magento/FunctionalTestingFramework/Test/etc/mergedActionGroupSchema.xsd
@@ -15,29 +15,21 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -57,4 +49,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php b/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php
index 8253a75ba..80056b3b9 100644
--- a/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php
+++ b/src/Magento/FunctionalTestingFramework/Util/TestGenerator.php
@@ -1172,6 +1172,16 @@ public function generateStepsPhp($actionObjects, $generationScope = TestGenerato
$selector
);
break;
+ case "return":
+ $actionOrigin = $actionObject->getActionOrigin();
+ $actionOriginStepKey = $actionOrigin[ActionGroupObject::ACTION_GROUP_ORIGIN_TEST_REF];
+ $testSteps .= $this->wrapFunctionCallWithReturnValue(
+ $actionOriginStepKey,
+ $actor,
+ $actionObject,
+ $value
+ );
+ break;
case "formatCurrency":
$testSteps .= $this->wrapFunctionCallWithReturnValue(
$stepKey,