Skip to content

Commit

Permalink
Merge pull request #150 from magento-commerce/develop
Browse files Browse the repository at this point in the history
MFTF 3.8.0 Release preparation
  • Loading branch information
okolesnyk authored Jan 7, 2022
2 parents 40dd3eb + c930b9a commit a934c0b
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 24 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
Magento Functional Testing Framework Changelog
================================================
3.8.0
---------

### Updates:
* Allow MFTF Helpers to Return Data to MFTF Test
* Improve parallel grouping and fix an issue with unbalanced groups
* Added new action WaitForElementClickable

3.7.3
---------

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "magento/magento2-functional-testing-framework",
"description": "Magento2 Functional Testing Framework",
"type": "library",
"version": "3.7.3",
"version": "3.8.0",
"license": "AGPL-3.0",
"keywords": ["magento", "automation", "functional", "testing"],
"config": {
Expand Down
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions dev/tests/functional/tests/MFTF/DevDocs/Helper/CustomHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,15 @@ public function goTo(
print('$bla = ' . $bla . PHP_EOL);
print('array $arraysomething = [' . implode(', ', $arraysomething) . ']' . PHP_EOL);
}

/**
* Returns value of provided param $text
*
* @param string $text
* @return string
*/
public function getText(string $text): string
{
return $text;
}
}
8 changes: 8 additions & 0 deletions dev/tests/functional/tests/MFTF/DevDocs/Test/DevDocsTest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@
<argument name="int">987</argument>
</helper>

<helper class="\MFTF\DevDocs\Helper\CustomHelper" method="getText" stepKey="getText">
<argument name="text">some text</argument>
</helper>
<assertEquals stepKey="assertHelperReturnValue" message="Method getText of CustomHelper should return value which may be used as variable in test">
<expectedResult type="string">some text</expectedResult>
<actualResult type="variable">getText</actualResult>
</assertEquals>

<actionGroup ref="HelperActionGroup" stepKey="actionGroupWithCustomHelper">
<argument name="test" value="{{HelperData.entityField}}" />
<argument name="entityTest" value="HelperData" />
Expand Down
1 change: 1 addition & 0 deletions dev/tests/verification/Resources/DataActionsTest.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class DataActionsTestCest
*/
public function DataActionsTest(AcceptanceTester $I)
{
$I->waitForElementClickable(".functionalTestSelector"); // stepKey: waitForElementClickable
$I->createEntity("createdInTest", "test", "entity", [], []); // stepKey: createdInTest
$I->updateEntity("createdInTest", "test", "entity",[]); // stepKey: updateInTest
$I->deleteEntity("createdInTest", "test"); // stepKey: deleteInTest
Expand Down
3 changes: 2 additions & 1 deletion dev/tests/verification/TestModule/Test/DataActionsTest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
<createData entity="entity" stepKey="createdInBefore"/>
<updateData entity="entity" createDataKey="createdInBefore" stepKey="updateInBefore"/>
<deleteData createDataKey="createdInBefore" stepKey="deleteInBefore"/>
</before>

</before>
<waitForElementClickable selector=".functionalTestSelector" time="30" stepKey="waitForElementClickable" />
<createData entity="entity" stepKey="createdInTest"/>
<updateData entity="entity" createDataKey="createdInTest" stepKey="updateInTest"/>
<deleteData createDataKey="createdInTest" stepKey="deleteInTest"/>
Expand Down
20 changes: 19 additions & 1 deletion docs/test/actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2374,10 +2374,28 @@ Attribute|Type|Use|Description
#### Example

```xml
<!-- Wait up to 30 seconds for `<div id="changedElement" ... >...</div>` to become visible on the page before continuing. -->
<waitForElementVisible selector="#changedElement" stepKey="waitForElementVisible"/>
```

### waitForElementClickable

See [waitForElementClickable docs on codeception.com](http://codeception.com/docs/modules/WebDriver#waitForElementClickable).

Attribute|Type|Use|Description
---|---|---|---
`selector`|string|optional| The selector identifying the corresponding HTML element.
`time`|string|optional| The number of seconds to wait for the element to appear.
`stepKey`|string|required| A unique identifier of the action.
`before`|string|optional| `stepKey` of action that must be executed next.
`after`|string|optional| `stepKey` of preceding action.

#### Example

```xml
<!-- Waits up to $timeout seconds for the given element to be clickable. If element doesn’t become clickable, a timeout exception is thrown. -->
<waitForElementClickable selector="#changedElement" stepKey="waitForElementClickable"/>
```

### waitForJS

See [waitForJS docs on codeception.com](http://codeception.com/docs/modules/WebDriver#waitForJS).
Expand Down
44 changes: 41 additions & 3 deletions src/Magento/FunctionalTestingFramework/Test/Objects/TestObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,35 @@ class TestObject

const TEST_ACTION_WEIGHT = [
'waitForPageLoad' => 1500,
'amOnPage' => 1000,
'amOnPage' => 1500,
'waitForLoadingMaskToDisappear' => 500,
'wait' => self::WAIT_TIME_ATTRIBUTE,
'waitForAjaxLoad' => 500,
'waitForElementNotVisible' => 500,
'waitForElementVisible' => 500,
'waitForText' => 500,
'waitForElement' => 500,
'waitForJS' => 500,
'comment' => 5,
'assertCount' => 5,
'closeAdminNotification' => 10
'closeAdminNotification' => 10,
'magentoCLI' => 1000,
'magentoCron' => 3000,
'createData' => 500,
'deleteData' => 200,
'updateData' => 200,
'getOTP' => 1000,
];

const WEBAPI_AUTH_TEST_ACTIONS = [
'createData',
'deleteData',
'updateData',
'getData',
];

const WEBAPI_AUTH_TEST_ACTION_WEIGHT = 6000;

/**
* Name of the test
*
Expand Down Expand Up @@ -85,6 +106,13 @@ class TestObject
*/
private $deprecated;

/**
* Indicates if a test contains an action that requires Web API authentication.
*
* @var boolean
*/
private $hasWebApiAuthAction;

/**
* TestObject constructor.
*
Expand Down Expand Up @@ -112,6 +140,7 @@ public function __construct(
$this->filename = $filename;
$this->parentTest = $parentTest;
$this->deprecated = $deprecated;
$this->hasWebApiAuthAction = false;
}

/**
Expand Down Expand Up @@ -222,7 +251,11 @@ public function getEstimatedDuration()

$testTime = $this->calculateWeightedActionTimes($this->getOrderedActions());

return $hookTime + $testTime;
if ($this->hasWebApiAuthAction) {
return $hookTime + $testTime + self::WEBAPI_AUTH_TEST_ACTION_WEIGHT;
} else {
return $hookTime + $testTime;
}
}

/**
Expand All @@ -237,6 +270,11 @@ private function calculateWeightedActionTimes($actions)
// search for any actions of special type
foreach ($actions as $action) {
/** @var ActionObject $action */

if (!$this->hasWebApiAuthAction && in_array($action->getType(), self::WEBAPI_AUTH_TEST_ACTIONS)) {
$this->hasWebApiAuthAction = true;
}

if (array_key_exists($action->getType(), self::TEST_ACTION_WEIGHT)) {
$weight = self::TEST_ACTION_WEIGHT[$action->getType()];
if ($weight === self::WAIT_TIME_ATTRIBUTE) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
<xs:element type="waitForPwaElementNotVisibleType" name="waitForPwaElementNotVisible" minOccurs="0" maxOccurs="unbounded"/>
<xs:element type="waitForPwaElementVisibleType" name="waitForPwaElementVisible" minOccurs="0" maxOccurs="unbounded"/>
<xs:element type="waitForTextType" name="waitForText" minOccurs="0" maxOccurs="unbounded"/>
<xs:element type="waitForElementClickableType" name="waitForElementClickable" minOccurs="0" maxOccurs="unbounded"/>

</xs:choice>
</xs:group>

Expand Down Expand Up @@ -224,4 +226,19 @@
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="waitForElementClickableType">
<xs:annotation>
<xs:documentation>
Waits up to $timeout seconds for the given element to be clickable.
If element doesn’t become clickable, a timeout exception is thrown.
</xs:documentation>
</xs:annotation>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute ref="selector" use="required"/>
<xs:attribute ref="time"/>
<xs:attributeGroup ref="commonActionAttributes"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>
35 changes: 18 additions & 17 deletions src/Magento/FunctionalTestingFramework/Util/TestGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,12 @@ public function generateStepsPhp($actionObjects, $generationScope = TestGenerato
$stepKey,
$customActionAttributes['class'] . '::' . $customActionAttributes['method']
);
$testSteps .= $this->wrapFunctionCall($actor, $actionObject, $arguments);
$testSteps .= $this->wrapFunctionCallWithReturnValue(
$stepKey,
$actor,
$actionObject,
$arguments
);
break;
case "createData":
$entity = $customActionAttributes['entity'];
Expand Down Expand Up @@ -2016,16 +2021,7 @@ private function addDollarSign($input)
*/
private function wrapFunctionCall($actor, $action, ...$args)
{
$isFirst = true;
$isActionHelper = $action->getType() === 'helper';
$actionType = $action->getType();
if ($isActionHelper) {
$actor = "this->helperContainer->get('" . $action->getCustomActionAttributes()['class'] . "')";
$args = $args[0];
$actionType = $action->getCustomActionAttributes()['method'];
}

$output = sprintf("\t\t$%s->%s(", $actor, $actionType);
$output = sprintf("\t\t$%s->%s(", $actor, $action->getType());
for ($i = 0; $i < count($args); $i++) {
if (null === $args[$i]) {
continue;
Expand All @@ -2046,17 +2042,22 @@ private function wrapFunctionCall($actor, $action, ...$args)
/**
* Wrap parameters into a function call with a return value.
*
* @param string $returnVariable
* @param string $actor
* @param string $action
* @param array ...$args
* @param string $returnVariable
* @param string $actor
* @param actionObject $action
* @param array ...$args
* @return string
* @throws \Exception
*/
private function wrapFunctionCallWithReturnValue($returnVariable, $actor, $action, ...$args)
{
$isFirst = true;
$output = sprintf("\t\t$%s = $%s->%s(", $returnVariable, $actor, $action->getType());
$actionType = $action->getType();
if ($actionType === 'helper') {
$actor = "this->helperContainer->get('" . $action->getCustomActionAttributes()['class'] . "')";
$args = $args[0];
$actionType = $action->getCustomActionAttributes()['method'];
}
$output = sprintf("\t\t$%s = $%s->%s(", $returnVariable, $actor, $actionType);
for ($i = 0; $i < count($args); $i++) {
if (null === $args[$i]) {
continue;
Expand Down

0 comments on commit a934c0b

Please sign in to comment.