Skip to content

Commit 3980852

Browse files
committed
MQE-241:[CAP] Add .env parameter support
- add logic for creating _ENV EntityDataObject - add logic for populating _ENV EntityDataObject with env var from .env file - change Action Object resolution so multiple params can be deind in url and userInput. - change Action Object resolution so url will resolve both Page and Env references. - remove explicit url reference appending from action object - support data inputs from types such as parameterArray
1 parent deb4bf1 commit 3980852

File tree

3 files changed

+162
-49
lines changed

3 files changed

+162
-49
lines changed

src/Magento/AcceptanceTestFramework/DataGenerator/Managers/DataManager.php

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,21 @@ class DataManager
1313
private $data = []; // an array of entity names to the entity data objects themselves
1414
private $arrayData;
1515
private static $dataManager;
16+
const ENV_DATA_OBJECT_NAME = '_ENV';
1617

18+
/**
19+
* Singleton method to access instance of DataManager.
20+
* @return DataManager
21+
* @throws Exception
22+
*/
1723
public static function getInstance()
1824
{
1925
if (!self::$dataManager) {
2026
$entityParser = ObjectManagerFactory::getObjectManager()->create(DataProfileSchemaParser::class);
2127
$entityParsedData = $entityParser->readDataProfiles();
2228

2329
if (!$entityParsedData) {
24-
throw new Exception(sprintf("No entities could be parsed from xml definitions"));
30+
throw new Exception("No entities could be parsed from xml definitions");
2531
}
2632

2733
self::$dataManager = new DataManager($entityParsedData);
@@ -30,14 +36,47 @@ public static function getInstance()
3036
return self::$dataManager;
3137
}
3238

39+
/**
40+
* DataManager constructor.
41+
* @param array $arrayData
42+
*/
3343
private function __construct($arrayData)
3444
{
3545
$this->arrayData = $arrayData;
3646
}
3747

48+
/**
49+
* Adds all .env variables defined in the PROJECT_ROOT as EntityDataObjects. This is to allow resolution
50+
* of these variables when referenced in a cest.
51+
*/
52+
private function parseEnvVariables()
53+
{
54+
$envFilename = PROJECT_ROOT . '/.env';
55+
56+
if (file_exists($envFilename)) {
57+
$envData = [];
58+
59+
$envFile = file($envFilename);
60+
61+
foreach ($envFile as $entry) {
62+
$params = explode("=", $entry);
63+
if (count($params) != 2) {
64+
continue;
65+
}
66+
$envData[strtolower(trim($params[0]))] = trim($params[1]);
67+
}
68+
69+
70+
$envDataObject = new EntityDataObject(self::ENV_DATA_OBJECT_NAME, 'environment', $envData, null);
71+
$this->data[$envDataObject->getName()] = $envDataObject;
72+
}
73+
}
74+
75+
/**
76+
* Parses data xml and extracts all information into EntityDataObject.
77+
*/
3878
private function parseDataEntities()
3979
{
40-
$entityObjects = array();
4180
$entities = $this->arrayData;
4281

4382
foreach ($entities[DataGeneratorConstants::ENTITY_DATA] as $entityName => $entity) {
@@ -85,24 +124,32 @@ private function parseDataEntities()
85124
$linkedEntities
86125
);
87126

88-
$entityObjects[$entityXmlObject->getName()] = $entityXmlObject;
127+
$this->data[$entityXmlObject->getName()] = $entityXmlObject;
89128

90129
}
91130
unset($entityName);
92131
unset($entity);
93-
94-
$this->data = $entityObjects;
95132
}
96133

134+
/**
135+
* Method returns a single data entity by name based on what is defined in data.xml.
136+
* @param $entityName
137+
* @return EntityDataObject
138+
*/
97139
public function getEntity($entityName)
98140
{
99141
return $this->getAllEntities()[$entityName];
100142
}
101143

144+
/**
145+
* Method returns all data entities read from data.xml into objects.
146+
* @return array
147+
*/
102148
public function getAllEntities()
103149
{
104150
if (!$this->data) {
105151
$this->parseDataEntities();
152+
$this->parseEnvVariables();
106153
}
107154

108155
return $this->data;

src/Magento/AcceptanceTestFramework/PageObject/Page/Page.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,15 @@ class Page implements PageInterface
2525
public static function getPage($pageName = null)
2626
{
2727
self::initPageObjects();
28-
return !$pageName ? self::$pageObjects : self::$pageObjects[$pageName];
28+
if (!$pageName) {
29+
return self::$pageObjects;
30+
}
31+
32+
if (array_key_exists($pageName, self::$pageObjects)) {
33+
return self::$pageObjects[$pageName];
34+
}
35+
36+
return null;
2937
}
3038

3139
/**

src/Magento/AcceptanceTestFramework/Test/Objects/ActionObject.php

Lines changed: 101 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@
88

99
class ActionObject
1010
{
11+
/**
12+
* @var string $mergeKey
13+
* @var string $type
14+
* @var array $actionAttributes
15+
* @var string $linkedAction
16+
* @var int $orderOffset
17+
* @var array $resolvedCustomAttributes
18+
* @var int timeout
19+
*/
1120
private $mergeKey;
1221
private $type;
1322
private $actionAttributes = [];
@@ -16,6 +25,16 @@ class ActionObject
1625
private $resolvedCustomAttributes = [];
1726
private $timeout;
1827

28+
const DATA_ENABLED_ATTRIBUTES = ["userInput", "parameterArray"];
29+
30+
/**
31+
* ActionObject constructor.
32+
* @param string $mergeKey
33+
* @param string $type
34+
* @param array $actionAttributes
35+
* @param string|null $linkedAction
36+
* @param int $order
37+
*/
1938
public function __construct($mergeKey, $type, $actionAttributes, $linkedAction = null, $order = 0)
2039
{
2140
$this->mergeKey = $mergeKey;
@@ -28,11 +47,19 @@ public function __construct($mergeKey, $type, $actionAttributes, $linkedAction =
2847
}
2948
}
3049

50+
/**
51+
* This function returns the string property mergeKey.
52+
* @return string
53+
*/
3154
public function getMergeKey()
3255
{
3356
return $this->mergeKey;
3457
}
3558

59+
/**
60+
* This function returns the string property type.
61+
* @return string
62+
*/
3663
public function getType()
3764
{
3865
return $this->type;
@@ -52,16 +79,29 @@ public function getCustomActionAttributes()
5279
return array_merge($this->actionAttributes, $this->resolvedCustomAttributes);
5380
}
5481

82+
/**
83+
* This function returns the string property linkedAction, describing a step to reference for a merge.
84+
* @return string
85+
*/
5586
public function getLinkedAction()
5687
{
5788
return $this->linkedAction;
5889
}
5990

91+
/**
92+
* This function returns the int property orderOffset, describing before or after for a merge.
93+
* @return int
94+
*/
6095
public function getOrderOffset()
6196
{
6297
return $this->orderOffset;
6398
}
6499

100+
/**
101+
* This function returns the int property timeout, this can be set as a result of the use of a section element
102+
* requiring a wait.
103+
* @return int
104+
*/
65105
public function getTimeout()
66106
{
67107
return $this->timeout;
@@ -81,7 +121,7 @@ public function resolveReferences()
81121
if (empty($this->resolvedCustomAttributes)) {
82122
$this->resolveSelectorReferenceAndTimeout();
83123
$this->resolveUrlReference();
84-
$this->resolveUserInputReference();
124+
$this->resolveDataInputReferences();
85125
}
86126
}
87127

@@ -100,9 +140,11 @@ private function resolveSelectorReferenceAndTimeout()
100140
}
101141
$selector = $this->actionAttributes['selector'];
102142

103-
$reference = $this->findReference($selector);
104-
if ($reference == null) {
105-
// Nothing to replace
143+
$reference = $this->findAllReferences($selector);
144+
if (count($reference) == 1) {
145+
$reference = $reference[0];
146+
} else {
147+
// Selectors can only handle a single var reference
106148
return;
107149
}
108150

@@ -112,8 +154,13 @@ private function resolveSelectorReferenceAndTimeout()
112154
// Bad section reference
113155
return;
114156
}
157+
115158
$replacement = Section::getElementLocator($sectionName, $elementName);
116159

160+
if ($replacement == null) {
161+
// Bad section reference
162+
return;
163+
}
117164
$this->resolvedCustomAttributes['selector'] = str_replace($reference, $replacement, $selector);
118165
$this->timeout = Section::getElementTimeOut($sectionName, $elementName);
119166
}
@@ -133,59 +180,70 @@ private function resolveUrlReference()
133180
}
134181
$url = $this->actionAttributes['url'];
135182

136-
$reference = $this->findReference($url);
137-
if ($reference == null) {
138-
// Nothing to replace
139-
return;
140-
}
183+
foreach ($this->findAllReferences($url) as $reference) {
184+
$replacement = null;
141185

142-
list($pageName) = $this->stripAndSplitReference($reference);
143-
$page = Page::getPage($pageName);
144-
if ($page == null) {
145-
// Bad page reference
146-
return;
186+
// assume this is a page
187+
list($pageName) = $this->stripAndSplitReference($reference);
188+
$page = Page::getPage($pageName);
189+
190+
if ($page != null) {
191+
$replacement = Page::getPageUrl($pageName);
192+
} else {
193+
// try to resolve as data
194+
list($entityName, $entityField) = $this->stripAndSplitReference($reference);
195+
$replacement = DataManager::getInstance()->getEntity($entityName)->getDataByName($entityField);
196+
}
197+
198+
if ($replacement == null) {
199+
continue;
200+
// Bad var ref
201+
}
202+
$url = str_replace($reference, $replacement, $url);
147203
}
148-
$replacement = $_ENV['MAGENTO_BASE_URL'] . Page::getPageUrl($pageName);
149204

150-
$this->resolvedCustomAttributes['url'] = str_replace($reference, $replacement, $url);
205+
$this->resolvedCustomAttributes['url'] = $url;
151206
}
152207

153-
154208
/**
155-
* Look up the value for EntityDataObjectName.Key and set it as the userInput attribute in the resolved custom
209+
* Look up the value for EntityDataObjectName.Key and set it as the corresponding attribute in the resolved custom
156210
* attributes.
157211
*
158212
* e.g. {{CustomerEntityFoo.FirstName}} becomes Jerry
159213
*
160214
* @return void
161215
*/
162-
private function resolveUserInputReference()
216+
private function resolveDataInputReferences()
163217
{
164-
if (!array_key_exists('userInput', $this->actionAttributes)) {
165-
return;
166-
}
167-
$userInput = $this->actionAttributes['userInput'];
218+
$actionAttributeKeys = array_keys($this->actionAttributes);
219+
$relevantDataAttributes = array_intersect($actionAttributeKeys, ActionObject::DATA_ENABLED_ATTRIBUTES);
168220

169-
$reference = $this->findReference($userInput);
170-
if ($reference == null) {
171-
// Nothing to replace
221+
if (empty($relevantDataAttributes)) {
172222
return;
173223
}
174224

175-
list($entityName, $entityKey) = $this->stripAndSplitReference($userInput);
176-
$entityObj = DataManager::getInstance()->getEntity($entityName);
177-
if ($entityObj == null) {
178-
// Bad entity reference
179-
return;
180-
}
225+
foreach ($relevantDataAttributes as $dataAttribute) {
226+
$varInput = $this->actionAttributes[$dataAttribute];
181227

182-
$replacement = $entityObj->getDataByName($entityKey);
183-
if ($replacement == null) {
184-
// Bad entity.key reference
185-
return;
186-
}
228+
foreach ($this->findAllReferences($varInput) as $reference) {
229+
list($entityName, $entityKey) = $this->stripAndSplitReference($reference);
230+
$entityObj = DataManager::getInstance()->getEntity($entityName);
231+
if ($entityObj == null) {
232+
// Bad entity reference
233+
continue;
234+
}
187235

188-
$this->resolvedCustomAttributes['userInput'] = str_replace($reference, $replacement, $userInput);
236+
$replacement = $entityObj->getDataByName($entityKey) ?? null;
237+
if ($replacement == null) {
238+
// Bad entity.key reference
239+
return;
240+
}
241+
242+
$varInput = str_replace($reference, $replacement, $varInput);
243+
}
244+
245+
$this->resolvedCustomAttributes[$dataAttribute] = $varInput;
246+
}
189247
}
190248

191249
/**
@@ -201,16 +259,16 @@ private function stripAndSplitReference($reference)
201259
}
202260

203261
/**
204-
* Return a {{reference.foo}} if it exists in the string.
262+
* Return an array of {{reference.foo}} if any exist in the string, otherwise returns an empty array.
205263
*
206264
* @param string $str
207-
* @return string|null
265+
* @return array
208266
*/
209-
private function findReference($str)
267+
private function findAllReferences($str)
210268
{
211-
preg_match('/{{[\w.]+}}/', $str, $matches);
269+
preg_match_all('/{{[\w.]+}}/', $str, $matches);
212270
if (empty($matches)) {
213-
return null;
271+
return [];
214272
} else {
215273
return $matches[0];
216274
}

0 commit comments

Comments
 (0)