Skip to content

Commit ad8cad9

Browse files
committed
MQE-309:[Customizability] Update nested API dependency schema and execution
- change test schema for simpler persisted entity relationships - change data persistence handler to resolve entity relationships - change data schema to allow var declaration as a placehold for persisted data
1 parent baef8f0 commit ad8cad9

File tree

9 files changed

+152
-69
lines changed

9 files changed

+152
-69
lines changed

etc/di.xml

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,8 @@
204204
<argument name="idAttributes" xsi:type="array">
205205
<item name="/config/cest" xsi:type="string">name</item>
206206
<item name="/config/cest/test" xsi:type="string">name</item>
207-
<item name="/config/cest/test/entity/data" xsi:type="string">key</item>
208-
<item name="/config/cest/test/entity/required-entity" xsi:type="string">key</item>
209207
<item name="/config/cest/test/actionGroup/argument" xsi:type="string">name</item>
210-
<item name="/config/cest/test/createData/required-entity" xsi:type="string">name</item>
208+
<item name="/config/cest/test/createData/required-entity" xsi:type="string">persistedKey</item>
211209
<item name="/config/cest/test/(acceptPopup|amOnPage|amOnUrl|appendField|assertArraySubset|attachFile|cancelPopup|checkOption|click|clickWithLeftButton|clickWithRightButton|closeTab|createData|deleteData|dontSee|dontSeeCheckboxIsChecked|dontSeeCookie|dontSeeCurrentUrlEquals|dontSeeCurrentUrlMatches|dontSeeElement|dontSeeElementInDOM|dontSeeInCurrentUrl|dontSeeInField|dontSeeInPageSource|dontSeeInSource|dontSeeInTitle|dontSeeLink|dontSeeOptionIsSelected|doubleClick|dragAndDrop|entity|executeJS|fillField|formatMoney|grabAttributeFrom|grabCookie|grabFromCurrentUrl|grabMultiple|grabPageSource|grabTextFrom|grabValueFrom|loadSessionSnapshot|loginAsAdmin|makeScreenshot|maximizeWindow|moveBack|moveForward|moveMouseOver|openNewTab|pauseExecution|performOn|pressKey|reloadPage|resetCookie|resizeWindow|scrollTo|searchAndMultiSelectOption|see|seeCheckboxIsChecked|seeCookie|seeCurrentUrlEquals|seeCurrentUrlMatches|seeElement|seeElementInDOM|seeInCurrentUrl|seeInField|seeInFormFields|seeInPageSource|seeInPopup|seeInSource|seeInTitle|seeLink|seeNumberOfElements|seeOptionIsSelected|selectOption|setCookie|switchToIFrame|switchToNextTab|switchToPreviousTab|switchToWindow|typeInPopup|uncheckOption|unselectOption|wait|waitForAjaxLoad|waitForElement|waitForElementChange|waitForElementNotVisible|waitForElementVisible|waitForJS|waitForLoadingMaskToDisappear|waitForPageLoad|waitForText)" xsi:type="string">mergeKey</item>
212210
</argument>
213211
<argument name="fileName" xsi:type="string">*Cest.xml</argument>
@@ -223,15 +221,9 @@
223221
<item name="/config/cest/after/(acceptPopup|amOnPage|amOnUrl|appendField|assertArraySubset|attachFile|cancelPopup|checkOption|click|clickWithLeftButton|clickWithRightButton|closeTab|createData|deleteData|dontSee|dontSeeCheckboxIsChecked|dontSeeCookie|dontSeeCurrentUrlEquals|dontSeeCurrentUrlMatches|dontSeeElement|dontSeeElementInDOM|dontSeeInCurrentUrl|dontSeeInField|dontSeeInPageSource|dontSeeInSource|dontSeeInTitle|dontSeeLink|dontSeeOptionIsSelected|doubleClick|dragAndDrop|entity|executeJS|fillField|formatMoney|grabAttributeFrom|grabCookie|grabFromCurrentUrl|grabMultiple|grabPageSource|grabTextFrom|grabValueFrom|loadSessionSnapshot|loginAsAdmin|makeScreenshot|maximizeWindow|moveBack|moveForward|moveMouseOver|openNewTab|pauseExecution|performOn|pressKey|reloadPage|resetCookie|resizeWindow|scrollTo|searchAndMultiSelectOption|see|seeCheckboxIsChecked|seeCookie|seeCurrentUrlEquals|seeCurrentUrlMatches|seeElement|seeElementInDOM|seeInCurrentUrl|seeInField|seeInFormFields|seeInPageSource|seeInPopup|seeInSource|seeInTitle|seeLink|seeNumberOfElements|seeOptionIsSelected|selectOption|setCookie|switchToIFrame|switchToNextTab|switchToPreviousTab|switchToWindow|typeInPopup|uncheckOption|unselectOption|wait|waitForAjaxLoad|waitForElement|waitForElementChange|waitForElementNotVisible|waitForElementVisible|waitForJS|waitForLoadingMaskToDisappear|waitForPageLoad|waitForText)" xsi:type="string">mergeKey</item>
224222
<item name="/config/cest/test" xsi:type="string">name</item>
225223
<item name="/config/cest" xsi:type="string">name</item>
226-
<item name="/config/cest/test/entity/data" xsi:type="string">key</item>
227-
<item name="/config/cest/test/entity/required-entity" xsi:type="string">key</item>
228-
<item name="/config/cest/test/createData/required-entity" xsi:type="string">name</item>
229-
<item name="/config/cest/before/entity/data" xsi:type="string">key</item>
230-
<item name="/config/cest/before/entity/required-entity" xsi:type="string">key</item>
231-
<item name="/config/cest/before/createData/required-entity" xsi:type="string">name</item>
232-
<item name="/config/cest/after/entity/data" xsi:type="string">key</item>
233-
<item name="/config/cest/after/entity/required-entity" xsi:type="string">key</item>
234-
<item name="/config/cest/after/createData/required-entity" xsi:type="string">name</item>
224+
<item name="/config/cest/test/createData/required-entity" xsi:type="string">persistedKey</item>
225+
<item name="/config/cest/before/createData/required-entity" xsi:type="string">persistedKey</item>
226+
<item name="/config/cest/after/createData/required-entity" xsi:type="string">persistedKey</item>
235227
<item name="/config/cest/test/actionGroup/argument" xsi:type="string">name</item>
236228
</argument>
237229
<argument name="numericArrays" xsi:type="array">

src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/DataObjectHandler.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ class DataObjectHandler implements ObjectHandlerInterface
4343
const ARRAY_ELEMENT_ITEM = 'item';
4444
const ARRAY_ELEMENT_ITEM_VALUE = 'value';
4545

46+
const VAR_VALUES = 'var';
47+
const VAR_KEY = 'key';
48+
const VAR_ENTITY = 'entityType';
49+
const VAR_FIELD = 'entityKey';
50+
const VAR_ENTITY_FIELD_SEPARATOR = '->';
51+
4652
const REQUIRED_ENTITY = 'required-entity';
4753
const REQUIRED_ENTITY_TYPE = 'type';
4854
const REQUIRED_ENTITY_VALUE = 'value';
@@ -150,6 +156,7 @@ private function parseDataEntities()
150156
$dataValues = [];
151157
$linkedEntities = [];
152158
$arrayValues = [];
159+
$vars = [];
153160
$uniquenessValues = [];
154161

155162
if (array_key_exists(self::DATA_VALUES, $entity)) {
@@ -186,12 +193,21 @@ private function parseDataEntities()
186193
}
187194
}
188195

196+
if (array_key_exists(self::VAR_VALUES, $entity)) {
197+
foreach ($entity[self::VAR_VALUES] as $varElement) {
198+
$varKey = $varElement[self::VAR_KEY];
199+
$varValue = $varElement[self::VAR_ENTITY] . self::VAR_ENTITY_FIELD_SEPARATOR . $varElement[self::VAR_FIELD];
200+
$vars[$varKey] = $varValue;
201+
}
202+
}
203+
189204
$entityDataObject = new EntityDataObject(
190205
$entityName,
191206
$entityType,
192207
$dataValues,
193208
$linkedEntities,
194-
$uniquenessValues
209+
$uniquenessValues,
210+
$vars
195211
);
196212

197213
$this->data[$entityDataObject->getName()] = $entityDataObject;

src/Magento/FunctionalTestingFramework/DataGenerator/Handlers/OperationDefinitionObjectHandler.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,14 @@ private function initDataDefinitions()
201201
} else {
202202
$value = $operationField[OperationDefinitionObjectHandler::ENTITY_OPERATION_ARRAY_VALUE][0]
203203
[OperationDefinitionObjectHandler::ENTITY_OPERATION_ARRAY_VALUE];
204-
$type = [OperationDefinitionObjectHandler::ENTITY_OPERATION_ARRAY_VALUE];
204+
$type = OperationDefinitionObjectHandler::ENTITY_OPERATION_ARRAY;
205205
}
206206

207207
$operationElements[] = new OperationElement(
208208
$operationField[OperationDefinitionObjectHandler::ENTITY_OPERATION_ARRAY_KEY],
209209
$value,
210210
$type,
211-
$dataEntryType[OperationDefinitionObjectHandler::ENTITY_OPERATION_REQUIRED] ?? null,
211+
$operationField[OperationDefinitionObjectHandler::ENTITY_OPERATION_REQUIRED] ?? null,
212212
$subOperationElements
213213
);
214214
}

src/Magento/FunctionalTestingFramework/DataGenerator/Objects/EntityDataObject.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ class EntityDataObject
3434
*/
3535
private $linkedEntities = [];
3636

37+
/**
38+
* An array of variable mappings for static data
39+
*
40+
* @var array
41+
*/
42+
private $vars;
43+
3744
/**
3845
* An array of Data Name to Data Value
3946
*
@@ -63,8 +70,9 @@ class EntityDataObject
6370
* @param array $data
6471
* @param array $linkedEntities
6572
* @param array $uniquenessData
73+
* @param array $vars
6674
*/
67-
public function __construct($entityName, $entityType, $data, $linkedEntities, $uniquenessData)
75+
public function __construct($entityName, $entityType, $data, $linkedEntities, $uniquenessData, $vars = [])
6876
{
6977
$this->name = $entityName;
7078
$this->type = $entityType;
@@ -73,6 +81,8 @@ public function __construct($entityName, $entityType, $data, $linkedEntities, $u
7381
if ($uniquenessData) {
7482
$this->uniquenessData = $uniquenessData;
7583
}
84+
85+
$this->vars = $vars;
7686
}
7787

7888
/**
@@ -189,6 +199,22 @@ public function getDataByName($dataName, $uniDataFormat)
189199
return null;
190200
}
191201

202+
/**
203+
* Function which returns a reference to another entity (e.g. a var with entity="category" field="id" returns as
204+
* category->id)
205+
*
206+
* @param string $dataKey
207+
* @return array|null
208+
*/
209+
public function getVarReference($dataKey)
210+
{
211+
if (array_key_exists($dataKey, $this->vars)) {
212+
return $this->vars[$dataKey];
213+
}
214+
215+
return null;
216+
}
217+
192218
/**
193219
* This function takes an array of entityTypes indexed by name and a string that represents the type of interest.
194220
* The function returns an array of entityNames relevant to the specified type.

src/Magento/FunctionalTestingFramework/DataGenerator/Persist/DataPersistenceHandler.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class DataPersistenceHandler
3131
* Array of dependent entities, handed to CurlHandler when entity is created.
3232
* @var array|null
3333
*/
34-
private $dependentObjects = [];
34+
private $dependentObjects;
3535

3636
/**
3737
* Store code in web api rest url.
@@ -46,11 +46,14 @@ class DataPersistenceHandler
4646
* @param EntityDataObject $entityObject
4747
* @param array $dependentObjects
4848
*/
49-
public function __construct($entityObject, $dependentObjects = null)
49+
public function __construct($entityObject, $dependentObjects = [])
5050
{
5151
$this->entityObject = clone $entityObject;
52-
$this->dependentObjects = $dependentObjects;
5352
$this->storeCode = 'default';
53+
54+
foreach ($dependentObjects as $dependentObject) {
55+
$this->dependentObjects[] = $dependentObject->getCreatedObject();
56+
}
5457
}
5558

5659
/**

src/Magento/FunctionalTestingFramework/DataGenerator/Persist/OperationDataArrayResolver.php

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ class OperationDataArrayResolver
1818
'string',
1919
'boolean',
2020
'integer',
21-
'double',
22-
OperationDefinitionObjectHandler::ENTITY_OPERATION_ARRAY
21+
'double'
2322
];
2423
const EXCEPTION_REQUIRED_DATA = "%s of key \" %s\" in \"%s\" is required by metadata, but was not provided.";
2524

@@ -82,9 +81,10 @@ public function resolveOperationDataArray($entityObject, $operationMetadata, $op
8281
$operationElementType = $operationElement->getValue();
8382

8483
if (in_array($operationElementType, self::PRIMITIVE_TYPES)) {
85-
$elementData = $entityObject->getDataByName(
84+
$elementData = $this->resolvePrimitiveReference(
85+
$entityObject,
8686
$operationElement->getKey(),
87-
EntityDataObject::CEST_UNIQUE_VALUE
87+
$operationElement->getType()
8888
);
8989

9090
// If data was defined at all, attempt to put it into operation data array
@@ -143,6 +143,67 @@ public function resolveOperationDataArray($entityObject, $operationMetadata, $op
143143
return $operationDataArray;
144144
}
145145

146+
/**
147+
* Resolves a reference for a primitive piece of data, if the data cannot be found as a defined field, the method
148+
* looks to see if any vars have been declared with the same operationKey and resolves based on defined dependent
149+
* entities.
150+
*
151+
* @param EntityDataObject $entityObject
152+
* @param string $operationKey
153+
* @param string $operationElementType
154+
* @return array|string
155+
*/
156+
private function resolvePrimitiveReference($entityObject, $operationKey, $operationElementType)
157+
{
158+
$elementData = $entityObject->getDataByName(
159+
$operationKey,
160+
EntityDataObject::CEST_UNIQUE_VALUE
161+
);
162+
163+
if ($elementData == null && $entityObject->getVarReference($operationKey) != null) {
164+
list($type, $field) = explode(
165+
DataObjectHandler::VAR_ENTITY_FIELD_SEPARATOR,
166+
$entityObject->getVarReference($operationKey)
167+
);
168+
169+
if ($operationElementType == OperationDefinitionObjectHandler::ENTITY_OPERATION_ARRAY) {
170+
$elementDatas = [];
171+
$entities = $this->getDependentEntitiesOfType($type);
172+
foreach ($entities as $entity) {
173+
$elementDatas[] = $entity->getDataByName($field, EntityDataObject::CEST_UNIQUE_VALUE);
174+
}
175+
176+
return $elementDatas;
177+
178+
}
179+
180+
$entity = $this->getDependentEntitiesOfType($type)[0];
181+
$elementData = $entity->getDataByName($field, EntityDataObject::CEST_UNIQUE_VALUE);
182+
}
183+
184+
return $elementData;
185+
}
186+
187+
/**
188+
* Returns all dependent entities of the type passed in as an arg (the dependent entities are given at runtime,
189+
* and are not statically defined).
190+
*
191+
* @param string $type
192+
* @return array
193+
*/
194+
private function getDependentEntitiesOfType($type)
195+
{
196+
$entitiesOfType = [];
197+
198+
foreach ($this->dependentEntities as $dependentEntity) {
199+
if ($dependentEntity->getType() == $type) {
200+
$entitiesOfType[] = $dependentEntity;
201+
}
202+
}
203+
204+
return $entitiesOfType;
205+
}
206+
146207
/**
147208
* This function does a comparison of the entity object being matched to the operation element. If there is a
148209
* mismatch in type we attempt to use a nested entity, if the entities are properly matched, we simply return
@@ -254,6 +315,15 @@ private function castValue($type, $value)
254315
{
255316
$newVal = $value;
256317

318+
if (is_array($value)) {
319+
$newVals = [];
320+
foreach($value as $val) {
321+
$newVals[] = $this->castValue($type, $val);
322+
}
323+
324+
return $newVals;
325+
}
326+
257327
switch ($type) {
258328
case 'string':
259329
break;

src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@
3030
</xs:documentation>
3131
</xs:annotation>
3232
</xs:element>
33+
<xs:element name="var" maxOccurs="unbounded" minOccurs="0">
34+
<xs:complexType>
35+
<xs:complexContent>
36+
<xs:extension base="dataType">
37+
<xs:attribute name="entityType" type="xs:string"/>
38+
<xs:attribute name="entityKey" type="xs:string"/>
39+
</xs:extension>
40+
</xs:complexContent>
41+
</xs:complexType>
42+
</xs:element>
3343
<xs:element name="required-entity" type="requiredEntityType" maxOccurs="unbounded" minOccurs="0">
3444
<xs:annotation>
3545
<xs:documentation>

src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@
380380
<xs:complexType name="requiredEntityType">
381381
<xs:simpleContent>
382382
<xs:extension base="xs:string">
383-
<xs:attribute type="xs:string" name="name" use="required"/>
383+
<xs:attribute type="xs:string" name="persistedKey" use="required"/>
384384
<xs:attribute type="xs:boolean" name="remove" default="false"/>
385385
<xs:attribute type="xs:string" name="before"/>
386386
<xs:attribute type="xs:string" name="after"/>

0 commit comments

Comments
 (0)