Skip to content

Commit 352d35f

Browse files
authored
Merge pull request #394 from magento-commerce/MFTF4.7.2-Release
MFTF4.7.2 : Release
2 parents 036c0db + 0fdedc8 commit 352d35f

File tree

8 files changed

+243
-6
lines changed

8 files changed

+243
-6
lines changed

Diff for: CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
Magento Functional Testing Framework Changelog
22
================================================
33

4+
4.7.2
5+
---------
6+
### Enhancements
7+
* Fail static test when introduced filename does not equal the MFTF object name
8+
contained within.
9+
410
4.7.1
511
---------
612
### Enhancements

Diff for: composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "magento/magento2-functional-testing-framework",
33
"description": "Magento2 Functional Testing Framework",
44
"type": "library",
5-
"version": "4.7.1",
5+
"version": "4.7.2",
66
"license": "AGPL-3.0",
77
"keywords": ["magento", "automation", "functional", "testing"],
88
"config": {

Diff for: composer.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace tests\unit\Magento\FunctionalTestFramework\Util;
9+
10+
use tests\unit\Util\MagentoTestCase;
11+
use Magento\FunctionalTestingFramework\StaticCheck\ClassFileNamingCheck;
12+
use Magento\FunctionalTestingFramework\Util\Script\ScriptUtil;
13+
14+
class ClassFileNameCheckTest extends MagentoTestCase
15+
{
16+
/**
17+
* This Test checks if the file name is renamed to match the class name if mismatch found in class and file name
18+
*/
19+
public function testClassAndFileMismatchStaticCheckWhenViolationsFound()
20+
{
21+
$scriptUtil = new ScriptUtil();
22+
$modulePaths = $scriptUtil->getAllModulePaths();
23+
$testXmlFiles = $scriptUtil->getModuleXmlFilesByScope($modulePaths, "Test");
24+
$classFileNameCheck = new ClassFileNamingCheck();
25+
$result = $classFileNameCheck->findErrorsInFileSet($testXmlFiles, "test");
26+
$this->assertMatchesRegularExpression('/does not match with file name/', $result[array_keys($result)[0]][0]);
27+
}
28+
29+
/**
30+
* This Test checks if the file name is renamed to match the class name if
31+
* mismatch not found in class and file name
32+
*/
33+
public function testClassAndFileMismatchStaticCheckWhenViolationsNotFound()
34+
{
35+
$scriptUtil = new ScriptUtil();
36+
$modulePaths = $scriptUtil->getAllModulePaths();
37+
$testXmlFiles = $scriptUtil->getModuleXmlFilesByScope($modulePaths, "Page");
38+
$classFileNameCheck = new ClassFileNamingCheck();
39+
$result = $classFileNameCheck->findErrorsInFileSet($testXmlFiles, "page");
40+
$this->assertEquals(count($result), 0);
41+
}
42+
}

Diff for: src/Magento/FunctionalTestingFramework/Console/StaticChecksCommand.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
117117

118118
$staticOutput = $staticCheck->getOutput();
119119
LoggingUtil::getInstance()->getLogger(get_class($staticCheck))->info($staticOutput);
120-
$this->ioStyle->text($staticOutput);
120+
$this->ioStyle->text($staticOutput??"");
121121

122122
$this->ioStyle->text('Total execution time is ' . (string)($end - $start) . ' seconds.' . PHP_EOL);
123123
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\FunctionalTestingFramework\StaticCheck;
8+
9+
use Symfony\Component\Console\Input\InputInterface;
10+
use Exception;
11+
use Magento\FunctionalTestingFramework\Util\Script\ScriptUtil;
12+
use Symfony\Component\Finder\SplFileInfo;
13+
14+
/**
15+
* Class ClassFileNamingCheck
16+
* @package Magento\FunctionalTestingFramework\StaticCheck
17+
*/
18+
class ClassFileNamingCheck implements StaticCheckInterface
19+
{
20+
const ERROR_LOG_FILENAME = 'mftf-class-file-naming-check';
21+
const ERROR_LOG_MESSAGE = 'MFTF Class File Naming Check';
22+
const ALLOW_LIST_FILENAME = 'class-file-naming-allowlist';
23+
const WARNING_LOG_FILENAME = 'mftf-class-file-naming-warnings';
24+
25+
/**
26+
* Array containing all warnings found after running the execute() function.
27+
* @var array
28+
*/
29+
private $warnings = [];
30+
/**
31+
* Array containing all errors found after running the execute() function.
32+
* @var array
33+
*/
34+
private $errors = [];
35+
36+
/**
37+
* String representing the output summary found after running the execute() function.
38+
* @var string
39+
*/
40+
private $output;
41+
42+
/**
43+
* @var array $allowFailureEntities
44+
*/
45+
private $allowFailureEntities = [];
46+
47+
/**
48+
* ScriptUtil instance
49+
*
50+
* @var ScriptUtil
51+
*/
52+
private $scriptUtil;
53+
/**
54+
* Checks usage of pause action in action groups, tests and suites and prints out error to file.
55+
*
56+
* @param InputInterface $input
57+
* @return void
58+
* @throws Exception
59+
*/
60+
public function execute(InputInterface $input)
61+
{
62+
$this->scriptUtil = new ScriptUtil();
63+
$modulePaths = [];
64+
$path = $input->getOption('path');
65+
if ($path) {
66+
if (!realpath($path)) {
67+
throw new \InvalidArgumentException('Invalid --path option: ' . $path);
68+
}
69+
$modulePaths[] = realpath($path);
70+
} else {
71+
$modulePaths = $this->scriptUtil->getAllModulePaths();
72+
}
73+
foreach ($modulePaths as $modulePath) {
74+
if (file_exists($modulePath . DIRECTORY_SEPARATOR . self::ALLOW_LIST_FILENAME)) {
75+
$contents = file_get_contents($modulePath . DIRECTORY_SEPARATOR . self::ALLOW_LIST_FILENAME);
76+
foreach (explode("\n", $contents) as $entity) {
77+
$this->allowFailureEntities[$entity] = true;
78+
}
79+
}
80+
}
81+
$testXmlFiles = $this->scriptUtil->getModuleXmlFilesByScope($modulePaths, "Test");
82+
$actionGroupXmlFiles = $this->scriptUtil->getModuleXmlFilesByScope($modulePaths, "ActionGroup");
83+
$pageXmlFiles = $this->scriptUtil->getModuleXmlFilesByScope($modulePaths, "Page");
84+
$sectionXmlFiles = $this->scriptUtil->getModuleXmlFilesByScope($modulePaths, "Section");
85+
$suiteXmlFiles = $this->scriptUtil->getModuleXmlFilesByScope($modulePaths, 'Suite');
86+
$this->errors = [];
87+
$this->errors += $this->findErrorsInFileSet($testXmlFiles, 'test');
88+
$this->errors += $this->findErrorsInFileSet($actionGroupXmlFiles, 'actionGroup');
89+
$this->errors += $this->findErrorsInFileSet($pageXmlFiles, 'page');
90+
$this->errors += $this->findErrorsInFileSet($sectionXmlFiles, 'section');
91+
$this->errors += $this->findErrorsInFileSet($suiteXmlFiles, 'suite');
92+
93+
// hold on to the output and print any errors to a file
94+
$this->output = $this->scriptUtil->printErrorsToFile(
95+
$this->errors,
96+
StaticChecksList::getErrorFilesPath() . DIRECTORY_SEPARATOR . self::ERROR_LOG_FILENAME . '.txt',
97+
self::ERROR_LOG_MESSAGE
98+
);
99+
if (!empty($this->warnings)) {
100+
$this->output .= "\n " . $this->scriptUtil->printWarningsToFile(
101+
$this->warnings,
102+
StaticChecksList::getErrorFilesPath() . DIRECTORY_SEPARATOR . self::WARNING_LOG_FILENAME . '.txt',
103+
self::ERROR_LOG_MESSAGE
104+
);
105+
}
106+
}
107+
108+
/**
109+
* Return array containing all errors found after running the execute() function.
110+
* @return array
111+
*/
112+
public function getErrors()
113+
{
114+
return $this->errors;
115+
}
116+
117+
/**
118+
* Return string of a short human readable result of the check. For example: "No errors found."
119+
* @return string
120+
*/
121+
public function getOutput()
122+
{
123+
return $this->output;
124+
}
125+
126+
/**
127+
* Returns Violations if found
128+
* @param SplFileInfo $files
129+
* @param string $fileType
130+
* @return array
131+
*/
132+
public function findErrorsInFileSet($files, $fileType)
133+
{
134+
$errors = [];
135+
/** @var SplFileInfo $filePath */
136+
137+
foreach ($files as $filePath) {
138+
$fileNameWithoutExtension = pathinfo($filePath->getFilename(), PATHINFO_FILENAME);
139+
$domDocument = new \DOMDocument();
140+
$domDocument->load($filePath);
141+
$testResult = $this->getAttributesFromDOMNodeList(
142+
$domDocument->getElementsByTagName($fileType),
143+
["type" => 'name']
144+
);
145+
if ($fileNameWithoutExtension != array_values($testResult[0])[0]) {
146+
$isInAllowList = array_key_exists(array_values($testResult[0])[0], $this->allowFailureEntities);
147+
if ($isInAllowList) {
148+
$errorOutput = ucfirst($fileType). " name does not match with file name
149+
{$filePath->getRealPath()}. ".ucfirst($fileType)." ".array_values($testResult[0])[0];
150+
$this->warnings[$filePath->getFilename()][] = $errorOutput;
151+
continue;
152+
}
153+
$errorOutput = ucfirst($fileType). " name does not match with file name
154+
{$filePath->getRealPath()}. ".ucfirst($fileType)." ".array_values($testResult[0])[0];
155+
$errors[$filePath->getFilename()][] = $errorOutput;
156+
}
157+
}
158+
return $errors;
159+
}
160+
161+
/**
162+
* Return attribute value for each node in DOMNodeList as an array
163+
*
164+
* @param DOMNodeList $nodes
165+
* @param string $attributeName
166+
* @return array
167+
*/
168+
public function getAttributesFromDOMNodeList($nodes, $attributeName)
169+
{
170+
$attributes = [];
171+
foreach ($nodes as $node) {
172+
if (is_string($attributeName)) {
173+
$attributeValue = $node->getAttribute($attributeName);
174+
} else {
175+
$attributeValue = [$node->getAttribute(key($attributeName)) =>
176+
$node->getAttribute($attributeName[key($attributeName)])];
177+
}
178+
if (!empty($attributeValue)) {
179+
$attributes[] = $attributeValue;
180+
}
181+
}
182+
return $attributes;
183+
}
184+
}

Diff for: src/Magento/FunctionalTestingFramework/StaticCheck/StaticChecksList.php

+7-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ class StaticChecksList implements StaticCheckListInterface
2020
const PAUSE_ACTION_USAGE_CHECK_NAME = 'pauseActionUsage';
2121
const CREATED_DATA_FROM_OUTSIDE_ACTIONGROUP = 'createdDataFromOutsideActionGroup';
2222
const UNUSED_ENTITY_CHECK = 'unusedEntityCheck';
23+
24+
const CLASS_FILE_NAMING_CHECK = 'classFileNamingCheck';
25+
2326
const STATIC_RESULTS = 'tests' . DIRECTORY_SEPARATOR .'_output' . DIRECTORY_SEPARATOR . 'static-results';
2427

2528
/**
@@ -51,8 +54,10 @@ public function __construct(array $checks = [])
5154
'annotations' => new AnnotationsCheck(),
5255
self::PAUSE_ACTION_USAGE_CHECK_NAME => new PauseActionUsageCheck(),
5356
self::UNUSED_ENTITY_CHECK => new UnusedEntityCheck(),
54-
self::CREATED_DATA_FROM_OUTSIDE_ACTIONGROUP => new CreatedDataFromOutsideActionGroupCheck(),
55-
] + $checks;
57+
self::CREATED_DATA_FROM_OUTSIDE_ACTIONGROUP => new CreatedDataFromOutsideActionGroupCheck(),
58+
self::CLASS_FILE_NAMING_CHECK => new ClassFileNamingCheck(),
59+
60+
] + $checks;
5661

5762
// Static checks error files directory
5863
if (null === self::$errorFilesPath) {

Diff for: src/Magento/FunctionalTestingFramework/StaticCheck/TestDependencyCheck.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ public function getErrors(): array
179179
*/
180180
public function getOutput(): string
181181
{
182-
return $this->output;
182+
return $this->output??"";
183183
}
184184

185185
/**

0 commit comments

Comments
 (0)