Skip to content

Commit 3f79812

Browse files
committed
MQE-809: Throw a warning or error when step key referencing in merges is invalid or ambiguous
- add Application Config for static ref
1 parent 9a0bb13 commit 3f79812

File tree

8 files changed

+196
-43
lines changed

8 files changed

+196
-43
lines changed

RoboFile.php

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ function generateTests(array $tests, $opts = ['config' => null, 'force' => true,
4949
{
5050
require 'dev' . DIRECTORY_SEPARATOR . 'tests'. DIRECTORY_SEPARATOR . 'functional' . DIRECTORY_SEPARATOR . '_bootstrap.php';
5151
$GLOBALS['GENERATE_TESTS'] = true;
52+
5253
if (!$this->isProjectBuilt()) {
5354
$this->say("<info>Please run bin/mftf build:project and configure your environment (.env) first.</info>");
5455
exit(\Robo\Result::EXITCODE_ERROR);

dev/tests/_bootstrap.php

+6-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@
1616
'includePaths' => [PROJECT_ROOT . '/src']
1717
]);
1818

19-
// force php to generate
20-
$GLOBALS['FORCE_PHP_GENERATE'] = true;
19+
// set mftf appplication context
20+
\Magento\FunctionalTestingFramework\Config\MftfApplicationConfig::create(
21+
true,
22+
\Magento\FunctionalTestingFramework\Config\MftfApplicationConfig::GENERATION_PHASE,
23+
true
24+
);
2125

2226
// Load needed framework env params
2327
$TEST_ENVS = [

dev/tests/unit/Magento/FunctionalTestFramework/Test/Util/ActionObjectExtractorTest.php

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
<?php
22
/**
3-
* Created by PhpStorm.
4-
* User: imeron
5-
* Date: 4/10/18
6-
* Time: 11:39 AM
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
75
*/
8-
96
namespace tests\unit\Magento\FunctionalTestFramework\Test\Util;
107

118
use Magento\FunctionalTestingFramework\Test\Objects\ActionObject;
@@ -106,4 +103,4 @@ private function createBasicActionObjectArray($stepKey = 'testAction1', $before
106103

107104
return $baseArray;
108105
}
109-
}
106+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\FunctionalTestingFramework\Config;
7+
8+
use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException;
9+
10+
class MftfApplicationConfig
11+
{
12+
const GENERATION_PHASE = "generation";
13+
const EXECUTION_PHASE = "execution";
14+
const MFTF_PHASES = [self::GENERATION_PHASE, self::EXECUTION_PHASE];
15+
16+
/**
17+
* Determines whether the user has specified a force option for generation
18+
*
19+
* @var bool
20+
*/
21+
private $forceGenerate;
22+
23+
/**
24+
* String which identifies the current phase of mftf execution
25+
*
26+
* @var string
27+
*/
28+
private $phase;
29+
30+
/**
31+
* Determines whether the user would like to execute mftf in a verbose run.
32+
*
33+
* @var bool
34+
*/
35+
private $verboseEnabled;
36+
37+
/**
38+
* MftfApplicationConfig Singelton Instance
39+
*
40+
* @var MftfApplicationConfig
41+
*/
42+
private static $MFTF_APPLICATION_CONTEXT;
43+
44+
/**
45+
* MftfApplicationConfig constructor.
46+
*
47+
* @param bool $forceGenerate
48+
* @param string $phase
49+
* @param bool $verboseEnabled
50+
* @throws TestFrameworkException
51+
*/
52+
private function __construct($forceGenerate = false, $phase = self::EXECUTION_PHASE, $verboseEnabled = null)
53+
{
54+
$this->forceGenerate = $forceGenerate;
55+
56+
if (!in_array($phase, self::MFTF_PHASES)) {
57+
throw new TestFrameworkException("{$phase} is not an mftf phase");
58+
}
59+
60+
$this->phase = $phase;
61+
$this->verboseEnabled = $verboseEnabled;
62+
}
63+
64+
/**
65+
* Creates an instance of the configuration instance for reference once application has started. This function
66+
* returns void and is only run once during the lifetime of the application.
67+
*
68+
* @param bool $forceGenerate
69+
* @param string $phase
70+
* @param bool $verboseEnabled
71+
* @return void
72+
*/
73+
public static function create($forceGenerate, $phase, $verboseEnabled)
74+
{
75+
if (self::$MFTF_APPLICATION_CONTEXT == null) {
76+
self::$MFTF_APPLICATION_CONTEXT = new MftfApplicationConfig($forceGenerate, $phase, $verboseEnabled);
77+
}
78+
}
79+
80+
/**
81+
* This function returns an instance of the MftfApplicationConfig which is created once the application starts.
82+
*
83+
* @return MftfApplicationConfig
84+
*/
85+
public static function getConfig()
86+
{
87+
// TODO explicitly set this with AcceptanceTester or MagentoWebDriver
88+
// during execution we cannot guarantee the use of the robofile so we return the default application config,
89+
// we don't want to set the application context in case the user explicitly does so at a later time.
90+
if (self::$MFTF_APPLICATION_CONTEXT == null) {
91+
return new MftfApplicationConfig();
92+
}
93+
94+
return self::$MFTF_APPLICATION_CONTEXT;
95+
}
96+
97+
/**
98+
* Returns a booelan indiciating whether or not the user has indicated a forced generation.
99+
*
100+
* @return bool
101+
*/
102+
public function forceGenerateEnabled()
103+
{
104+
return $this->forceGenerate;
105+
}
106+
107+
/**
108+
* Returns a boolean indicating whether the user has indicated a verbose run, which will cause all applicable
109+
* text to print to the console.
110+
*
111+
* @return bool
112+
*/
113+
public function verboseEnabled()
114+
{
115+
return $this->verboseEnabled ?? getenv('MFTF_DEBUG');
116+
}
117+
118+
/**
119+
* Returns a string which indicates the phase of mftf execution.
120+
*
121+
* @return string
122+
*/
123+
public function getPhase()
124+
{
125+
return $this->phase;
126+
}
127+
}

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
namespace Magento\FunctionalTestingFramework\Test\Objects;
77

8+
use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig;
89
use Magento\FunctionalTestingFramework\DataGenerator\Handlers\DataObjectHandler;
910
use Magento\FunctionalTestingFramework\DataGenerator\Objects\EntityDataObject;
1011
use Magento\FunctionalTestingFramework\Exceptions\XmlException;
@@ -264,7 +265,8 @@ public function trimAssertionAttributes()
264265
$oldAttributes = array_intersect($actionAttributeKeys, ActionObject::OLD_ASSERTION_ATTRIBUTES);
265266
if (!empty($oldAttributes)) {
266267
// @codingStandardsIgnoreStart
267-
if ($GLOBALS['GENERATE_TESTS'] ?? false == true) {
268+
$appConfig = MftfApplicationConfig::getConfig();
269+
if ($appConfig->getPhase() == MftfApplicationConfig::GENERATION_PHASE && $appConfig->verboseEnabled()) {
268270
echo("WARNING: Use of one line Assertion actions will be deprecated in MFTF 3.0.0, please use nested syntax (Action: {$this->type} StepKey: {$this->stepKey})" . PHP_EOL);
269271
}
270272
// @codingStandardsIgnoreEnd

src/Magento/FunctionalTestingFramework/Test/Util/ActionObjectExtractor.php

+42-22
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Magento\FunctionalTestingFramework\Test\Util;
88

9+
use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig;
910
use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException;
1011
use Magento\FunctionalTestingFramework\Exceptions\TestReferenceException;
1112
use Magento\FunctionalTestingFramework\Exceptions\XmlException;
@@ -65,8 +66,6 @@ public function extractActions($testActions, $testName = null)
6566
self::TEST_STEP_MERGE_KEY,
6667
self::NODE_NAME
6768
);
68-
$linkedAction = null;
69-
$order = null;
7069

7170
// Flatten AssertSorted "array" element to parameterArray
7271
if (isset($actionData["array"])) {
@@ -77,24 +76,12 @@ public function extractActions($testActions, $testName = null)
7776
$actionAttributes = $this->processActionGroupArgs($actionAttributes);
7877
}
7978

80-
if (array_key_exists(self::TEST_ACTION_BEFORE, $actionData)
81-
and array_key_exists(self::TEST_ACTION_AFTER, $actionData)) {
82-
throw new XmlException(sprintf(self::BEFORE_AFTER_ERROR_MSG, $actionName));
83-
}
84-
85-
if (array_key_exists(self::TEST_ACTION_BEFORE, $actionData)) {
86-
$linkedAction = $actionData[self::TEST_ACTION_BEFORE];
87-
$order = self::TEST_ACTION_BEFORE;
88-
} elseif (array_key_exists(self::TEST_ACTION_AFTER, $actionData)) {
89-
$linkedAction = $actionData[self::TEST_ACTION_AFTER];
90-
$order = self::TEST_ACTION_AFTER;
91-
}
92-
79+
$linkedAction = $this->processLinkedActions($actionName, $actionData);
9380
$actions = $this->extractFieldActions($actionData, $actions);
9481
$actionAttributes = $this->extractFieldReferences($actionData, $actionAttributes);
9582

96-
if ($linkedAction != null) {
97-
$stepKeyRefs[$linkedAction][] = $stepKey;
83+
if ($linkedAction['stepKey'] != null) {
84+
$stepKeyRefs[$linkedAction['stepKey']][] = $stepKey;
9885
}
9986

10087
// TODO this is to be implemented later. Currently the schema does not use or need return var.
@@ -106,8 +93,8 @@ public function extractActions($testActions, $testName = null)
10693
$stepKey,
10794
$actionData[self::NODE_NAME],
10895
$actionAttributes,
109-
$linkedAction,
110-
$order
96+
$linkedAction['stepKey'],
97+
$linkedAction['order']
11198
);
11299
}
113100

@@ -116,6 +103,34 @@ public function extractActions($testActions, $testName = null)
116103
return $actions;
117104
}
118105

106+
/**
107+
* Function which processes any actions which have an explicit reference to an additional step for merging purposes.
108+
* Returns an array with keys corresponding to the linked action's stepKey and order.
109+
*
110+
* @param string $actionName
111+
* @param array $actionData
112+
* @return array
113+
* @throws XmlException
114+
*/
115+
private function processLinkedActions($actionName, $actionData)
116+
{
117+
$linkedAction =['stepKey' => null, 'order' => null];
118+
if (array_key_exists(self::TEST_ACTION_BEFORE, $actionData)
119+
and array_key_exists(self::TEST_ACTION_AFTER, $actionData)) {
120+
throw new XmlException(sprintf(self::BEFORE_AFTER_ERROR_MSG, $actionName));
121+
}
122+
123+
if (array_key_exists(self::TEST_ACTION_BEFORE, $actionData)) {
124+
$linkedAction['stepKey'] = $actionData[self::TEST_ACTION_BEFORE];
125+
$linkedAction['order'] = self::TEST_ACTION_BEFORE;
126+
} elseif (array_key_exists(self::TEST_ACTION_AFTER, $actionData)) {
127+
$linkedAction['stepKey'] = $actionData[self::TEST_ACTION_AFTER];
128+
$linkedAction['order'] = self::TEST_ACTION_AFTER;
129+
}
130+
131+
return $linkedAction;
132+
}
133+
119134
/**
120135
* Takes the action group reference and parses out arguments as an array that can be passed to override defaults
121136
* defined in the action group xml.
@@ -238,11 +253,16 @@ private function auditMergeSteps($stepKeyRefs, $testName)
238253
return count($value) > 1;
239254
});
240255

256+
$multipleActionsError = "";
241257
foreach ($atRiskStepRef as $stepKey => $stepRefs) {
242-
print "multiple actions referencing step key {$stepKey} in test {$testName}:\n";
243-
array_walk($stepRefs, function ($value) {
244-
print "\t{$value}\n";
258+
$multipleActionsError.= "multiple actions referencing step key {$stepKey} in test {$testName}:\n";
259+
array_walk($stepRefs, function ($value) use (&$multipleActionsError) {
260+
$multipleActionsError.= "\t{$value}\n";
245261
});
246262
}
263+
264+
if (MftfApplicationConfig::getConfig()->verboseEnabled()) {
265+
print $multipleActionsError;
266+
}
247267
}
248268
}

src/Magento/FunctionalTestingFramework/Util/ConfigSanitizerUtil.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
namespace Magento\FunctionalTestingFramework\Util;
88

9+
use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig;
10+
911
/**
1012
* Class ConfigSanitizerUtil
1113
*/
@@ -86,8 +88,7 @@ private static function validateConfigBasedVars($config)
8688
*/
8789
public static function sanitizeUrl($url)
8890
{
89-
$forceGenerate = $GLOBALS['FORCE_PHP_GENERATE'] ?? false;
90-
if (strlen($url) == 0 && $forceGenerate === false) {
91+
if (strlen($url) == 0 && !MftfApplicationConfig::getConfig()->forceGenerateEnabled()) {
9192
trigger_error("MAGENTO_BASE_URL must be defined in .env", E_USER_ERROR);
9293
}
9394

src/Magento/FunctionalTestingFramework/Util/ModuleResolver.php

+11-10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
namespace Magento\FunctionalTestingFramework\Util;
88

9+
use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig;
10+
911
/**
1012
* Class ModuleResolver, resolve module path based on enabled modules of target Magento instance.
1113
*
@@ -126,13 +128,11 @@ private function __construct()
126128
*/
127129
public function getEnabledModules()
128130
{
129-
$testGenerationPhase = $GLOBALS['GENERATE_TESTS'] ?? false;
130-
131131
if (isset($this->enabledModules)) {
132132
return $this->enabledModules;
133133
}
134134

135-
if ($testGenerationPhase) {
135+
if (MftfApplicationConfig::getConfig()->getPhase() == MftfApplicationConfig::GENERATION_PHASE) {
136136
$this->printMagentoVersionInfo();
137137
}
138138

@@ -190,9 +190,7 @@ public function getModulesPath()
190190
}
191191

192192
$enabledModules = $this->getEnabledModules();
193-
$forceGeneration = $GLOBALS['FORCE_PHP_GENERATE'] ?? false;
194-
195-
if (empty($enabledModules) && !$forceGeneration) {
193+
if (empty($enabledModules) && !MftfApplicationConfig::getConfig()->forceGenerateEnabled()) {
196194
trigger_error(
197195
"Could not retrieve enabled modules from provided 'MAGENTO_BASE_URL'," .
198196
"please make sure Magento is available at this url",
@@ -321,12 +319,13 @@ private function getEnabledDirectoryPaths($enabledModules, $allModulePaths)
321319
*/
322320
private function printMagentoVersionInfo()
323321
{
324-
$forceGeneration = $GLOBALS['FORCE_PHP_GENERATE'] ?? false;
325-
if ($forceGeneration) {
322+
323+
if (MftfApplicationConfig::getConfig()->forceGenerateEnabled()) {
326324
return;
327325
}
328326
$url = ConfigSanitizerUtil::sanitizeUrl(getenv('MAGENTO_BASE_URL')) . $this->versionUrl;
329-
print "Fetching version information from {$url}";
327+
print "Fetching version information from {$url}\n";
328+
330329
$ch = curl_init($url);
331330
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
332331
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
@@ -336,7 +335,9 @@ private function printMagentoVersionInfo()
336335
$response = "No version information available.";
337336
}
338337

339-
print "\nVersion Information: {$response}\n";
338+
if (MftfApplicationConfig::getConfig()->verboseEnabled()) {
339+
print "\nVersion Information: {$response}\n";
340+
}
340341
}
341342

342343
/**

0 commit comments

Comments
 (0)