diff --git a/dev/tests/functional/standalone_bootstrap.php b/dev/tests/functional/standalone_bootstrap.php index 34516236e..58030231d 100755 --- a/dev/tests/functional/standalone_bootstrap.php +++ b/dev/tests/functional/standalone_bootstrap.php @@ -53,6 +53,9 @@ defined('WAIT_TIMEOUT') || define('WAIT_TIMEOUT', 30); $env->setEnvironmentVariable('WAIT_TIMEOUT', WAIT_TIMEOUT); + defined('VERBOSE_ARTIFACTS') || define('VERBOSE_ARTIFACTS', false); + $env->setEnvironmentVariable('VERBOSE_ARTIFACTS', VERBOSE_ARTIFACTS); + try { new DateTimeZone(DEFAULT_TIMEZONE); } catch (\Exception $e) { diff --git a/docs/configuration.md b/docs/configuration.md index 9466f2bcc..11882084e 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -299,6 +299,20 @@ Example: CREDENTIAL_AWS_SECRETS_MANAGER_PROFILE=default ``` +### VERBOSE_ARTIFACTS + +Determines if passed tests should still have all their Allure artifacts. These artifacts include `.txt` attachments for things like `dontSee` actions and `createData` actions. + +If enabled, all tests will have all of their normal Allure artifacts. + +If disabled, passed tests will have their Allure artifacts trimmed. Failed tests will still contain all their artifacts. + +This is set `false` by default. + +```conf +VERBOSE_ARTIFACTS=true +``` + ### ENABLE_BROWSER_LOG Enables addition of browser logs to Allure steps diff --git a/etc/config/.env.example b/etc/config/.env.example index 349d7da9c..86df31b3d 100644 --- a/etc/config/.env.example +++ b/etc/config/.env.example @@ -59,6 +59,9 @@ MODULE_WHITELIST=Magento_Framework,ConfigurableProductWishlist,ConfigurableProdu #*** Default timeout for wait actions #WAIT_TIMEOUT=30 +#*** Uncomment and set to enable all tests, regardless of passing status, to have all their Allure artifacts. +#VERBOSE_ARTIFACTS=true + #*** Uncomment and set to enable browser log entries on actions in Allure. Blacklist is used to filter logs of a specific "source" #ENABLE_BROWSER_LOG=true #BROWSER_LOG_BLACKLIST=other diff --git a/src/Magento/FunctionalTestingFramework/Allure/Adapter/MagentoAllureAdapter.php b/src/Magento/FunctionalTestingFramework/Allure/Adapter/MagentoAllureAdapter.php index e9e1c344c..bc0d0a91c 100644 --- a/src/Magento/FunctionalTestingFramework/Allure/Adapter/MagentoAllureAdapter.php +++ b/src/Magento/FunctionalTestingFramework/Allure/Adapter/MagentoAllureAdapter.php @@ -10,6 +10,8 @@ use Magento\FunctionalTestingFramework\Test\Objects\ActionGroupObject; use Magento\FunctionalTestingFramework\Test\Objects\ActionObject; use Magento\FunctionalTestingFramework\Util\TestGenerator; +use Yandex\Allure\Adapter\Model\Failure; +use Yandex\Allure\Adapter\Model\Provider; use Yandex\Allure\Adapter\Model\Status; use Yandex\Allure\Adapter\Model\Step; use Yandex\Allure\Codeception\AllureCodeception; @@ -250,6 +252,8 @@ public function testError(FailEvent $failEvent) */ public function testEnd() { + // Peek top of testCaseStorage to check of failure + $testFailed = $this->getLifecycle()->getTestCaseStorage()->get()->getFailure(); // Pops top of stepStorage, need to add it back in after processing $rootStep = $this->getLifecycle()->getStepStorage()->pollLast(); $formattedSteps = []; @@ -257,6 +261,7 @@ public function testEnd() $actionGroupStepKey = null; foreach ($rootStep->getSteps() as $step) { + $this->removeAttachments($step, $testFailed); $stepKey = str_replace($actionGroupStepKey, '', $step->getName()); if ($stepKey !== '[]' && $stepKey !== null) { $step->setName($stepKey); @@ -354,4 +359,21 @@ private function retrieveStepKey($stepLine) return $stepKey; } + + /** + * Removes attachments from step depending on MFTF configuration + * @param Step $step + * @param Failure $testFailed + * @return void + */ + private function removeAttachments($step, $testFailed) + { + //Remove Attachments if verbose flag is not true AND test did not fail + if (getenv('VERBOSE_ARTIFACTS') !== true && $testFailed === null) { + foreach ($step->getAttachments() as $index => $attachment) { + $step->removeAttachment($index); + unlink(Provider::getOutputDirectory() . DIRECTORY_SEPARATOR . $attachment->getSource()); + } + } + } } diff --git a/src/Magento/FunctionalTestingFramework/Console/GenerateDevUrnCommand.php b/src/Magento/FunctionalTestingFramework/Console/GenerateDevUrnCommand.php index f953deb16..bca72421b 100644 --- a/src/Magento/FunctionalTestingFramework/Console/GenerateDevUrnCommand.php +++ b/src/Magento/FunctionalTestingFramework/Console/GenerateDevUrnCommand.php @@ -4,7 +4,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ -declare(strict_types = 1); +declare(strict_types=1); namespace Magento\FunctionalTestingFramework\Console; @@ -19,6 +19,14 @@ class GenerateDevUrnCommand extends Command { + /** + * Argument for the path to IDE config file + */ + const IDE_FILE_PATH_ARGUMENT = 'path'; + + const PROJECT_PATH_IDENTIFIER = '$PROJECT_DIR$'; + const MFTF_SRC_PATH = 'src/Magento/FunctionalTestingFramework/'; + /** * Configures the current command. * @@ -27,8 +35,12 @@ class GenerateDevUrnCommand extends Command protected function configure() { $this->setName('generate:urn-catalog') - ->setDescription('This command generates an URN catalog to enable PHPStorm to recognize and highlight URNs.') - ->addArgument('path', InputArgument::REQUIRED, 'path to PHPStorm misc.xml file (typically located in [ProjectRoot]/.idea/misc.xml)') + ->setDescription('Generates the catalog of URNs to *.xsd mappings for the IDE to highlight xml.') + ->addArgument( + self::IDE_FILE_PATH_ARGUMENT, + InputArgument::REQUIRED, + 'Path to file to output the catalog. For PhpStorm use .idea/misc.xml' + ) ->addOption( "force", 'f', @@ -47,7 +59,7 @@ protected function configure() */ protected function execute(InputInterface $input, OutputInterface $output) { - $miscXmlFilePath = $input->getArgument('path') . DIRECTORY_SEPARATOR . "misc.xml"; + $miscXmlFilePath = $input->getArgument(self::IDE_FILE_PATH_ARGUMENT); $miscXmlFile = realpath($miscXmlFilePath); $force = $input->getOption('force'); @@ -71,7 +83,7 @@ protected function execute(InputInterface $input, OutputInterface $output) //Locate ProjectResources node, create one if none are found. $nodeForWork = null; - foreach($dom->getElementsByTagName('component') as $child) { + foreach ($dom->getElementsByTagName('component') as $child) { if ($child->getAttribute('name') === 'ProjectResources') { $nodeForWork = $child; } @@ -109,35 +121,74 @@ protected function execute(InputInterface $input, OutputInterface $output) /** * Generates urn => location array for all MFTF schema. + * * @return array - * @throws TestFrameworkException */ private function generateResourcesArray() { $resourcesArray = [ 'urn:magento:mftf:DataGenerator/etc/dataOperation.xsd' => - realpath(FilePathFormatter::format(FW_BP) - . 'src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataOperation.xsd'), + $this->getResourcePath('DataGenerator/etc/dataOperation.xsd'), 'urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd' => - realpath(FilePathFormatter::format(FW_BP) - . 'src/Magento/FunctionalTestingFramework/DataGenerator/etc/dataProfileSchema.xsd'), + $this->getResourcePath('DataGenerator/etc/dataProfileSchema.xsd'), 'urn:magento:mftf:Page/etc/PageObject.xsd' => - realpath(FilePathFormatter::format(FW_BP) - . 'src/Magento/FunctionalTestingFramework/Page/etc/PageObject.xsd'), + $this->getResourcePath('Page/etc/PageObject.xsd'), 'urn:magento:mftf:Page/etc/SectionObject.xsd' => - realpath(FilePathFormatter::format(FW_BP) - . 'src/Magento/FunctionalTestingFramework/Page/etc/SectionObject.xsd'), + $this->getResourcePath('Page/etc/SectionObject.xsd'), 'urn:magento:mftf:Test/etc/actionGroupSchema.xsd' => - realpath(FilePathFormatter::format(FW_BP) - . 'src/Magento/FunctionalTestingFramework/Test/etc/actionGroupSchema.xsd'), + $this->getResourcePath('Test/etc/actionGroupSchema.xsd'), 'urn:magento:mftf:Test/etc/testSchema.xsd' => - realpath(FilePathFormatter::format(FW_BP) - . 'src/Magento/FunctionalTestingFramework/Test/etc/testSchema.xsd'), + $this->getResourcePath('Test/etc/testSchema.xsd'), 'urn:magento:mftf:Suite/etc/suiteSchema.xsd' => - realpath(FilePathFormatter::format(FW_BP) - . 'src/Magento/FunctionalTestingFramework/Suite/etc/suiteSchema.xsd') + $this->getResourcePath('Suite/etc/suiteSchema.xsd') ]; return $resourcesArray; } + /** + * Returns path (full or PhpStorm project-based) to XSD file + * + * @param $relativePath + * @return string + * @throws TestFrameworkException + */ + private function getResourcePath($relativePath) + { + $urnPath = realpath(FilePathFormatter::format(FW_BP) . self::MFTF_SRC_PATH . $relativePath); + $projectRoot = $this->getProjectRootPath(); + + if ($projectRoot !== null) { + return str_replace($projectRoot, self::PROJECT_PATH_IDENTIFIER, $urnPath); + } + + return $urnPath; + } + + /** + * Returns Project root directory absolute path + * @TODO Find out how to detect other types of installation + * + * @return string|null + */ + private function getProjectRootPath() + { + $frameworkRoot = realpath(__DIR__); + + if ($this->isInstalledByComposer($frameworkRoot)) { + return strstr($frameworkRoot, '/vendor/', true); + } + + return null; + } + + /** + * Determines whether MFTF was installed using Composer + * + * @param string $frameworkRoot + * @return bool + */ + private function isInstalledByComposer($frameworkRoot) + { + return false !== strpos($frameworkRoot, '/vendor/'); + } } diff --git a/src/Magento/FunctionalTestingFramework/_bootstrap.php b/src/Magento/FunctionalTestingFramework/_bootstrap.php index e35b20bad..b655fb28e 100644 --- a/src/Magento/FunctionalTestingFramework/_bootstrap.php +++ b/src/Magento/FunctionalTestingFramework/_bootstrap.php @@ -53,6 +53,9 @@ defined('WAIT_TIMEOUT') || define('WAIT_TIMEOUT', 30); $env->setEnvironmentVariable('WAIT_TIMEOUT', WAIT_TIMEOUT); + defined('VERBOSE_ARTIFACTS') || define('VERBOSE_ARTIFACTS', false); + $env->setEnvironmentVariable('VERBOSE_ARTIFACTS', VERBOSE_ARTIFACTS); + try { new DateTimeZone(DEFAULT_TIMEZONE); } catch (\Exception $e) {